Reputation: 1401
I'm working on an embedded device that is recording video on the fly. I'd like to stream that to an HTML5 video element, using our own custom server. I have this almost working and would like some help.
So far as I can tell, I've got libav / ffmpeg doing their job right. I encoded an mp4 in RAM with the moov atom at the start of the file. I've written this file to disk and it plays everywhere it should.
The problem, I think, lies with how I'm responding to HTTP range requests. When I try to do a live stream, I get an initial range request from the browser / player (currently tried Chrome, Firefox, and VLC) for bytes:0-
. I responded with some initial bytes. The browser / player actually plays this fine, but never asks again. So the live stream doesn't work, just the first 3 seconds or whatever.
I've looked at the RFC spec of partial content, and my understanding is I'm doing what I should be... Clearly I'm not though. Here is an example of a request / response with Chrome as the requester:
get /live.mp4 HTTP/1.1
host: localhost:1235
connection: keep-alive
accept-encoding: identity;q=1, *;q=0
user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.167 Safari/537.36
accept: */*
dnt: 1
accept-language: en-GB,en-US;q=0.9,en;q=0.8
range: bytes=0-
HTTP/1.1 206 Partial Content
Accept-Ranges: bytes
Content-Type: video/mp4
Content-Length: 182400
Content-Range: bytes 0-182399/*
Again, with that request / response pair, Chrome plays the first 182400 bytes but never makes a second request. I thought having the '*' in Content-Range
would make this happen...
Upvotes: 0
Views: 1768
Reputation: 166
You would need to include the total size of the content in the Content-Range
response header for progressive download to function properly. For example: Content-Range: bytes 0-182399/123456789
.
Upvotes: 0
Reputation: 266
I came across a similar issue where it was working perfectly on Firebox but only plays the first fragment of the video in Chrome and does not request any other. My case was solved simply by making the very first response return nothing with a 200
status code and Accept-Ranges: bytes
header.
Looks like it is common, check the update part for the following question: Content-Range working in Safari but not in Chrome
Upvotes: 0
Reputation: 1401
This was the problem. I needed media extensions, it wasn't clear to me that progressive streaming wasn't for live feeds of unknown length. Media extensions and a websocket solved the issue. Also needed to use -dash
for libav to make it work in Chrome.
Upvotes: 0
Reputation: 31120
Progressive download doesn’t work that way. It browser assumes the file will never change. To play a live stream you need to use fragmented MP4 and media source extensions.
Upvotes: 0