简体   繁体   中英

HTML5 video currentTime repaint issue in Chrome

I have been pulling my hair out trying to figure this out. Check out my saga, and codepen below:

I am playing around with some HTML5 video currentTime javascript effects. This one in particular binds currentTime to the angle of a circle and the mouse position, created using d3.js.

My issue is poor performance in Chrome. For some reason the effect is incredibly choppy, effectively unresponsive. If you run it in Firefox, performance is a lot better (albeit still a little choppy).

Now, I think it has to do with the video quality. Is it too poor? For comparison, replace "sky4.mp4" with "apple.mp4" in the src. This is a video I pulled from Apple's iPhone6 site ( https://www.apple.com/iphone-6/ ), it's very high quality and the effect actually runs a lot smoother on both browsers.

I compared video quality, and they are the same FPS (~30fps). Apple's vid has a higher resolution, and a much higher bitrate (10mbps) vs the original (6mpbs). But I assume if all I'm doing is changing the currentTime, then FPS should be the only thing that matters?

I guess not, because replace the src file and check out "space.mp4". It is a very low quality video (15fps, very low res, and 130 kbps). It runs very smoothly on both Chrome and Firefox.

What is going on here? Why is my mediocre quality video not working with this effect while the low and high quality videos do? Can any shed some insight on this? http://codepen.io/jayventura/pen/EaweaJ

(code to make stackoverflow happy)

They're all pretty slow for me, probably because I have an older/slower machine. But I noticed that jumping around in sky4.mp4 uses more CPU than the other two.

In addition to being longer (~7 seconds vs 4s for apple.mp4 and 1s for space.mp4), sky4.mp4 is the only one of the three that's encoded with H.264 High profile; the other two use the Main profile. High profile takes more computation, so you might get faster performance if you reencode it using H.264 Main. That performance might be platform-dependent, though. And of course Main profile is less efficient, quality/bits wise.

The fact that it's longer could be an issue too. Since (I assume) you're mapping the full length of the video onto the 360 degrees of the circle, moving the cursor the same amount will move through more frames of the video with a longer video.

Video formats are meant to be played from start to finish; jumping around and playing backwards are very inefficient. So another thing you could do is try to pre-render the whole video to a bunch of canvas elements. I wouldn't want to do this with a video that was both long and high res, but I've done it with small videos.

With the video element off-screen, create a 2D canvas element of the same size. Set the video element's currentTime to the first frame, wait for its onseeked event, then draw the video to the canvas. Create another canvas and repeat for the next frame, and so on. Then you can instantly show whichever canvas shows the frame that you need.

This requires that the video is loaded from the same domain as the web page it's in, or else is served with CORS headers that allow it to be used as an image source for the canvas.

Another difficulty is that there's no good way for JavaScript to find out the frame rate of the video. But if you're only doing this with your own videos, you know the frame rate.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM