[extractor/common] Add support for float durations in _parse_mpd_formats (closes #13919)
This commit is contained in:
parent
da20951a57
commit
4850478543
3 changed files with 105 additions and 1 deletions
|
@ -10,6 +10,7 @@ import unittest
|
||||||
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||||
|
|
||||||
from test.helper import FakeYDL, expect_dict, expect_value
|
from test.helper import FakeYDL, expect_dict, expect_value
|
||||||
|
from youtube_dl.compat import compat_etree_fromstring
|
||||||
from youtube_dl.extractor.common import InfoExtractor
|
from youtube_dl.extractor.common import InfoExtractor
|
||||||
from youtube_dl.extractor import YoutubeIE, get_info_extractor
|
from youtube_dl.extractor import YoutubeIE, get_info_extractor
|
||||||
from youtube_dl.utils import encode_data_uri, strip_jsonp, ExtractorError, RegexNotFoundError
|
from youtube_dl.utils import encode_data_uri, strip_jsonp, ExtractorError, RegexNotFoundError
|
||||||
|
@ -488,6 +489,91 @@ jwplayer("mediaplayer").setup({"abouttext":"Visit Indie DB","aboutlink":"http:\/
|
||||||
self.ie._sort_formats(formats)
|
self.ie._sort_formats(formats)
|
||||||
expect_value(self, formats, expected_formats, None)
|
expect_value(self, formats, expected_formats, None)
|
||||||
|
|
||||||
|
def test_parse_mpd_formats(self):
|
||||||
|
_TEST_CASES = [
|
||||||
|
(
|
||||||
|
# https://github.com/rg3/youtube-dl/issues/13919
|
||||||
|
'float_duration',
|
||||||
|
'http://unknown/manifest.mpd',
|
||||||
|
[{
|
||||||
|
'manifest_url': 'http://unknown/manifest.mpd',
|
||||||
|
'ext': 'mp4',
|
||||||
|
'format_id': '318597',
|
||||||
|
'format_note': 'DASH video',
|
||||||
|
'protocol': 'http_dash_segments',
|
||||||
|
'acodec': 'none',
|
||||||
|
'vcodec': 'avc1.42001f',
|
||||||
|
'tbr': 318.597,
|
||||||
|
'width': 340,
|
||||||
|
'height': 192,
|
||||||
|
}, {
|
||||||
|
'manifest_url': 'http://unknown/manifest.mpd',
|
||||||
|
'ext': 'mp4',
|
||||||
|
'format_id': '638590',
|
||||||
|
'format_note': 'DASH video',
|
||||||
|
'protocol': 'http_dash_segments',
|
||||||
|
'acodec': 'none',
|
||||||
|
'vcodec': 'avc1.42001f',
|
||||||
|
'tbr': 638.59,
|
||||||
|
'width': 512,
|
||||||
|
'height': 288,
|
||||||
|
}, {
|
||||||
|
'manifest_url': 'http://unknown/manifest.mpd',
|
||||||
|
'ext': 'mp4',
|
||||||
|
'format_id': '1022565',
|
||||||
|
'format_note': 'DASH video',
|
||||||
|
'protocol': 'http_dash_segments',
|
||||||
|
'acodec': 'none',
|
||||||
|
'vcodec': 'avc1.4d001f',
|
||||||
|
'tbr': 1022.565,
|
||||||
|
'width': 688,
|
||||||
|
'height': 384,
|
||||||
|
}, {
|
||||||
|
'manifest_url': 'http://unknown/manifest.mpd',
|
||||||
|
'ext': 'mp4',
|
||||||
|
'format_id': '2046506',
|
||||||
|
'format_note': 'DASH video',
|
||||||
|
'protocol': 'http_dash_segments',
|
||||||
|
'acodec': 'none',
|
||||||
|
'vcodec': 'avc1.4d001f',
|
||||||
|
'tbr': 2046.506,
|
||||||
|
'width': 1024,
|
||||||
|
'height': 576,
|
||||||
|
}, {
|
||||||
|
'manifest_url': 'http://unknown/manifest.mpd',
|
||||||
|
'ext': 'mp4',
|
||||||
|
'format_id': '3998017',
|
||||||
|
'format_note': 'DASH video',
|
||||||
|
'protocol': 'http_dash_segments',
|
||||||
|
'acodec': 'none',
|
||||||
|
'vcodec': 'avc1.640029',
|
||||||
|
'tbr': 3998.017,
|
||||||
|
'width': 1280,
|
||||||
|
'height': 720,
|
||||||
|
}, {
|
||||||
|
'manifest_url': 'http://unknown/manifest.mpd',
|
||||||
|
'ext': 'mp4',
|
||||||
|
'format_id': '5997485',
|
||||||
|
'format_note': 'DASH video',
|
||||||
|
'protocol': 'http_dash_segments',
|
||||||
|
'acodec': 'none',
|
||||||
|
'vcodec': 'avc1.640032',
|
||||||
|
'tbr': 5997.485,
|
||||||
|
'width': 1920,
|
||||||
|
'height': 1080,
|
||||||
|
}]
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
||||||
|
for mpd_file, mpd_url, expected_formats in _TEST_CASES:
|
||||||
|
with io.open('./test/testdata/mpd/%s.mpd' % mpd_file,
|
||||||
|
mode='r', encoding='utf-8') as f:
|
||||||
|
formats = self.ie._parse_mpd_formats(
|
||||||
|
compat_etree_fromstring(f.read().encode('utf-8')),
|
||||||
|
mpd_url=mpd_url)
|
||||||
|
self.ie._sort_formats(formats)
|
||||||
|
expect_value(self, formats, expected_formats, None)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
18
test/testdata/mpd/float_duration.mpd
vendored
Normal file
18
test/testdata/mpd/float_duration.mpd
vendored
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<MPD xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:mpeg:dash:schema:mpd:2011" type="static" minBufferTime="PT2S" profiles="urn:mpeg:dash:profile:isoff-on-demand:2011" mediaPresentationDuration="PT6014S">
|
||||||
|
<Period bitstreamSwitching="true">
|
||||||
|
<AdaptationSet mimeType="audio/mp4" codecs="mp4a.40.2" startWithSAP="1" segmentAlignment="true">
|
||||||
|
<SegmentTemplate timescale="1000000" presentationTimeOffset="0" initialization="ai_$RepresentationID$.mp4d" media="a_$RepresentationID$_$Number$.mp4d" duration="2000000.0" startNumber="0"></SegmentTemplate>
|
||||||
|
<Representation id="318597" bandwidth="61587"></Representation>
|
||||||
|
</AdaptationSet>
|
||||||
|
<AdaptationSet mimeType="video/mp4" startWithSAP="1" segmentAlignment="true">
|
||||||
|
<SegmentTemplate timescale="1000000" presentationTimeOffset="0" initialization="vi_$RepresentationID$.mp4d" media="v_$RepresentationID$_$Number$.mp4d" duration="2000000.0" startNumber="0"></SegmentTemplate>
|
||||||
|
<Representation id="318597" codecs="avc1.42001f" width="340" height="192" bandwidth="318597"></Representation>
|
||||||
|
<Representation id="638590" codecs="avc1.42001f" width="512" height="288" bandwidth="638590"></Representation>
|
||||||
|
<Representation id="1022565" codecs="avc1.4d001f" width="688" height="384" bandwidth="1022565"></Representation>
|
||||||
|
<Representation id="2046506" codecs="avc1.4d001f" width="1024" height="576" bandwidth="2046506"></Representation>
|
||||||
|
<Representation id="3998017" codecs="avc1.640029" width="1280" height="720" bandwidth="3998017"></Representation>
|
||||||
|
<Representation id="5997485" codecs="avc1.640032" width="1920" height="1080" bandwidth="5997485"></Representation>
|
||||||
|
</AdaptationSet>
|
||||||
|
</Period>
|
||||||
|
</MPD>
|
|
@ -1786,7 +1786,7 @@ class InfoExtractor(object):
|
||||||
ms_info['timescale'] = int(timescale)
|
ms_info['timescale'] = int(timescale)
|
||||||
segment_duration = source.get('duration')
|
segment_duration = source.get('duration')
|
||||||
if segment_duration:
|
if segment_duration:
|
||||||
ms_info['segment_duration'] = int(segment_duration)
|
ms_info['segment_duration'] = float(segment_duration)
|
||||||
|
|
||||||
def extract_Initialization(source):
|
def extract_Initialization(source):
|
||||||
initialization = source.find(_add_ns('Initialization'))
|
initialization = source.find(_add_ns('Initialization'))
|
||||||
|
|
Loading…
Reference in a new issue