Apparently HLS (HTTP Live Streaming) requires JS on every platform aside from Apple's. I was looking at that for streaming video + captions but since it requires JS to run it didn't really achieve what I wanted it to.
Maybe you could build an in-memory video stream for each user and just serve it slowly but then they would likely need to press play or you rely on autoplay and I've no idea how well that would play with buffering behaviour.
This solution maps quite closely to the idea that MJPEG is intended for "live" video. And also I find it adorable that it is just an img tag.
Almost every browser accepts, and sends, byte-range headers for video, which is pretty easy to map for an endless stream - you don't have to return the actual length of the video, and if you don't, browsers will treat it as an endless stream.
Whilst you do have to actually trigger the play somehow, the range will come in controllable chunks, so you can respond in kind without trashing the stream.
You can do this with the WebM container, not with MP4. The reason is that the MP4 container requires the video frames to be segmented properly and marked into a metadata part of the file which can be in front or end but cannot be created with an infinite stream. WebM (i.e. VP8/9) is not supported on Apple's platform so you also have to have a fallback of HLS + H.264. But in general its doable with WebM and works pretty nice with low latency compared to segmented formats like HLS and DASH. It's impossible to cache on a CDN of course, which is not the case with HLS.
i actually use fragmented mp4 streams as a method to live stream video directly to a browsers video tag. I can point any common browser directly to that stream and it will start playing immediately... ive written a small utility to proxy requests to an RTMP server and repackage the stream for HTTP clients using just a little bit of overhead.
Not really. The browser need to read the header to know where the video frames are in the file.
The table with pointers to all the frames cannot be made before all the frames are encoded and their size is known. Then you can shuffle the file and move the table to the start (known as faststarting), and in that case you can start viewing the video before it is completely downloaded.
This can't be used for live content, since the encoded frames does not exist at the time you start viewing in that case.
Does it have to know the information for all frames, or just the key frames? If it’s the later, then you could encode so the initial table, has X key frames spread out over a few hours, then force a frame to exist in those locations when encoding the live stream.
You cannot use MP4 for live streaming. The file cannot be demuxed properly if the moov soon is incomplete. Frames cannot be located, it is impossible to decode it in the end. With live streaming, you don't ever have the full file until the end of the event, which is why you cannot stream it. Video streaming with a complete file is possible of course, but that is nothing special nor related to this discussion.
HLS is one of those standards that I find absolutely maddening and clearly only exists because a number of things are completely broken. It also makes it much harder to capture or intercept the stream for your own purposes.
Browser/firewall refusing to accept anything other than HTTP? HTTP range requests broken? Connection keepalive broken? I know, we'll segment the video into blocks and send a list of the blocks to download as individual files!
mjpeg is a normal, albeit very simple video stream. While you could certainly squeeze the counter in less bytes by using a more advanced codec with interframe coding, it would be overkill for this poc.
The point im trying to make is more that video streaming is a standard technique with off the shelf solution. The author presents MJPEG as some long lost solution to do this without js, but you can just as easily throw in a <video> tag without JS and call it a day. Except video tags arent as exciting.
If you did that, wouldn’t you need to keep generating frames regardless of whether they updated or not versus this solution that only sends a new jpg down when concurrents change?