Spent a whole day researching how video streaming works and all I needed was to play a rather large video in the browser (400mb). There are Nginx tutorials, Node.js tutorials, whole media servers and npm packages. None of them are easy solutions. But I figure one out.

1- Convert your video to the HLS format

HTTP Live Streaming (HLS) specification is basically a playlist made for streaming. This is what it looks like:

Manually (in bash) the conversion command is a single line:

ffmpeg -i input.mkv -s 640x360 -hls_time 10 -hls_list_size 0 -f hls video_dir/output.m3u8

Let's explore the command.

ffmpeg is the conversion software (make sure it's installed).
-i input.mkv is your source video file.
-s 640x360 if you want to change resolution.
-hls_time 10 the length of a single video part (seconds)
-hls_list_size 0 shorten the playlist to 0 items so the whole video plays uninterrupted
-f hls the f is for "force format"
video_dir/output.m3u8 is where you want your HLS formatted playlist. You probably want this in a separate folder as it's got a lot of noise.

To automate ffmpeg with Node.js you can use fluent-ffmpeg (you may want a more specific tutorial).

2- Serve the files

Either with Nginx or Node.js and Express. In any case serving them as static files will work just fine.

3- Browser support

Since most browsers don't support HLS (Edge has a feature Chrome doesn't???) you'll have to supplement with a HLS player. Video.js is a neat player and it has a HLS plugin so let's go with that.

The following example is a plain HTML version, you can configure Bower or whatever for the frontend package:

    <video-js id=vid1 width=600 height=300 class="vjs-default-skin" controls>
        <source src="vide_dir/output.m3u8" type="application/x-mpegURL">
    <script src="dist/video.min.js"></script>
    <script src="dist/videojs-http-streaming.min.js"></script>
        var player = videojs('vid1');


So it's basically serving a static video file, just that we need a video-play and to convert the video to the HLS format. Obviously this doesn't serve all purposes, but works pretty damn well.