can't seek html5 video or audio in chrome

后端 未结 2 741
我寻月下人不归
我寻月下人不归 2020-12-13 18:09

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, unabl

相关标签:
2条回答
  • 2020-12-13 18:36

    I found the reason why it's not working on this question:

    HTML5 video will not loop

    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).

    0 讨论(0)
  • 2020-12-13 18:38

    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);
            }
    
    0 讨论(0)
提交回复
热议问题