can't seek html5 video or audio in chrome
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).
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); }