can't seek html5 video or audio in chrome

48,265

Solution 1

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

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);
        }
Share:
48,265
toxkillfraex
Author by

toxkillfraex

Updated on April 16, 2020

Comments

  • toxkillfraex
    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
      toxkillfraex almost 12 years
      I've added some of the code that's being generated and the headers I'm getting.
    • Arvind Singh
      Arvind Singh about 10 years
      Just 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
      Ujjawal Mandhani almost 3 years
      you can check the encoding of the video. stackoverflow.com/a/68574159/14737117
  • Pham Duc Toan
    Pham Duc Toan about 4 years
    Please update the code with " let downloadStream = bucket.openDownloadStream(fileId, {start: start, end: end}); " --> which set options starting and end points of the streaming.