can't seek html5 video or audio in chrome
Solution 1
I found the reason why it's not working on this question:
Our server doesn't understand partial content right now. As a result chrome is sending requests for content that doesn't get answered which in turn makes our video's and audio unseekable (and unloopable).
Solution 2
You must handle req.headers['range'] which Chrome will send to your streaming server.
Please refer to my codes below. It worked well on Chrome, Firefox, Edge and IE. I haven't test it on Safari but hopefully it also can work.
I used Sails/Nodejs backend and gridFS/mongodb database for storing Videos files as Chunks.
try {
let foundMetaFile = await GridFS.findOne({id: fileId});
if (!foundMetaFile) return res.status(400).json(Res.error(undefined, {message: `invalid ${fileId} file`}));
let fileLength = foundMetaFile['length'];
let contentType = foundMetaFile['contentType'];
// let chunkSize = foundMetaFile['chunkSize'];
if(req.headers['range']) {
// Range request, partialle stream the file
console.log('Range Reuqest');
var parts = req.headers['range'].replace(/bytes=/, "").split("-");
var partialStart = parts[0];
var partialEnd = parts[1];
var start = parseInt(partialStart, 10);
var end = partialEnd ? parseInt(partialEnd, 10) : fileLength - 1;
var chunkSize = (end - start) + 1;
console.log('Range ', start, '-', end);
res.writeHead(206, {
'Content-Range': 'bytes ' + start + '-' + end + '/' + fileLength,
'Accept-Ranges': 'bytes',
'Content-Length': chunkSize,
'Content-Type': contentType
});
}
let { mongodbConnection } = global;
let bucket = new GridFSBucket(mongodbConnection, { bucketName: 'fs' });
return new Promise ((resolve, reject) => {
let downloadStream = bucket.openDownloadStream(fileId);
downloadStream.on('error', (err) => {
console.log("Received Error stream")
res.end();
reject(err);
})
downloadStream.on('end', () => {
console.log("Received End stream");
res.end();
resolve(true);
})
console.log("start streaming");
downloadStream.pipe(res);
})
} catch (error) {
switch (error.name) {
case 'UsageError':
return res.status(400).json(Res.error(undefined, {message: 'invalid Input'}));
case 'AdapterError':
return res.status(400).json(Res.error(undefined, {message: 'adapter Error'}));
default:
return res.serverError(error);
}
toxkillfraex
Updated on April 16, 2020Comments
-
toxkillfraex about 4 years
I've been fiddling with the hell that is HTML5 video/audio for a couple of weeks now. Usually the reason why something failed popped up after a while, but I've been, unable to find why I get forwarding and rewinding problems in chrome.
Anyhow...
The video or audio tag is being loaded in an extjs panel when a video or audio file is requested. The files are sent as streams and they work fine in IE and firefox (after adding duration to the response header) There's an issue with safari, but it's apparently the fact that the whole site runs in HTTPS (that's being worked on right now).
In chrome (which is my issue and is at the latest version) the video and audio loads just fine, but I'm unable to rewind or forward. When trying to seek videos just go ahead a few seconds until it reaches the end of the stream. the audio also plays just fine but trying to rewind (or forward) multiple times simply breaks the progress bar and stops the audio from playing on.
I'm not entirely sure what's being sent from the server, but I'm wondering if this might be caused by missing data in the response. If it's not that anything else to point me towards a fix is just as welcome. I think I've covered pretty much the whole set up and I've made sure that there's a source tag for each browser.
edit: this is the code generated by the javascript for one of the files:
<video width="1889" height="2" preload="auto" autoplay="1" controls="1" id="videoPlayer" style="width: 1889px; height: 233px; "> <source src="http://localhost:8080/epaServer/epa/documents/496.ds_webm?sessionId=5616fde4-50af-43d6-a57c-f06540b64fcb" type="video/webm"> <source src="http://localhost:8080/epaServer/epa/documents/496.ds_mp4?sessionId=5616fde4-50af-43d6-a57c-f06540b64fcb" type="video/mp4"> <div>Your browser doesn't support html5 video. <a>Upgrade Chrome</a></div> </video>
I've also found that I can't seek any of the files even if I open them separately from the application.
I've tried to find more info on my own these are the headers chrome shows in the network tab:
Request URL:https://localhost:8443/epaServer/epa/documents/496.ds_webm?sessionId=5616fde4-50af-43d6-a57c-f06540b64fcb
Request Method:GET
Status Code:200 OK
Request Headers
Accept:/ Accept-Charset:ISO-8859-1,utf-8;q=0.7,*;q=0.3
Accept-Encoding:identity;q=1, *;q=0
Accept-Language:en-US,en;q=0.8
Connection:keep-alive
Cookie:sessionId=5616fde4-50af-43d6-a57c-f06540b64fcb
Host:localhost:8443
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.168 Safari/535.19
Query String Parametersview URL encoded
sessionId:5616fde4-50af-43d6-a57c-f06540b64fcb
Response Headers
Cache-Control:private
Content-Length:1588816
Content-Type:video/webm
Date:Mon, 14 May 2012 14:23:02 GMT
Expires:Thu, 01 Jan 1970 01:00:00 CET
Server:Apache-Coyote/1.1
X-Content-Duration:17.31
>
-
toxkillfraex almost 12 yearsI've added some of the code that's being generated and the headers I'm getting.
-
Arvind Singh about 10 yearsJust to make a note for people like me who are just looking for browser capable of seeking I suggest to try using alternate browser like Mozilla Firefox (ver 29.0 tested capable of seeking).
-
Ujjawal Mandhani almost 3 yearsyou can check the encoding of the video. stackoverflow.com/a/68574159/14737117
-
-
Pham Duc Toan about 4 yearsPlease update the code with " let downloadStream = bucket.openDownloadStream(fileId, {start: start, end: end}); " --> which set options starting and end points of the streaming.