ler
ler

Reputation: 1606

Prepare mp4 videos for Media Source Extensions API using ffmpeg

This command produce init.mp4 + bunch of m4s files, i'm trying to play them using MSE :

ffmpeg -i <input file> -f hls -hls_segment_type fmp4 -c:v copy playlist.m3u8

This is the client side code i'm using:

var socket = io();
var video = document.querySelector('video');
var mimeCodec = 'video/mp4; codecs="avc1.64000d,mp4a.40.2"'; 
if ('MediaSource' in window && MediaSource.isTypeSupported(mimeCodec)) {
    var mediaSource = new MediaSource;
    video.src = URL.createObjectURL(mediaSource);
    mediaSource.addEventListener('sourceopen', sourceOpen);
} else {
    console.error('Unsupported MIME type or codec: ', mimeCodec);
}
function sourceOpen (_) {
  var mediaSource = this;
  var sourceBuffer = mediaSource.addSourceBuffer(mimeCodec);
  sourceBuffer.mode = 'sequence'; 
  socket.on('broadcast', function (newPiece) {
      // here i'm getting the buffer of the video  == buffer
      sourceBuffer.addEventListener('updateend', function (_) {
        video.play().then(function() { }).catch(function(error) { });
      });
      sourceBuffer.appendBuffer(buffer); // when the seconde video comes i append it's buffer
  })
};

Everything works fine when i send init.mp4 file followed by playlist0.m4s, playlist1.m4s, playlist2.m4s, ..... But when i try to play init.mp4 file followed immediately 6,7,8 not 0,1,2 meaning playlist6.m4s, playlist7.m4s, playlist8.m4s, ...., it didn't work. I don't know why, this supposed to be live video, the viewer that is watching the live from the beginning gets init.mp4, playlist0.m4s, playlist1.m4s, playlist2.m4s, ..... Someone that came after 5 minutes gets something like this init.mp4, playlist32.m4s, playlist33.m4s, playlist34.m4s, .... and so on, but so far it works only for the viewer that get's init.mp4, playlist0.m4s, playlist1.m4s, playlist2.m4s, ..... the video can't play for the others

Upvotes: 3

Views: 2790

Answers (1)

Pablo Montilla
Pablo Montilla

Reputation: 3050

If you can use fMP4 instead of webm, you can generate a suitable fragmented MP4 using the following command line (geared towards low latency):

ffmpeg -i <input file> -c:v libx264 -profile:v main -level 3.2 -pix_fmt yuv420p -b:v <bitrate> -preset medium -tune zerolatency -flags +cgop+low_delay -movflags empty_moov+omit_tfhd_offset+frag_keyframe+default_base_moof+isml -c:a aac <output file.mp4>

Be sure to use the latest version.

You'll still need to parse the generated MP4 output to send the web client an initialization segment with the moov box, and pairs of moof+mdat boxes as segments for MSE to play video.

Upvotes: 3

Related Questions