|
|
@ -8,7 +8,14 @@ from .external import FFmpegFD
|
|
|
|
from .fragment import FragmentFD
|
|
|
|
from .fragment import FragmentFD
|
|
|
|
from .. import webvtt
|
|
|
|
from .. import webvtt
|
|
|
|
from ..dependencies import Cryptodome
|
|
|
|
from ..dependencies import Cryptodome
|
|
|
|
from ..utils import bug_reports_message, parse_m3u8_attributes, update_url_query
|
|
|
|
from ..utils import (
|
|
|
|
|
|
|
|
bug_reports_message,
|
|
|
|
|
|
|
|
parse_m3u8_attributes,
|
|
|
|
|
|
|
|
remove_start,
|
|
|
|
|
|
|
|
traverse_obj,
|
|
|
|
|
|
|
|
update_url_query,
|
|
|
|
|
|
|
|
urljoin,
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class HlsFD(FragmentFD):
|
|
|
|
class HlsFD(FragmentFD):
|
|
|
@ -150,6 +157,13 @@ class HlsFD(FragmentFD):
|
|
|
|
i = 0
|
|
|
|
i = 0
|
|
|
|
media_sequence = 0
|
|
|
|
media_sequence = 0
|
|
|
|
decrypt_info = {'METHOD': 'NONE'}
|
|
|
|
decrypt_info = {'METHOD': 'NONE'}
|
|
|
|
|
|
|
|
external_aes_key = traverse_obj(info_dict, ('hls_aes', 'key'))
|
|
|
|
|
|
|
|
if external_aes_key:
|
|
|
|
|
|
|
|
external_aes_key = binascii.unhexlify(remove_start(external_aes_key, '0x'))
|
|
|
|
|
|
|
|
assert len(external_aes_key) in (16, 24, 32), 'Invalid length for HLS AES-128 key'
|
|
|
|
|
|
|
|
external_aes_iv = traverse_obj(info_dict, ('hls_aes', 'iv'))
|
|
|
|
|
|
|
|
if external_aes_iv:
|
|
|
|
|
|
|
|
external_aes_iv = binascii.unhexlify(remove_start(external_aes_iv, '0x').zfill(32))
|
|
|
|
byte_range = {}
|
|
|
|
byte_range = {}
|
|
|
|
discontinuity_count = 0
|
|
|
|
discontinuity_count = 0
|
|
|
|
frag_index = 0
|
|
|
|
frag_index = 0
|
|
|
@ -165,10 +179,7 @@ class HlsFD(FragmentFD):
|
|
|
|
frag_index += 1
|
|
|
|
frag_index += 1
|
|
|
|
if frag_index <= ctx['fragment_index']:
|
|
|
|
if frag_index <= ctx['fragment_index']:
|
|
|
|
continue
|
|
|
|
continue
|
|
|
|
frag_url = (
|
|
|
|
frag_url = urljoin(man_url, line)
|
|
|
|
line
|
|
|
|
|
|
|
|
if re.match(r'^https?://', line)
|
|
|
|
|
|
|
|
else urllib.parse.urljoin(man_url, line))
|
|
|
|
|
|
|
|
if extra_query:
|
|
|
|
if extra_query:
|
|
|
|
frag_url = update_url_query(frag_url, extra_query)
|
|
|
|
frag_url = update_url_query(frag_url, extra_query)
|
|
|
|
|
|
|
|
|
|
|
@ -190,10 +201,7 @@ class HlsFD(FragmentFD):
|
|
|
|
return False
|
|
|
|
return False
|
|
|
|
frag_index += 1
|
|
|
|
frag_index += 1
|
|
|
|
map_info = parse_m3u8_attributes(line[11:])
|
|
|
|
map_info = parse_m3u8_attributes(line[11:])
|
|
|
|
frag_url = (
|
|
|
|
frag_url = urljoin(man_url, map_info.get('URI'))
|
|
|
|
map_info.get('URI')
|
|
|
|
|
|
|
|
if re.match(r'^https?://', map_info.get('URI'))
|
|
|
|
|
|
|
|
else urllib.parse.urljoin(man_url, map_info.get('URI')))
|
|
|
|
|
|
|
|
if extra_query:
|
|
|
|
if extra_query:
|
|
|
|
frag_url = update_url_query(frag_url, extra_query)
|
|
|
|
frag_url = update_url_query(frag_url, extra_query)
|
|
|
|
|
|
|
|
|
|
|
@ -218,15 +226,18 @@ class HlsFD(FragmentFD):
|
|
|
|
decrypt_url = decrypt_info.get('URI')
|
|
|
|
decrypt_url = decrypt_info.get('URI')
|
|
|
|
decrypt_info = parse_m3u8_attributes(line[11:])
|
|
|
|
decrypt_info = parse_m3u8_attributes(line[11:])
|
|
|
|
if decrypt_info['METHOD'] == 'AES-128':
|
|
|
|
if decrypt_info['METHOD'] == 'AES-128':
|
|
|
|
if 'IV' in decrypt_info:
|
|
|
|
if external_aes_iv:
|
|
|
|
|
|
|
|
decrypt_info['IV'] = external_aes_iv
|
|
|
|
|
|
|
|
elif 'IV' in decrypt_info:
|
|
|
|
decrypt_info['IV'] = binascii.unhexlify(decrypt_info['IV'][2:].zfill(32))
|
|
|
|
decrypt_info['IV'] = binascii.unhexlify(decrypt_info['IV'][2:].zfill(32))
|
|
|
|
if not re.match(r'^https?://', decrypt_info['URI']):
|
|
|
|
if external_aes_key:
|
|
|
|
decrypt_info['URI'] = urllib.parse.urljoin(
|
|
|
|
decrypt_info['KEY'] = external_aes_key
|
|
|
|
man_url, decrypt_info['URI'])
|
|
|
|
else:
|
|
|
|
if extra_query:
|
|
|
|
decrypt_info['URI'] = urljoin(man_url, decrypt_info['URI'])
|
|
|
|
decrypt_info['URI'] = update_url_query(decrypt_info['URI'], extra_query)
|
|
|
|
if extra_query:
|
|
|
|
if decrypt_url != decrypt_info['URI']:
|
|
|
|
decrypt_info['URI'] = update_url_query(decrypt_info['URI'], extra_query)
|
|
|
|
decrypt_info['KEY'] = None
|
|
|
|
if decrypt_url != decrypt_info['URI']:
|
|
|
|
|
|
|
|
decrypt_info['KEY'] = None
|
|
|
|
|
|
|
|
|
|
|
|
elif line.startswith('#EXT-X-MEDIA-SEQUENCE'):
|
|
|
|
elif line.startswith('#EXT-X-MEDIA-SEQUENCE'):
|
|
|
|
media_sequence = int(line[22:])
|
|
|
|
media_sequence = int(line[22:])
|
|
|
|