2
votes

I'm trying to set up a video server with MPEG-Dash where the video content is hosted on an S3 bucket. When hosted locally (nginx server) it works fine, but when I alter the MPD file to point to the S3 bucket, it doesn't work.

Here's what I'm doing:

--First I convert the video to multi-bitrate MP4

/usr/bin/ffmpeg -y -async 1 -vsync -1 -analyzeduration 999999999 -i <SOURCE> \
    -movflags faststart -keyint_min 30 -x264opts "keyint=30:min-keyint=30:no-scenecut" -g 30 -filter:v "scale=iw*min(320/iw\,180/ih):ih*min(320/iw\,180/ih), pad=320:180:(320-iw*min(320/iw\,180/ih))/2:(180-ih*min(320/iw\,180/ih))/2" -r:v 30 -s 320x180 -b:v 320k -c:v libx264 -pix_fmt yuv420p -profile:v baseline -level 3.0 -an "'.$base.'180p.mp4" \
    -movflags faststart -keyint_min 30 -x264opts "keyint=30:min-keyint=30:no-scenecut" -g 30 -filter:v "scale=iw*min(640/iw\,360/ih):ih*min(640/iw\,360/ih), pad=640:360:(640-iw*min(640/iw\,360/ih))/2:(360-ih*min(640/iw\,360/ih))/2" -r:v 30 -s 640x360 -b:v 640k -c:v libx264 -pix_fmt yuv420p -profile:v baseline -level 3.0 -an "'.$base.'360p.mp4" \
    -movflags faststart -keyint_min 30 -x264opts "keyint=30:min-keyint=30:no-scenecut" -g 30 -filter:v "scale=iw*min(1280/iw\,720/ih):ih*min(1280/iw\,720/ih), pad=1280:720:(1280-iw*min(1280/iw\,720/ih))/2:(720-ih*min(1280/iw\,720/ih))/2" -r:v 30 -s 1280x720 -b:v 1280k -c:v libx264 -pix_fmt yuv420p -profile:v baseline -level 3.1 -an "'.$base.'720p.mp4" \
    -c:v copy -c:a libfdk_aac -ac 2 -ar 48000 -b:a 96k "'.$base.'aacp.mp4"

--Then I dash it with MP4Box

/usr/bin/MP4Box -dash 10000 -rap -profile dashavc264:onDemand -out "stream.mpd" \
    180p.mp4#video \
    360p.mp4#video \
    720p.mp4#video \
    aacp.mp4#audio

--That results in the following MPD

<?xml version="1.0"?>
<!-- MPD file Generated with GPAC version 0.5.1-DEV-rev4065  on 2015-08-08T02:18:28Z-->
<MPD xmlns="urn:mpeg:dash:schema:mpd:2011" minBufferTime="PT1.500000S" type="static" mediaPresentationDuration="PT0H1M56.11S" profiles="urn:mpeg:dash:profile:isoff-on-demand:2011, http://dashif.org/guildelines/dash264">
 <ProgramInformation moreInformationURL="http://gpac.sourceforge.net">
  <Title>/webdata/temp/10/dash/10.mpd generated by GPAC</Title>
 </ProgramInformation>

 <Period duration="PT0H1M56.11S">
  <AdaptationSet segmentAlignment="true" maxWidth="1280" maxHeight="720" maxFrameRate="30" par="16:9" lang="und">
   <Representation id="1" mimeType="video/mp4" codecs="avc1.42c01e" width="320" height="180" frameRate="30" sar="1:1" startWithSAP="1" bandwidth="349890">
    <BaseURL>180p_track1_dashinit.mp4</BaseURL>
    <SegmentBase indexRangeExact="true" indexRange="900-1075">
      <Initialization range="0-899"/>
    </SegmentBase>
   </Representation>
   <Representation id="2" mimeType="video/mp4" codecs="avc1.42c01e" width="640" height="360" frameRate="30" sar="1:1" startWithSAP="1" bandwidth="701122">
    <BaseURL>360p_track1_dashinit.mp4</BaseURL>
    <SegmentBase indexRangeExact="true" indexRange="900-1075">
      <Initialization range="0-899"/>
    </SegmentBase>
   </Representation>
   <Representation id="3" mimeType="video/mp4" codecs="avc1.42c01f" width="1280" height="720" frameRate="30" sar="1:1" startWithSAP="1" bandwidth="1401368">
    <BaseURL>720p_track1_dashinit.mp4</BaseURL>
    <SegmentBase indexRangeExact="true" indexRange="900-1075">
      <Initialization range="0-899"/>
    </SegmentBase>
   </Representation>
  </AdaptationSet>
  <AdaptationSet segmentAlignment="true" lang="und">
   <Representation id="4" mimeType="audio/mp4" codecs="mp4a.40.2" audioSamplingRate="48000" startWithSAP="1" bandwidth="97736">
    <AudioChannelConfiguration schemeIdUri="urn:mpeg:dash:23003:3:audio_channel_configuration:2011" value="2"/>
    <BaseURL>aacp_track2_dashinit.mp4</BaseURL>
    <SegmentBase indexRangeExact="true" indexRange="837-1012">
      <Initialization range="0-836"/>
    </SegmentBase>
   </Representation>
  </AdaptationSet>
 </Period>
</MPD>

When I edit the MPD to have dynamic URLS:

--PHP source --

<?php
    $temp = S3URL("<VIDEOBUCKET>","10/dash/180p_track1_dashinit.mp4","653");
    echo "<BaseURL>".str_replace("https://<VIDEOBUCKET>.s3.amazonaws.com/10/dash/","",$temp)."</BaseURL>".PHP_EOL;
?>

--ECHOED DATA--

<BaseURL>180p_track1_dashinit.mp4?AWSAccessKeyId=XXXXXXXXXX&Expires=XXXXXXXXXX&Signature=XXXXXXXXXX</BaseURL>

I get invalid content on the MPD file. I've looked around and tried moving the BaseURL to the Adaptation, Representation and other stanzas of the XML but nothing seems to work.

What is the correct way of doing this?

1
Which player do you use, bitdash, dash.js, shaka, etc.?Christopher Mueller
@ChristopherMueller, I tried them all...I think it's something to do with where the BaseUrl is placed but the Dash documents are so cryptic I can't figure it out.hdezela

1 Answers

1
votes

I ran into the same issue. The problem I had is that the S3 Presigned URLs have characters that need to be escaped for XML. Otherwise you end up with invalid XML.

I'm using C#, so I had to use the HttpUtility.HtmlEncode() method to make sure that my secure links were not invalidating the XML.