Safari: Streaming MP4 files


#1

Hey guys,
I’m just having an issue with streaming videos in mp4 format to Safari. Just for example, I add a video like this to my page:

<video controls preload="auto" >
        <source type="video/mp4" src="http://192.168.178.34:1337/files/videos/565cdde12106f69712f41a6a">
</video>

It’s not working on my Mac and iPhone 6s. When I use Google Chrome, everything works fine. Here are my ffmpeg settings:

                                var norm = new ffmpeg()
                                .input(originalFile.name)
                                .withVideoCodec('libx264')
                                .withAudioCodec('libfaac')
                                .toFormat('mp4')
                                .audioBitrate('128k')
                                .videoBitrate("1000k")
                                .size("?x720");

I also use Sails.js to stream the videos from my GridFS collection to the user, so my response only looks like this:

//Express / Sails.js response

res.set('Content-Type', 'video/mp4');
 var readstream = gfs.createReadStream(options);
 readstream.pipe(res);

I know that Safari has some “special Apple issues” on that topic, but at the moment I don’t know, if I only forgot to set a special header, or my ffmpeg file format is wrong. I only get “Failed to load resource”.


#2

you may need a direct mp4 file name like my.mp4 in URL.


#3

Hey,
thanks for the trick, but that doesn’t work either :frowning: - I can open the original file, if I copy it to my assets folder, but the “streaming” one of GridFS isn’t working. The only difference between both variants are the HTTP headers, the streaming one uses “Transfer-Encoding:chunks” while the other has a fixed Content Length.


#4

So, I’ve got it running, but still having a problem with the headers. I forgot to response the byte range to Safari. Now I can see the video, but safari does some bad byte range requests, just for example, if I open the video, Sails.js logs the following byte-range requests:

undefined
bytes=0-1
bytes=0-285855
bytes=285855-285855
bytes=285855-285855
bytes=285855-285855
bytes=285855-285855
bytes=285855-285855
bytes=285855-285855
bytes=285855-285855
bytes=285855-285855
bytes=285855-285855

//Edit: Okay, I found the problem. I’ve set the wrong Content-Length, this here was wrong:

       res.set('Content-Length', rangeEnd - rangeStart);

This is the correct one:

       res.set('Content-Length', (rangeEnd - rangeStart)+1);