From 111dac92641dcb4035eb64db462121f173cbb9ef Mon Sep 17 00:00:00 2001 From: rlaphoenix Date: Thu, 9 Mar 2023 21:46:48 +0000 Subject: [PATCH] Fix association of preceding HLS EXT-X-KEYs with m3u8 fork This will improve efficiency and accuracy of getting appropriate DRM systems when downloading segments. This can dramatically improve download speed from less than 50 kb/s to full speed if the HLS playlist used a lot of AES-128 EXT-X-KEYs. E.g., a unique key for each segment. This was caused because the HLS.get_drm function took EVERY EXT-X-KEY, checked for supported systems, loaded them, and returned the supported objects. This meant it could load possibly 100s of AES-128 ClearKey objects (likely requiring URL downloads for the key URI) causing a huge delay before downloading each segment. --- devine/core/manifests/hls.py | 11 +++-------- poetry.lock | 32 ++++++++++++++++---------------- pyproject.toml | 2 +- 3 files changed, 20 insertions(+), 25 deletions(-) diff --git a/devine/core/manifests/hls.py b/devine/core/manifests/hls.py index c99007a..ba1a572 100644 --- a/devine/core/manifests/hls.py +++ b/devine/core/manifests/hls.py @@ -256,15 +256,10 @@ class HLS: with drm_lock: newest_segment_key = segment_key.get() try: - if segment.key and newest_segment_key[1] != segment.key: + if segment.keys and newest_segment_key[1] != segment.keys: try: drm = HLS.get_drm( - # TODO: We append master.keys because m3u8 class only puts the last EXT-X-KEY - # to the segment.key property, not supporting multi-drm scenarios. - # By re-adding every single EXT-X-KEY found, we can at least try to get - # a suitable key. However, it may not match the right segment/timeframe! - # It will try to use the first key provided where possible. - keys=[segment.key] + master.keys, + keys=segment.keys, proxy=proxy ) except NotImplementedError as e: @@ -281,7 +276,7 @@ class HLS: if not license_widevine: raise ValueError("license_widevine func must be supplied to use Widevine DRM") license_widevine(drm, track_kid=track_kid) - newest_segment_key = (drm, segment.key) + newest_segment_key = (drm, segment.keys) finally: segment_key.put(newest_segment_key) diff --git a/poetry.lock b/poetry.lock index a0ca277..31ff2f4 100644 --- a/poetry.lock +++ b/poetry.lock @@ -695,21 +695,6 @@ html5 = ["html5lib"] htmlsoup = ["BeautifulSoup4"] source = ["Cython (>=0.29.7)"] -[[package]] -name = "m3u8" -version = "3.4.0" -description = "Python m3u8 parser" -category = "main" -optional = false -python-versions = ">=3.6" -files = [ - {file = "m3u8-3.4.0-py3-none-any.whl", hash = "sha256:5016060622786abf4924bd7f0e04923c261762c999edaab073690d9031c1a8db"}, - {file = "m3u8-3.4.0.tar.gz", hash = "sha256:6dddfb57ce485f67bf307e9581990db9a55614eeb2df4b89d6ae2c0ca7e525cd"}, -] - -[package.dependencies] -iso8601 = "*" - [[package]] name = "marisa-trie" version = "0.7.8" @@ -1396,6 +1381,21 @@ pygments = ">=2.14.0,<3.0.0" [package.extras] jupyter = ["ipywidgets (>=7.5.1,<9)"] +[[package]] +name = "rlaphoenix-m3u8" +version = "3.4.0" +description = "Python m3u8 parser" +category = "main" +optional = false +python-versions = ">=3.6" +files = [ + {file = "rlaphoenix.m3u8-3.4.0-py3-none-any.whl", hash = "sha256:cd2c22195c747d52c63189d4bd5f664e1fc5ea202f5a7396b7336581f26a2838"}, + {file = "rlaphoenix.m3u8-3.4.0.tar.gz", hash = "sha256:6f8c71350bc8a07f2bd714d1e72b0a483455b9c6e5141a5a308bf264b6718504"}, +] + +[package.dependencies] +iso8601 = "*" + [[package]] name = "ruamel-yaml" version = "0.17.21" @@ -1730,4 +1730,4 @@ multidict = ">=4.0" [metadata] lock-version = "2.0" python-versions = ">=3.9.0,<3.12" -content-hash = "2f0a42a2b10aaad2f946f3eee9d317db401fa12bca5fd2b3bc99f9bde5d843c8" +content-hash = "74e5f149b8cb8e02b0faee5d5eae309eb97e2a4e1d614bbdb9ef41cab5ba5095" diff --git a/pyproject.toml b/pyproject.toml index 58367d4..1cec92a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -32,7 +32,6 @@ crccheck = "^1.3.0" jsonpickle = "^3.0.1" langcodes = { extras = ["data"], version = "^3.3.0" } lxml = "^4.9.2" -m3u8 = "^3.4.0" pproxy = "^2.7.8" protobuf = "4.21.6" pycaption = "^2.1.1" @@ -45,6 +44,7 @@ pywidevine = { extras = ["serve"], version = "^1.6.0" } PyYAML = "^6.0" requests = { extras = ["socks"], version = "^2.28.2" } rich = "^13.3.1" +"rlaphoenix.m3u8" = "^3.4.0" "ruamel.yaml" = "^0.17.21" sortedcontainers = "^2.4.0" subtitle-filter = "^1.4.4"