25

I'm having issues seeking in video's using Chrome.

For some reason, no matter what I do, video.seekable.end(0) is always 0.

When I call video.currentTime = 5, followed by console.log(video.currentTime), I see it is always 0, which seems to reset the video.

I've tried both MP4 and VP9-based webm formats, but both gave the same results.

What's more annoying is that Firefox runs everything perfectly. Is there something special about Chrome that I should know about?

Here's my code (which only works in Firefox):

      <div class="myvideo">
        <video width="500" height="300" id="video1" preload="auto">
          <source src="data/video1.webm" type="video/webm"/>
          Your browser does not support videos.
        </video>
      </div>

And here's the javascript:

var videoDiv = $(".myvideo").children().get(0)
videoDiv.load();
  videoDiv.addEventListener("loadeddata", function(){
    console.log("loaded");
    console.log(videoDiv.seekable.end(0)); //Why is this always 0 in Chrome, but not Firefox?
    videoDiv.currentTime = 5;
    console.log(videoDiv.currentTime); //Why is this also always 0 in Chrome, but not Firefox?
  });

Note that simply calling videoDiv.play() does actually correctly play the video in both browsers.

Also, after the movie file is fully loaded, the videoDiv.buffered.end(0) also gives correct values in both browsers.

Tovi7
  • 2,793
  • 3
  • 23
  • 27

5 Answers5

51

It took me a while to figure it out...

The problem turned out to be server-side. I was using a version of Jetty to serve all my video-files. The simple configuration of Jetty did not support byte serving.

The difference between Firefox and Chrome is that Firefox will download the entire video file so that you can seek through it, even if the server does not support http code 206 (partial content). Chrome on the other hand refuses to download the entire file (unless it is really small, like around 2-3mb).

So to get the currentTime parameter of html5 video to be working in Chrome, you need a server that supports http code 206.

For anyone else having this problem, you can double check your server config with curl:

curl -H Range:bytes=16- -I http://localhost:8080/GOPR0001.mp4

This should return code 206. If it returns code 200, Chrome will not be able to seek the video, but Firefox will, due to a workaround in the browser.

And a final tip: You can use npm http-server to get a simple http-server for a local folder that supports partial content:

npm install http-server -g

And run it to serve a local folder:

http-server -p 8000
Tovi7
  • 2,793
  • 3
  • 23
  • 27
  • I have a similar problem, but only on Mac. Chrome refuses to seek, but Firefox works. I am running a http 206 compatible server on my machine and I can see the 206 requests in the network log. Maybe I should ask a new question on SO for this. – Joris Mans Jan 31 '17 at 08:20
  • Are you saying we need to just send the return code as 206 for the seek feature to work in Chrome? – vbNewbie Feb 08 '18 at 13:28
  • No, I'm saying that 206 is a way of checking that partial content can be retrieved from a server. If you are writing your own server, you have to be compliant with the protocol. Chrome uses this information to not have to download the entire video before streaming it. It's efficient. – Tovi7 Feb 08 '18 at 18:03
  • Thank you Tovi7, and forgive me for the additional questions here. We have a Jetty server that handles the video files and currently deliver the full stream in the response. Of course like your case, seek feature doesn't work. So if I understand correctly, even if I send the stream in partial bytes at a time it will not work based on the type of server running? Is there an upgraded version of Jetty that does support byte serving? I have very little experience so just want to get an understanding. – vbNewbie Feb 09 '18 at 06:54
  • This could be related to the `Content-Range` issue I have here for audio files - https://stackoverflow.com/questions/53226595/streaming-audio-in-node-js-with-content-range – loretoparisi Nov 09 '18 at 14:23
2

Work around if modifying server code is unfeasible. Make an API call for you video, then load the blob into URL.createObjectURL and feed that into the src attribute of your video html tag. This will load the entire file and then chrome will know the size of the file allowing seeking capabilities to work.

 axios.get(`${url}`, {
      responseType: "blob"
    })
      .then(function(response) {
        setVideo(URL.createObjectURL(response.data));
      })
      .catch(function(error) {
        // handle error
        console.log(error);
      });
Luis Salas
  • 21
  • 2
1

If you wait for canplaythrough instead of loadeddata, it works.

See this codepen example.

Ian Devlin
  • 18,534
  • 6
  • 55
  • 73
  • I tried this, and I wasn't even aware of the property. Great suggestion, but unfortunately it did not fix my case. I did manage to fix the problem though, but it turned out to be a server side problem... I upvoted your answer though cause I learned something new :-) – Tovi7 Mar 19 '16 at 12:30
  • did you already set your jetty configuration as above because using your suggestion did not work for me – vbNewbie Feb 05 '18 at 09:44
0

You have 3 possibilities for the Video tag: MP4, OGG, WebM.

Not all formats work in all browsers.

Here, I'm thinking that WebM works in Firefox but not Chrome, so you should supply both alternative formats for MP4 and WebM files, by including a 2nd Source tag referring to the MP4 file.

E.g. src="data/video1.mp4" type="video/mp4"

The relevant version will be automatically selected by the browser.

Tony Duffill
  • 277
  • 1
  • 5
  • As mentioned in the question, I actually tried using mp4 in chrome, and it made no difference. Also, it would suprise me that webm would not work in Chrome, since Google is the main driving force behind the entire format. – Tovi7 Mar 02 '16 at 16:43
  • Sorry - you're right on both counts - I should read the question first - and yes, Chrome should certainly deal with WebM. It looks like Ian Devlin has the correct answer. As a quick aside, I have had problems with MP4 files that aren't in H264 format... – Tony Duffill Mar 03 '16 at 17:23
0

I had a similar problem. I was listening for an the end event on a video and setting currentTime to the middle of the video to loop it continuously. It wasn't working in Safari or Chrome.

I think there may be a bug in Safari/Chrome where playhead position properties aren't available unless the media is currently playing.

My workaround was to start my loop just before the video end and not letting it actually end.

Try testing yours by starting playback first and then run your fuction to see if it works in Safari Chrome.

Mysterfxit
  • 126
  • 5
  • This is a great suggestion, but unfortunately it did not help for my particular problem. Thanks though! – Tovi7 Mar 19 '16 at 12:26