javascripthtml5-videompeg-dashmedia-sourcedash.js

Load MPEG-DASH Segments Non-Sequentially for Seeking


Building an MPEG-DASH player in JavaScript. However, I'm having an issue implementing seek, and there doesn't appear to be much reference material out there in how to handle it with MSE and the corresponding Source Buffer object.

As far as I can tell, provided the segments are encoded properly (I'm using individual m4s files via a SegmentTemplate, not byte ranges), one should just have to append the segment for the desired, arbitrary point (say the 10 second mark), and then set the VideoElement's currentTime parameter to the mark, as well. All of this works, I can confirm the segment buffers without error, and the first frame of the segment will even visually load within the VideoElement. However, it won't play, and scrubbing is not possible. No errors, either. It merely acts like it's waiting for more data.

This is remedied by adding all the previous segments, up to the arbitrary point, but that's just not practical. For instance, dash.js doesn't do that (but I can't pin down exactly what it is doing differently to allow for proper seeking). I'm guessing I have to dynamically modify the sidx, mfhd, and/or tfdt boxes somehow, in order to trick the browser into believing I'm loading the segments sequentially – but that seems over-the-top for such a standard.

Anyone know how to jump to an arbitrary point and continue playback, when feeding fragmented MP4 segments to the MSE Source Buffer?


Solution

  • Solved.

    Turns out this will work automatically, so long as:

    A) I-frames are aligned correctly. (They were, but sometimes it's a challenge to tell, in this case, if an error is introduced due to one's encoding or their implementation.)

    B) Segments are loaded at (and following) the seek point. So, if seeking the 10s mark, segment loading should start at the 10s mark and continue onward.

    Strangely, I had this (fairly obvious) setup several times previously, but it failed to play properly or introduced a number of rendering hiccups. As far as I can tell, though, those were due to a minor implementation error in the segment import/buffer routines.