mirror of
				https://github.com/ytdl-org/youtube-dl
				synced 2025-11-04 03:33:46 +00:00 
			
		
		
		
	[InfoExtractor] Support byte range for DASH
* adapted from https://github.com/ytdl-org/youtube-dl/pull/30279 * thx former GH user kikuyan
This commit is contained in:
		
							parent
							
								
									bec9180e89
								
							
						
					
					
						commit
						4eaeb9b2c6
					
				@ -1126,6 +1126,72 @@ jwplayer("mediaplayer").setup({"abouttext":"Visit Indie DB","aboutlink":"http:\/
 | 
			
		||||
                    'fps': 30,
 | 
			
		||||
                }],
 | 
			
		||||
                {},
 | 
			
		||||
            ), (
 | 
			
		||||
                # https://github.com/ytdl-org/youtube-dl/issues/30235
 | 
			
		||||
                # Bento4 generated test mpd
 | 
			
		||||
                # mp4dash --mpd-name=manifest.mpd --no-split --use-segment-list mediafiles
 | 
			
		||||
                'url_and_range',
 | 
			
		||||
                'http://unknown/manifest.mpd',  # mpd_url
 | 
			
		||||
                'http://unknown/',  # mpd_base_url
 | 
			
		||||
                [{
 | 
			
		||||
                    'manifest_url': 'http://unknown/manifest.mpd',
 | 
			
		||||
                    'fragment_base_url': 'http://unknown/',
 | 
			
		||||
                    'ext': 'm4a',
 | 
			
		||||
                    'format_id': 'audio-und-mp4a.40.2',
 | 
			
		||||
                    'format_note': 'DASH audio',
 | 
			
		||||
                    'container': 'm4a_dash',
 | 
			
		||||
                    'protocol': 'http_dash_segments',
 | 
			
		||||
                    'acodec': 'mp4a.40.2',
 | 
			
		||||
                    'vcodec': 'none',
 | 
			
		||||
                    'tbr': 98.808,
 | 
			
		||||
                }, {
 | 
			
		||||
                    'manifest_url': 'http://unknown/manifest.mpd',
 | 
			
		||||
                    'fragment_base_url': 'http://unknown/',
 | 
			
		||||
                    'ext': 'mp4',
 | 
			
		||||
                    'format_id': 'video-avc1',
 | 
			
		||||
                    'format_note': 'DASH video',
 | 
			
		||||
                    'container': 'mp4_dash',
 | 
			
		||||
                    'protocol': 'http_dash_segments',
 | 
			
		||||
                    'acodec': 'none',
 | 
			
		||||
                    'vcodec': 'avc1.4D401E',
 | 
			
		||||
                    'tbr': 699.597,
 | 
			
		||||
                    'width': 768,
 | 
			
		||||
                    'height': 432
 | 
			
		||||
                }],
 | 
			
		||||
                {},
 | 
			
		||||
            ), (
 | 
			
		||||
                # https://github.com/ytdl-org/youtube-dl/issues/27575
 | 
			
		||||
                # GPAC generated test mpd
 | 
			
		||||
                # MP4Box -dash 10000 -single-file -out manifest.mpd mediafiles
 | 
			
		||||
                'range_only',
 | 
			
		||||
                'http://unknown/manifest.mpd',  # mpd_url
 | 
			
		||||
                'http://unknown/',  # mpd_base_url
 | 
			
		||||
                [{
 | 
			
		||||
                    'manifest_url': 'http://unknown/manifest.mpd',
 | 
			
		||||
                    'fragment_base_url': 'http://unknown/audio_dashinit.mp4',
 | 
			
		||||
                    'ext': 'm4a',
 | 
			
		||||
                    'format_id': '2',
 | 
			
		||||
                    'format_note': 'DASH audio',
 | 
			
		||||
                    'container': 'm4a_dash',
 | 
			
		||||
                    'protocol': 'http_dash_segments',
 | 
			
		||||
                    'acodec': 'mp4a.40.2',
 | 
			
		||||
                    'vcodec': 'none',
 | 
			
		||||
                    'tbr': 98.096,
 | 
			
		||||
                }, {
 | 
			
		||||
                    'manifest_url': 'http://unknown/manifest.mpd',
 | 
			
		||||
                    'fragment_base_url': 'http://unknown/video_dashinit.mp4',
 | 
			
		||||
                    'ext': 'mp4',
 | 
			
		||||
                    'format_id': '1',
 | 
			
		||||
                    'format_note': 'DASH video',
 | 
			
		||||
                    'container': 'mp4_dash',
 | 
			
		||||
                    'protocol': 'http_dash_segments',
 | 
			
		||||
                    'acodec': 'none',
 | 
			
		||||
                    'vcodec': 'avc1.4D401E',
 | 
			
		||||
                    'tbr': 526.987,
 | 
			
		||||
                    'width': 768,
 | 
			
		||||
                    'height': 432
 | 
			
		||||
                }],
 | 
			
		||||
                {},
 | 
			
		||||
            ), (
 | 
			
		||||
                'subtitles',
 | 
			
		||||
                'https://sdn-global-streaming-cache-3qsdn.akamaized.net/stream/3144/files/17/07/672975/3144-kZT4LWMQw6Rh7Kpd.ism/manifest.mpd',
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										35
									
								
								test/testdata/mpd/range_only.mpd
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								test/testdata/mpd/range_only.mpd
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,35 @@
 | 
			
		||||
<?xml version="1.0"?>
 | 
			
		||||
<!-- MPD file Generated with GPAC version 1.0.1-revrelease at 2021-11-27T20:53:11.690Z -->
 | 
			
		||||
<MPD xmlns="urn:mpeg:dash:schema:mpd:2011" minBufferTime="PT1.500S" type="static" mediaPresentationDuration="PT0H0M30.196S" maxSegmentDuration="PT0H0M10.027S" profiles="urn:mpeg:dash:profile:full:2011">
 | 
			
		||||
 <ProgramInformation moreInformationURL="http://gpac.io">
 | 
			
		||||
  <Title>manifest.mpd generated by GPAC</Title>
 | 
			
		||||
 </ProgramInformation>
 | 
			
		||||
 | 
			
		||||
 <Period duration="PT0H0M30.196S">
 | 
			
		||||
  <AdaptationSet segmentAlignment="true" maxWidth="768" maxHeight="432" maxFrameRate="30000/1001" par="16:9" lang="und" startWithSAP="1">
 | 
			
		||||
   <Representation id="1" mimeType="video/mp4" codecs="avc1.4D401E" width="768" height="432" frameRate="30000/1001" sar="1:1" bandwidth="526987">
 | 
			
		||||
    <BaseURL>video_dashinit.mp4</BaseURL>
 | 
			
		||||
    <SegmentList timescale="90000" duration="900000">
 | 
			
		||||
     <Initialization range="0-881"/>
 | 
			
		||||
     <SegmentURL mediaRange="882-876094" indexRange="882-925"/>
 | 
			
		||||
     <SegmentURL mediaRange="876095-1466732" indexRange="876095-876138"/>
 | 
			
		||||
     <SegmentURL mediaRange="1466733-1953615" indexRange="1466733-1466776"/>
 | 
			
		||||
     <SegmentURL mediaRange="1953616-1994211" indexRange="1953616-1953659"/>
 | 
			
		||||
    </SegmentList>
 | 
			
		||||
   </Representation>
 | 
			
		||||
  </AdaptationSet>
 | 
			
		||||
  <AdaptationSet segmentAlignment="true" lang="und" startWithSAP="1">
 | 
			
		||||
   <Representation id="2" mimeType="audio/mp4" codecs="mp4a.40.2" audioSamplingRate="48000" bandwidth="98096">
 | 
			
		||||
    <AudioChannelConfiguration schemeIdUri="urn:mpeg:dash:23003:3:audio_channel_configuration:2011" value="2"/>
 | 
			
		||||
    <BaseURL>audio_dashinit.mp4</BaseURL>
 | 
			
		||||
    <SegmentList timescale="48000" duration="480000">
 | 
			
		||||
     <Initialization range="0-752"/>
 | 
			
		||||
     <SegmentURL mediaRange="753-124129" indexRange="753-796"/>
 | 
			
		||||
     <SegmentURL mediaRange="124130-250544" indexRange="124130-124173"/>
 | 
			
		||||
     <SegmentURL mediaRange="250545-374929" indexRange="250545-250588"/>
 | 
			
		||||
    </SegmentList>
 | 
			
		||||
   </Representation>
 | 
			
		||||
  </AdaptationSet>
 | 
			
		||||
 </Period>
 | 
			
		||||
</MPD>
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										351
									
								
								test/testdata/mpd/subtitles.mpd
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										351
									
								
								test/testdata/mpd/subtitles.mpd
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,351 @@
 | 
			
		||||
<?xml version="1.0" encoding="utf-8"?>
 | 
			
		||||
<!-- Created with Unified Streaming Platform (version=1.10.18-20255) -->
 | 
			
		||||
<MPD
 | 
			
		||||
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 | 
			
		||||
  xmlns="urn:mpeg:dash:schema:mpd:2011"
 | 
			
		||||
  xsi:schemaLocation="urn:mpeg:dash:schema:mpd:2011 http://standards.iso.org/ittf/PubliclyAvailableStandards/MPEG-DASH_schema_files/DASH-MPD.xsd"
 | 
			
		||||
  type="static"
 | 
			
		||||
  mediaPresentationDuration="PT14M48S"
 | 
			
		||||
  maxSegmentDuration="PT1M"
 | 
			
		||||
  minBufferTime="PT10S"
 | 
			
		||||
  profiles="urn:mpeg:dash:profile:isoff-live:2011">
 | 
			
		||||
  <Period
 | 
			
		||||
    id="1"
 | 
			
		||||
    duration="PT14M48S">
 | 
			
		||||
    <BaseURL>dash/</BaseURL>
 | 
			
		||||
    <AdaptationSet
 | 
			
		||||
      id="1"
 | 
			
		||||
      group="1"
 | 
			
		||||
      contentType="audio"
 | 
			
		||||
      segmentAlignment="true"
 | 
			
		||||
      audioSamplingRate="48000"
 | 
			
		||||
      mimeType="audio/mp4"
 | 
			
		||||
      codecs="mp4a.40.2"
 | 
			
		||||
      startWithSAP="1">
 | 
			
		||||
      <AudioChannelConfiguration
 | 
			
		||||
        schemeIdUri="urn:mpeg:dash:23003:3:audio_channel_configuration:2011"
 | 
			
		||||
        value="2" />
 | 
			
		||||
      <Role schemeIdUri="urn:mpeg:dash:role:2011" value="main" />
 | 
			
		||||
      <SegmentTemplate
 | 
			
		||||
        timescale="48000"
 | 
			
		||||
        initialization="3144-kZT4LWMQw6Rh7Kpd-$RepresentationID$.dash"
 | 
			
		||||
        media="3144-kZT4LWMQw6Rh7Kpd-$RepresentationID$-$Time$.dash">
 | 
			
		||||
        <SegmentTimeline>
 | 
			
		||||
          <S t="0" d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="96256" r="2" />
 | 
			
		||||
          <S d="95232" />
 | 
			
		||||
          <S d="3584" />
 | 
			
		||||
        </SegmentTimeline>
 | 
			
		||||
      </SegmentTemplate>
 | 
			
		||||
      <Representation
 | 
			
		||||
        id="audio=128001"
 | 
			
		||||
        bandwidth="128001">
 | 
			
		||||
      </Representation>
 | 
			
		||||
    </AdaptationSet>
 | 
			
		||||
    <AdaptationSet
 | 
			
		||||
      id="2"
 | 
			
		||||
      group="3"
 | 
			
		||||
      contentType="text"
 | 
			
		||||
      lang="en"
 | 
			
		||||
      mimeType="application/mp4"
 | 
			
		||||
      codecs="stpp"
 | 
			
		||||
      startWithSAP="1">
 | 
			
		||||
      <Role schemeIdUri="urn:mpeg:dash:role:2011" value="subtitle" />
 | 
			
		||||
      <SegmentTemplate
 | 
			
		||||
        timescale="1000"
 | 
			
		||||
        initialization="3144-kZT4LWMQw6Rh7Kpd-$RepresentationID$.dash"
 | 
			
		||||
        media="3144-kZT4LWMQw6Rh7Kpd-$RepresentationID$-$Time$.dash">
 | 
			
		||||
        <SegmentTimeline>
 | 
			
		||||
          <S t="0" d="60000" r="9" />
 | 
			
		||||
          <S d="24000" />
 | 
			
		||||
        </SegmentTimeline>
 | 
			
		||||
      </SegmentTemplate>
 | 
			
		||||
      <Representation
 | 
			
		||||
        id="textstream_eng=1000"
 | 
			
		||||
        bandwidth="1000">
 | 
			
		||||
      </Representation>
 | 
			
		||||
    </AdaptationSet>
 | 
			
		||||
    <AdaptationSet
 | 
			
		||||
      id="3"
 | 
			
		||||
      group="2"
 | 
			
		||||
      contentType="video"
 | 
			
		||||
      par="960:409"
 | 
			
		||||
      minBandwidth="100000"
 | 
			
		||||
      maxBandwidth="4482000"
 | 
			
		||||
      maxWidth="1689"
 | 
			
		||||
      maxHeight="720"
 | 
			
		||||
      segmentAlignment="true"
 | 
			
		||||
      mimeType="video/mp4"
 | 
			
		||||
      codecs="avc1.4D401F"
 | 
			
		||||
      startWithSAP="1">
 | 
			
		||||
      <Role schemeIdUri="urn:mpeg:dash:role:2011" value="main" />
 | 
			
		||||
      <SegmentTemplate
 | 
			
		||||
        timescale="12288"
 | 
			
		||||
        initialization="3144-kZT4LWMQw6Rh7Kpd-$RepresentationID$.dash"
 | 
			
		||||
        media="3144-kZT4LWMQw6Rh7Kpd-$RepresentationID$-$Time$.dash">
 | 
			
		||||
        <SegmentTimeline>
 | 
			
		||||
          <S t="0" d="24576" r="443" />
 | 
			
		||||
        </SegmentTimeline>
 | 
			
		||||
      </SegmentTemplate>
 | 
			
		||||
      <Representation
 | 
			
		||||
        id="video=100000"
 | 
			
		||||
        bandwidth="100000"
 | 
			
		||||
        width="336"
 | 
			
		||||
        height="144"
 | 
			
		||||
        sar="2880:2863"
 | 
			
		||||
        scanType="progressive">
 | 
			
		||||
      </Representation>
 | 
			
		||||
      <Representation
 | 
			
		||||
        id="video=326000"
 | 
			
		||||
        bandwidth="326000"
 | 
			
		||||
        width="562"
 | 
			
		||||
        height="240"
 | 
			
		||||
        sar="115200:114929"
 | 
			
		||||
        scanType="progressive">
 | 
			
		||||
      </Representation>
 | 
			
		||||
      <Representation
 | 
			
		||||
        id="video=698000"
 | 
			
		||||
        bandwidth="698000"
 | 
			
		||||
        width="844"
 | 
			
		||||
        height="360"
 | 
			
		||||
        sar="86400:86299"
 | 
			
		||||
        scanType="progressive">
 | 
			
		||||
      </Representation>
 | 
			
		||||
      <Representation
 | 
			
		||||
        id="video=1493000"
 | 
			
		||||
        bandwidth="1493000"
 | 
			
		||||
        width="1126"
 | 
			
		||||
        height="480"
 | 
			
		||||
        sar="230400:230267"
 | 
			
		||||
        scanType="progressive">
 | 
			
		||||
      </Representation>
 | 
			
		||||
      <Representation
 | 
			
		||||
        id="video=4482000"
 | 
			
		||||
        bandwidth="4482000"
 | 
			
		||||
        width="1688"
 | 
			
		||||
        height="720"
 | 
			
		||||
        sar="86400:86299"
 | 
			
		||||
        scanType="progressive">
 | 
			
		||||
      </Representation>
 | 
			
		||||
    </AdaptationSet>
 | 
			
		||||
  </Period>
 | 
			
		||||
</MPD>
 | 
			
		||||
							
								
								
									
										32
									
								
								test/testdata/mpd/url_and_range.mpd
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								test/testdata/mpd/url_and_range.mpd
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,32 @@
 | 
			
		||||
<?xml version="1.0" ?>
 | 
			
		||||
<MPD xmlns="urn:mpeg:dash:schema:mpd:2011" profiles="urn:mpeg:dash:profile:isoff-live:2011" minBufferTime="PT10.01S" mediaPresentationDuration="PT30.097S" type="static">
 | 
			
		||||
  <!-- Created with Bento4 mp4-dash.py, VERSION=2.0.0-639 -->
 | 
			
		||||
  <Period>
 | 
			
		||||
    <!-- Video -->
 | 
			
		||||
    <AdaptationSet mimeType="video/mp4" segmentAlignment="true" startWithSAP="1" maxWidth="768" maxHeight="432">
 | 
			
		||||
      <Representation id="video-avc1" codecs="avc1.4D401E" width="768" height="432" scanType="progressive" frameRate="30000/1001" bandwidth="699597">
 | 
			
		||||
        <SegmentList timescale="1000" duration="10010">
 | 
			
		||||
          <Initialization sourceURL="video-frag.mp4" range="36-746"/>
 | 
			
		||||
          <SegmentURL media="video-frag.mp4" mediaRange="747-876117"/>
 | 
			
		||||
          <SegmentURL media="video-frag.mp4" mediaRange="876118-1466913"/>
 | 
			
		||||
          <SegmentURL media="video-frag.mp4" mediaRange="1466914-1953954"/>
 | 
			
		||||
          <SegmentURL media="video-frag.mp4" mediaRange="1953955-1994652"/>
 | 
			
		||||
        </SegmentList>
 | 
			
		||||
      </Representation>
 | 
			
		||||
    </AdaptationSet>
 | 
			
		||||
    <!-- Audio -->
 | 
			
		||||
    <AdaptationSet mimeType="audio/mp4" startWithSAP="1" segmentAlignment="true">
 | 
			
		||||
      <Representation id="audio-und-mp4a.40.2" codecs="mp4a.40.2" bandwidth="98808" audioSamplingRate="48000">
 | 
			
		||||
        <AudioChannelConfiguration schemeIdUri="urn:mpeg:mpegB:cicp:ChannelConfiguration" value="2"/>
 | 
			
		||||
        <SegmentList timescale="1000" duration="10010">
 | 
			
		||||
          <Initialization sourceURL="audio-frag.mp4" range="32-623"/>
 | 
			
		||||
          <SegmentURL media="audio-frag.mp4" mediaRange="624-124199"/>
 | 
			
		||||
          <SegmentURL media="audio-frag.mp4" mediaRange="124200-250303"/>
 | 
			
		||||
          <SegmentURL media="audio-frag.mp4" mediaRange="250304-374365"/>
 | 
			
		||||
          <SegmentURL media="audio-frag.mp4" mediaRange="374366-374836"/>
 | 
			
		||||
        </SegmentList>
 | 
			
		||||
      </Representation>
 | 
			
		||||
    </AdaptationSet>
 | 
			
		||||
  </Period>
 | 
			
		||||
</MPD>
 | 
			
		||||
 | 
			
		||||
@ -183,6 +183,8 @@ class InfoExtractor(object):
 | 
			
		||||
                                            fragment_base_url
 | 
			
		||||
                                 * "duration" (optional, int or float)
 | 
			
		||||
                                 * "filesize" (optional, int)
 | 
			
		||||
                                 * "range" (optional, str of the form "start-end"
 | 
			
		||||
                                            to use in HTTP Range header)
 | 
			
		||||
                    * preference Order number of this format. If this field is
 | 
			
		||||
                                 present and not None, the formats get sorted
 | 
			
		||||
                                 by this field, regardless of all other values.
 | 
			
		||||
@ -2296,15 +2298,27 @@ class InfoExtractor(object):
 | 
			
		||||
            def extract_Initialization(source):
 | 
			
		||||
                initialization = source.find(_add_ns('Initialization'))
 | 
			
		||||
                if initialization is not None:
 | 
			
		||||
                    ms_info['initialization_url'] = initialization.attrib['sourceURL']
 | 
			
		||||
                    ms_info['initialization_url'] = initialization.get('sourceURL') or base_url
 | 
			
		||||
                    initialization_url_range = initialization.get('range')
 | 
			
		||||
                    if initialization_url_range:
 | 
			
		||||
                        ms_info['initialization_url_range'] = initialization_url_range
 | 
			
		||||
 | 
			
		||||
            segment_list = element.find(_add_ns('SegmentList'))
 | 
			
		||||
            if segment_list is not None:
 | 
			
		||||
                extract_common(segment_list)
 | 
			
		||||
                extract_Initialization(segment_list)
 | 
			
		||||
                segment_urls_e = segment_list.findall(_add_ns('SegmentURL'))
 | 
			
		||||
                if segment_urls_e:
 | 
			
		||||
                    ms_info['segment_urls'] = [segment.attrib['media'] for segment in segment_urls_e]
 | 
			
		||||
                segment_urls = traverse_obj(segment_urls_e, (
 | 
			
		||||
                    Ellipsis, T(lambda e: e.attrib), 'media'))
 | 
			
		||||
                if segment_urls:
 | 
			
		||||
                    ms_info['segment_urls'] = segment_urls
 | 
			
		||||
                segment_urls_range = traverse_obj(segment_urls_e, (
 | 
			
		||||
                    Ellipsis, T(lambda e: e.attrib), 'mediaRange',
 | 
			
		||||
                    T(lambda r: re.findall(r'^\d+-\d+$', r)), 0))
 | 
			
		||||
                if segment_urls_range:
 | 
			
		||||
                    ms_info['segment_urls_range'] = segment_urls_range
 | 
			
		||||
                    if not segment_urls:
 | 
			
		||||
                        ms_info['segment_urls'] = [base_url for _ in segment_urls_range]
 | 
			
		||||
            else:
 | 
			
		||||
                segment_template = element.find(_add_ns('SegmentTemplate'))
 | 
			
		||||
                if segment_template is not None:
 | 
			
		||||
@ -2443,6 +2457,11 @@ class InfoExtractor(object):
 | 
			
		||||
                    def location_key(location):
 | 
			
		||||
                        return 'url' if re.match(r'^https?://', location) else 'path'
 | 
			
		||||
 | 
			
		||||
                    def calc_segment_duration():
 | 
			
		||||
                        return float_or_none(
 | 
			
		||||
                            representation_ms_info['segment_duration'],
 | 
			
		||||
                            representation_ms_info['timescale']) if 'segment_duration' in representation_ms_info else None
 | 
			
		||||
 | 
			
		||||
                    if 'segment_urls' not in representation_ms_info and 'media' in representation_ms_info:
 | 
			
		||||
 | 
			
		||||
                        media_template = prepare_template('media', ('Number', 'Bandwidth', 'Time'))
 | 
			
		||||
@ -2512,45 +2531,68 @@ class InfoExtractor(object):
 | 
			
		||||
                                        'duration': duration,
 | 
			
		||||
                                    })
 | 
			
		||||
                                    segment_index += 1
 | 
			
		||||
                            representation_ms_info['fragments'] = fragments
 | 
			
		||||
                        elif 'segment_urls' in representation_ms_info:
 | 
			
		||||
                        elif 'segment_urls_range' in representation_ms_info:
 | 
			
		||||
                            # Segment URLs with mediaRange
 | 
			
		||||
                            # Example: https://kinescope.io/200615537/master.mpd
 | 
			
		||||
                            # https://github.com/ytdl-org/youtube-dl/issues/30235
 | 
			
		||||
                            # or any mpd generated with Bento4 `mp4dash --no-split --use-segment-list`
 | 
			
		||||
                            segment_duration = calc_segment_duration()
 | 
			
		||||
                            for segment_url, segment_url_range in zip(
 | 
			
		||||
                                    representation_ms_info['segment_urls'], representation_ms_info['segment_urls_range']):
 | 
			
		||||
                                fragments.append({
 | 
			
		||||
                                    location_key(segment_url): segment_url,
 | 
			
		||||
                                    'range': segment_url_range,
 | 
			
		||||
                                    'duration': segment_duration,
 | 
			
		||||
                                })
 | 
			
		||||
                        else:
 | 
			
		||||
                            # Segment URLs with no SegmentTimeline
 | 
			
		||||
                            # Example: https://www.seznam.cz/zpravy/clanek/cesko-zasahne-vitr-o-sile-vichrice-muze-byt-i-zivotu-nebezpecny-39091
 | 
			
		||||
                            # https://github.com/ytdl-org/youtube-dl/pull/14844
 | 
			
		||||
                            fragments = []
 | 
			
		||||
                            segment_duration = float_or_none(
 | 
			
		||||
                                representation_ms_info['segment_duration'],
 | 
			
		||||
                                representation_ms_info['timescale']) if 'segment_duration' in representation_ms_info else None
 | 
			
		||||
                            segment_duration = calc_segment_duration()
 | 
			
		||||
                            for segment_url in representation_ms_info['segment_urls']:
 | 
			
		||||
                                fragment = {
 | 
			
		||||
                                fragments.append({
 | 
			
		||||
                                    location_key(segment_url): segment_url,
 | 
			
		||||
                                }
 | 
			
		||||
                                if segment_duration:
 | 
			
		||||
                                    fragment['duration'] = segment_duration
 | 
			
		||||
                                fragments.append(fragment)
 | 
			
		||||
                            representation_ms_info['fragments'] = fragments
 | 
			
		||||
                        # If there is a fragments key available then we correctly recognized fragmented media.
 | 
			
		||||
                        # Otherwise we will assume unfragmented media with direct access. Technically, such
 | 
			
		||||
                        # assumption is not necessarily correct since we may simply have no support for
 | 
			
		||||
                        # some forms of fragmented media renditions yet, but for now we'll use this fallback.
 | 
			
		||||
                        if 'fragments' in representation_ms_info:
 | 
			
		||||
                            f.update({
 | 
			
		||||
                                # NB: mpd_url may be empty when MPD manifest is parsed from a string
 | 
			
		||||
                                'url': mpd_url or base_url,
 | 
			
		||||
                                'fragment_base_url': base_url,
 | 
			
		||||
                                'fragments': [],
 | 
			
		||||
                                'protocol': 'http_dash_segments',
 | 
			
		||||
                                    'duration': segment_duration,
 | 
			
		||||
                                })
 | 
			
		||||
                        representation_ms_info['fragments'] = fragments
 | 
			
		||||
 | 
			
		||||
                    # If there is a fragments key available then we correctly recognized fragmented media.
 | 
			
		||||
                    # Otherwise we will assume unfragmented media with direct access. Technically, such
 | 
			
		||||
                    # assumption is not necessarily correct since we may simply have no support for
 | 
			
		||||
                    # some forms of fragmented media renditions yet, but for now we'll use this fallback.
 | 
			
		||||
                    if 'fragments' in representation_ms_info:
 | 
			
		||||
                        base_url = representation_ms_info['base_url'] 
 | 
			
		||||
                        f.update({
 | 
			
		||||
                            # NB: mpd_url may be empty when MPD manifest is parsed from a string
 | 
			
		||||
                            'url': mpd_url or base_url,
 | 
			
		||||
                            'fragment_base_url': base_url,
 | 
			
		||||
                            'fragments': [],
 | 
			
		||||
                            'protocol': 'http_dash_segments',
 | 
			
		||||
                        })
 | 
			
		||||
                        if 'initialization_url' in representation_ms_info and 'initialization_url_range' in representation_ms_info:
 | 
			
		||||
                            # Initialization URL with range (accompanied by Segment URLs with mediaRange above)
 | 
			
		||||
                            # https://github.com/ytdl-org/youtube-dl/issues/30235
 | 
			
		||||
                            initialization_url = representation_ms_info['initialization_url']
 | 
			
		||||
                            f['fragments'].append({
 | 
			
		||||
                                location_key(initialization_url): initialization_url,
 | 
			
		||||
                                'range': representation_ms_info['initialization_url_range'],
 | 
			
		||||
                            })
 | 
			
		||||
                            if 'initialization_url' in representation_ms_info:
 | 
			
		||||
                                initialization_url = representation_ms_info['initialization_url']
 | 
			
		||||
                                if not f.get('url'):
 | 
			
		||||
                                    f['url'] = initialization_url
 | 
			
		||||
                                f['fragments'].append({location_key(initialization_url): initialization_url})
 | 
			
		||||
                            f['fragments'].extend(representation_ms_info['fragments'])
 | 
			
		||||
                        else:
 | 
			
		||||
                            # Assuming direct URL to unfragmented media.
 | 
			
		||||
                            f['url'] = base_url
 | 
			
		||||
                        formats.append(f)
 | 
			
		||||
                        elif 'initialization_url' in representation_ms_info:
 | 
			
		||||
                            initialization_url = representation_ms_info['initialization_url']
 | 
			
		||||
                            if not f.get('url'):
 | 
			
		||||
                                f['url'] = initialization_url
 | 
			
		||||
                            f['fragments'].append({location_key(initialization_url): initialization_url})
 | 
			
		||||
                        elif 'initialization_url_range' in representation_ms_info:
 | 
			
		||||
                            # no Initialization URL but range (accompanied by no Segment URLs but mediaRange above)
 | 
			
		||||
                            # https://github.com/ytdl-org/youtube-dl/issues/27575
 | 
			
		||||
                            f['fragments'].append({
 | 
			
		||||
                                location_key(base_url): base_url,
 | 
			
		||||
                                'range': representation_ms_info['initialization_url_range'],
 | 
			
		||||
                            })
 | 
			
		||||
                        f['fragments'].extend(representation_ms_info['fragments'])
 | 
			
		||||
                        if not period_duration:
 | 
			
		||||
                            period_duration = sum(traverse_obj(representation_ms_info, (
 | 
			
		||||
                                'fragments', Ellipsis, 'duration', T(float_or_none))))
 | 
			
		||||
                    else:
 | 
			
		||||
                        # Assuming direct URL to unfragmented media.
 | 
			
		||||
                        f['url'] = representation_ms_info['base_url']
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user