Jump to content
Search Community

Animating the playhead of <video> element. Is it possible?

Ahrengot test
Moderator Tag

Warning: Please note

This thread was started before GSAP 3 was released. Some information, especially the syntax, may be out of date for GSAP 3. Please see the GSAP 3 migration guide and release notes for more information about how to update the code to GSAP 3's syntax. 

Recommended Posts

Hey guys,

 

I have a pretty interesting challenge. I need to animate the "playhead" of a <video> element. Ie the video.currentTime property. Running currentTime through TweenMax like so doesn't work as setting currentTime takes a little while to update, so it simply jumps to it's destination.

 

I suspect what I want to do can't be done using the native <video> element, but I have to use an image sequence and <canvas> instead, but I wanted to check with you bright fellas before venturing down that path :)

 

 

Link to comment
Share on other sites

Hello Ahrengot

 

GSAP can animate any numerical JavaScript object or property. It is just if each browser will allow the progress of the video to be animated based on the file type. Since not all file types are supported in all browsers for HTML5 video.

 

You would need to add a <progress> bar tag and then you can either use GSAP AtrtrPlugin to animate the value attribute:

<progress id="progress-bar" min="0" max="100" value="0">0%</progress>

But you would have to apply the tween within a addEventListener() for the timeupdate event of the video progress. And determine by the duration and currentTime the progress.

 

And or you could setup a div tag with your own custom progress bar that is animated by that same timeupdate event of the progress.

 

But i think you would have to disable the video tags controls and create your own controls and buttons. Then animate the progress like i described above.
 

videoPlayer = document.getElementById('media-video');
videoPlayer.controls = false;


GSAP AttrPlugin: http://greensock.com/docs/#/HTML5/GSAP/Plugins/AttrPlugin/

 

Resources:

progress tag: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/progress

timeupdate event: https://developer.mozilla.org/en-US/docs/Web/Events/timeupdate

currentTime: https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement

duration: https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement

 

:)

  • Like 3
Link to comment
Share on other sites

Haha.. no i don't work for Mozilla, or do I :D  

 

I love HTML5 stuff, so i bare through the frustration, since it keeps changing. Mozilla always keeps their reference on the spec up to date and searchable! Since the W3C and WHATWG are really bad at organizing the spec in a easy accessible format. Especially when you need to find spec info fast. Apple documents ok, but they dont keep their spec reference up to date and focus on webkit. And IE has some good stuff but mostly specific to IE. But even Mozilla, sometimes has references that are useless, but better than the others.

 

I would link more to the W3C spec info but sometimes finding anything in there is not that fun. Boring as it is going through the W3C and WHATWG spec, it can put a twitch in your eye.. or put you to sleep with some dull reading. But i mess with a lot of HTML5 spec for work, so this stuff is always in my brain :blink:

  • Like 2
Link to comment
Share on other sites

Hey Jonathan,

 

Thanks a lot for the elaborate answer. However I think i didn't get my challenge across clearly enough. I'm trying to animate the progress of the video itself. It seems like your solution is for animating a progress indicator, unless I'm missing something?

Link to comment
Share on other sites

Maybe I'm not using a long enough video, but it works fine here.

 

See the Pen 0dbaf4a4e8aad479b6d318f21eb7afe7?editors=001 by osublake (@osublake) on CodePen

Oh wow that is smooth! I wonder if something funky is going on with my video file then, because it takes about 1 full second for it to refresh the currentTime.

 

I'll investigate some more. Thanks for the answers everybody.

  • Like 1
Link to comment
Share on other sites

Sorry for the confusion.. What i was suggesting is to disable the video controls and then animate the progress that is linked to the video tag as it plays. Playing the video with GSAP inside your progress function. But that would require you to create your own custom controls. Kind of like in the Adobe Flash days when you needed to create custom controls for a video player.

 

Modifying

See the Pen 0dbaf4a4e8aad479b6d318f21eb7afe7?editors=001 by osublake (@osublake) on CodePen

you, thanks Blake. You could add a linear tween with no easing.  And then set the duration of the tween to the duration of the video.

See the Pen LpBmwx by jonathan (@jonathan) on CodePen


 

var video = document.querySelector("video");

video.onloadeddata = function() {
  video.pause();
  TweenLite.to(video, 4, { // duration is same as video duration
    currentTime: video.duration,
    ease: Power0.easeNone // adding a linear ease with no easing
  });
};
video.src = "http://v2v.cc/~j/theora_testsuite/320x240.ogg";

Then you can use GSAP methods to play(), pause(), seek() etc with TimelineMax

 

I think you were seeing that jump due to lagSmoothing() trying to keep the tween in sync, since it is on by default. But by making the duration the same as the video duration you make sure the video plays at its appropriate rate.

 

 

:)

  • Like 1
Link to comment
Share on other sites

Hey guys — Thanks again or all of the feedback. 

 

I think this simply has to do with my video file being too large for this to work. Here's your codepen with a larger video, and it acts simmilar to as what I'm seeing with my actual video file. I guess this is a limitation in the way the browser buffers video and there's nothing I can do about it. It even lags this much when I play the video from disc.

 

See the Pen GpBGLe by Ahrengot (@Ahrengot) on CodePen

 

You'll see I also changed the lagSmoothing to a whopping 50.000 and still getting a very laggy result. The small video plays really smoothly though :)

  • Like 1
Link to comment
Share on other sites

You might need to add the preload attribute to your <video> tag.

<video src="myvideo.ogv" preload="auto">
...
</video>

preload
 

The preload attribute is used when autoplay is not used. It is a hint to the browser whether to download some, all or none of the video before a user decides to play the video.

 

It takes one of three values:

  • preload="none" tells the browser not to download any of the video. This saves bandwidth.
  • preload="metadata" tells the browser to download metadata, such as length of the video or its format.
  • preload="auto" tells the browser to do as it sees fit. This may change depending on whether a device is on wifi, 3G, data roaming etc. If you just use preload on its own, this defaults to preload="auto"

In all cases, the browser takes this attribute as a hint, not a command. If both autoplay and preload are used, then preload is ignored.

 

Also take a look at the buffered attribute:

 

https://developer.mozilla.org/en-US/docs/Web/HTML/Element/video

  • buffered
    An attribute you can read to determine which time ranges of the media have been buffered. This attribute contains a TimeRanges object.

And also wrap your JS in a jQuery ready() event or native JS DOMContentLoaded to make sure the DOM is ready.

Then i would also add a window load event inside your DOM ready event so you make sure that all links, stylesheets, videos, and other assets have been loaded as well.

// wait until DOM is ready
document.addEventListener("DOMContentLoaded", function(event) {

  // wait until window, stylesheets, images, links, and other media assets are loaded
  window.onload = function() {


      // add code here


  };

});

Also keep in mind Codepen's servers are slow and have constant lag so you might want to test on your own remote server or local testing environment

 

:)

  • Like 2
Link to comment
Share on other sites

Thanks for the update, however I tried preload before and I think I've found the issue now. It simply seems to be the way the video file is encoded that caused the issue. I was just about to abandon ship and do this whole thing in canvas, when I noticed that Apple uses a video here: http://www.apple.com/mac-pro/

 

I grabbed the video file: http://movies.apple.com/media/us/mac-pro/2013/16C1b6b5-1d91-4fef-891e-ff2fc1c1bb58/videos/macpro_main_desktop.mp4 and replaced my existing one with that. The apple video runs smoothly when I tween currentTime so it simply seems to be an issue with the video.

 

Interresting... 

  • Like 2
Link to comment
Share on other sites

Cool glad you figured it out Ahrengot! Just as a best practice.. when using the HTML5 video tag, its always best to provide more than one video file type using multiple <source> tags. Due to different browsers supporting different video file types. This way you cover yourself with video fallbacks if one video type does not play or is not supported in any browser - mobile or desktop

 

<source> tag: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/source

 

Media formats: https://developer.mozilla.org/en-US/docs/Web/HTML/Supported_media_formats

 

:)

Link to comment
Share on other sites

  • 4 weeks later...

Hi again,

 

second older topic I digg up because they helped me a lot but it's still not perfect,

so I have a video (3 formats) and a cursor to controll it, but it's not smooth at all, even if I followed all recommendations from here.

 

I made a fork you can see here:

See the Pen WrerQp by fripi (@fripi) on CodePen

 

Any idea how to optimise this?

Sorry for the dubble post but it seems more appropriate here, can I delete my other post?

Link to comment
Share on other sites

Hello fripi,

 

This seems more of an issue with jQuery UI Slider.

 

The reason being if you look at the browser inspector. You will see that the jQuery UI handle is animating using the CSS left property, instead of using a transform like translateX (x). And anytime you animate any of the CSS position offset like top, right, bottom, or left. It will animate on a pixel level which will not animate smooth, versus a sub-pixel level with transforms.

 

So you might want to either create your own video scrubber or use the HTML5 <video> element instead.

 

:)

Link to comment
Share on other sites

Dear fripi, 

 

last week, i played around with tweening the current time of a video a lot. I think your code might just work fine - its an issue of the video codec. At least for me it works even with large video sizes now that i have changed settings in the codec - to be precise: it works only when i put a keyframe (I-frame) on every frame in the video codec. Take a look at the program in which you are rendering the video with. In premiere CC (for example) my default settings for keyframes when rendering h264 was every 24 frames - meaning, the codec just takes "full pictures" (pretty much like jpgs as i understand it) every 24th frame. Between these frames he tries to interpolate. We figured: It might just be the case that tweening with greensock between these 24 frames might not work that well, because the codec is not so fast as to figure out the excact interpolation between them. If you make every frame a keyframe in your codec, it works perfectly for me... I hope it does for you as well:)  (ps: please excuse my poor english skills - i hope you are getting what i am trying to convey:)) 

  • Like 3
Link to comment
Share on other sites

As long as you match the duration of the video with the tweens duration, than the tween will animate with the video correctly.

 

See the Pen LpBmwx by jonathan (@jonathan) on CodePen

 

The HTML5 <video> playhead animates on a sub-pixel level, that is why the  html5 <video> tag animates smooth. Unlike the jQuery UI slider that animates on a pixel level, and as a result will animate all clunky.

Link to comment
Share on other sites

  • 11 months later...
  • 1 year later...
On 3.11.2015 at 4:05 PM, Jonathan said:

What i was suggesting is to disable the video controls and then animate the progress that is linked to the video tag as it plays.

 

I am still confused, Jonathan–

I don't see how you can link the <progress>-tag to the <video>-tag

Did I miss the demo where one of you guys did this exact technique?

 

For binding the duration of a video to scroll, I use this so far.

 

var $video = $("video");
var video = $video[0];
var scene = undefined; // preparing scene var

// I had problems with loadedmetadata event
$video.on("canplay", function() {

	// cancel if scene already exists
  	// (Don't ask me how, but this scene got created multiple times without this cancel)
	if (typeof scene === "object") return;

	var duration = video.duration;
	var tl = TweenMax.to(video, duration, { currentTime: duration, ease: Power0.easeNone });
	scene = new ScrollMagic.Scene({
		triggerElement: "video",
		triggerHook: .5,
		duration: "50%" 
	})
	.setTween(tl)
	.addTo(controller)
	.addIndicators()
})

 

Bad performance on Android Chrome though.. a few frames, even if I scroll super slowly.

What's why I want to go to try the <progress> route–

Link to comment
Share on other sites

Hello @kreativzirkel

 

Yes what i meant in that quote you quoted, is the progress (currentTime) of the video element, not the <progress> element. Above i did advise in the 2nd post that they could use an event using timeUpdate and then inside that addEventListener() event handler to update a <progress> bar.

 

Also keep in mind that even through ScrollMagic uses GSAP as its main animation platform. That ScrollMagic is not made by GreenSock.

 

I didn't have time to create a full blown example to animate progress element with video element. But you can see the 2 codepens below. One animates and aria-progressbar way. And the other animates a <progress> bar element.

 

Even though this following cocdepen uses aria-progressbar its the same concept as animating a <progress> element.

 

 

And here is animating a <progress> element with GSAP

 

See the Pen QmNLVM by jonathan (@jonathan) on CodePen

 

Happy Tweening! :)

  • Like 2
Link to comment
Share on other sites

Oh okay; I was somewhat under the impression, that you suggest to animate a <progress>-element that is linked to a <video>-element.

 

I know that ScrollMagic isn't from GreenSock. Worth a shot though, that maybe one of you guys know why this approch might be far away from smooth on mobile devices.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...