mirror of
https://github.com/spaam/svtplay-dl.git
synced 2024-11-27 13:44:14 +01:00
m3u8: add support for ext-x-byterange x-map
add tests for x-map ext-byte-range
This commit is contained in:
parent
8a72c4d200
commit
eac21b3979
@ -248,7 +248,7 @@ class HLS(VideoRetriever):
|
|||||||
duration = 0
|
duration = 0
|
||||||
max_duration = 0
|
max_duration = 0
|
||||||
for index, i in enumerate(m3u8.media_segment):
|
for index, i in enumerate(m3u8.media_segment):
|
||||||
if "duration" in i["EXTINF"]:
|
if "EXTINF" in i and "duration" in i["EXTINF"]:
|
||||||
duration = i["EXTINF"]["duration"]
|
duration = i["EXTINF"]["duration"]
|
||||||
max_duration = max(max_duration, duration)
|
max_duration = max(max_duration, duration)
|
||||||
total_duration += duration
|
total_duration += duration
|
||||||
@ -261,7 +261,10 @@ class HLS(VideoRetriever):
|
|||||||
eta.increment()
|
eta.increment()
|
||||||
progressbar(size_media, index + 1, "".join(["ETA: ", str(eta)]))
|
progressbar(size_media, index + 1, "".join(["ETA: ", str(eta)]))
|
||||||
|
|
||||||
data = self.http.request("get", item, cookies=cookies)
|
headers = {}
|
||||||
|
if "EXT-X-BYTERANGE" in i:
|
||||||
|
headers["Range"] = f'bytes={i["EXT-X-BYTERANGE"]["o"]}-{i["EXT-X-BYTERANGE"]["o"] + i["EXT-X-BYTERANGE"]["n"] - 1}'
|
||||||
|
data = self.http.request("get", item, cookies=cookies, headers=headers)
|
||||||
if data.status_code == 404:
|
if data.status_code == 404:
|
||||||
break
|
break
|
||||||
data = data.content
|
data = data.content
|
||||||
@ -426,7 +429,19 @@ class M3U8:
|
|||||||
# 4.3.2.5. EXT-X-MAP
|
# 4.3.2.5. EXT-X-MAP
|
||||||
elif tag == "EXT-X-MAP":
|
elif tag == "EXT-X-MAP":
|
||||||
info = _get_tuple_attribute(attr)
|
info = _get_tuple_attribute(attr)
|
||||||
self.media_segment.insert(0, {"URI": info["URI"], "EXTINF": {"duration": 0}})
|
if "BYTERANGE" in info:
|
||||||
|
if "@" in info["BYTERANGE"]:
|
||||||
|
n, o = info["BYTERANGE"].split("@", 1)
|
||||||
|
info["EXT-X-BYTERANGE"] = {}
|
||||||
|
info["EXT-X-BYTERANGE"]["n"], info["EXT-X-BYTERANGE"]["o"] = (int(n), int(o))
|
||||||
|
else:
|
||||||
|
info["EXT-X-BYTERANGE"] = {}
|
||||||
|
info["EXT-X-BYTERANGE"]["n"] = int(attr)
|
||||||
|
info["EXT-X-BYTERANGE"]["o"] = 0
|
||||||
|
if "BYTERANGE" not in info:
|
||||||
|
info["EXTINF"] = {}
|
||||||
|
info["EXTINF"]["duration"] = 0
|
||||||
|
self.media_segment.insert(0, info)
|
||||||
|
|
||||||
# 4.3.2.6. EXT-X-PROGRAM-DATE-TIME"
|
# 4.3.2.6. EXT-X-PROGRAM-DATE-TIME"
|
||||||
elif tag == "EXT-X-PROGRAM-DATE-TIME":
|
elif tag == "EXT-X-PROGRAM-DATE-TIME":
|
||||||
|
17
lib/svtplay_dl/tests/m3u8-playlists/ext-x-byterange.m3u8
Normal file
17
lib/svtplay_dl/tests/m3u8-playlists/ext-x-byterange.m3u8
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
#EXTM3U
|
||||||
|
#EXT-X-VERSION:6
|
||||||
|
#EXT-X-PLAYLIST-TYPE:VOD
|
||||||
|
#EXT-X-INDEPENDENT-SEGMENTS
|
||||||
|
#EXT-X-TARGETDURATION:10
|
||||||
|
#EXT-X-MEDIA-SEQUENCE:0
|
||||||
|
#EXT-X-MAP:URI="Frank---Kastaniegaarde_bfc1970adae844c180ae0c447e079c1e_5500_audio.mp4",BYTERANGE="748@0"
|
||||||
|
#EXTINF:10.005333,
|
||||||
|
#EXT-X-BYTERANGE:242398@2828
|
||||||
|
Frank---Kastaniegaarde_bfc1970adae844c180ae0c447e079c1e_5500_audio.mp4
|
||||||
|
#EXTINF:10.005333,
|
||||||
|
#EXT-X-BYTERANGE:242050@245226
|
||||||
|
Frank---Kastaniegaarde_bfc1970adae844c180ae0c447e079c1e_5500_audio.mp4
|
||||||
|
#EXTINF:10.005333,
|
||||||
|
#EXT-X-BYTERANGE:242104@487276
|
||||||
|
Frank---Kastaniegaarde_bfc1970adae844c180ae0c447e079c1e_5500_audio.mp4
|
||||||
|
#EXT-X-ENDLIST
|
11
lib/svtplay_dl/tests/m3u8-playlists/x-map.m3u8
Normal file
11
lib/svtplay_dl/tests/m3u8-playlists/x-map.m3u8
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
#EXTM3U
|
||||||
|
#EXT-X-VERSION:6
|
||||||
|
#EXT-X-TARGETDURATION:17
|
||||||
|
#EXT-X-PLAYLIST-TYPE:VOD
|
||||||
|
#EXT-X-MAP:URI="video/init.mp4"
|
||||||
|
#EXTINF:11.378,
|
||||||
|
video/1.m4s
|
||||||
|
#EXTINF:10.677,
|
||||||
|
video/2.m4s
|
||||||
|
#EXTINF:10.944,
|
||||||
|
video/3.m4s
|
@ -25,6 +25,12 @@ def parse(playlist):
|
|||||||
return streams
|
return streams
|
||||||
|
|
||||||
|
|
||||||
|
def parse_m3u8(playlist):
|
||||||
|
with open(os.path.join(os.path.dirname(os.path.realpath(__file__)), "m3u8-playlists", playlist)) as fd:
|
||||||
|
manifest = fd.read()
|
||||||
|
return M3U8(manifest)
|
||||||
|
|
||||||
|
|
||||||
# Example HLS playlist, source:
|
# Example HLS playlist, source:
|
||||||
# loosly inspired by
|
# loosly inspired by
|
||||||
# https://devstreaming-cdn.apple.com/videos/streaming/examples/bipbop_4x3/bipbop_4x3_variant.m3u8
|
# https://devstreaming-cdn.apple.com/videos/streaming/examples/bipbop_4x3/bipbop_4x3_variant.m3u8
|
||||||
@ -130,3 +136,16 @@ def test_audio_bottom():
|
|||||||
data = parse("audio-uri-bottom.m3u8")
|
data = parse("audio-uri-bottom.m3u8")
|
||||||
assert data[2639].segments
|
assert data[2639].segments
|
||||||
assert data[2639].audio
|
assert data[2639].audio
|
||||||
|
|
||||||
|
|
||||||
|
def test_x_byterange():
|
||||||
|
data = parse_m3u8("ext-x-byterange.m3u8")
|
||||||
|
assert data.media_segment[0]["EXT-X-BYTERANGE"]["n"] == 748
|
||||||
|
assert data.media_segment[1]["EXT-X-BYTERANGE"]["n"] == 242398
|
||||||
|
assert data.media_segment[1]["EXT-X-BYTERANGE"]["n"] + data.media_segment[1]["EXT-X-BYTERANGE"]["o"] - 1 == 245225
|
||||||
|
|
||||||
|
|
||||||
|
def test_x_map():
|
||||||
|
data = parse_m3u8("x-map.m3u8")
|
||||||
|
assert data.media_segment[0]["URI"] == "video/init.mp4"
|
||||||
|
assert data.media_segment[2]["URI"] == "video/2s.m4s"
|
||||||
|
Loading…
Reference in New Issue
Block a user