Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Control and coordinate video playback state with css #11587

Open
flackr opened this issue Jan 28, 2025 · 9 comments
Open

Control and coordinate video playback state with css #11587

flackr opened this issue Jan 28, 2025 · 9 comments

Comments

@flackr
Copy link
Contributor

flackr commented Jan 28, 2025

There are many sites which pause offscreen videos and unpause them when onscreen. Similarly sometimes the playback of videos is coordinated with animations. What if we could coordinate this without javascript.

Proposal: Add video-play-state: auto | paused similar to animation-play-state

  • auto would do what the video was doing before.
  • paused will mean that even if a call is made to play the video (e.g. autoplay) it will be paused at its current time.

This would allow a simple animation to pause offscreen videos:

@keyframes play-onscreen {
  0% { video-play-state: auto; }
}
video {
  /* Play while in view, pause offscreen */
  animation: play-onscreen steps(1);
  animation-timeline: view();
  video-play-state: paused;
}

Play videos on hover:

video {
  video-play-state: paused;
  &:hover {
    video-play-state: auto;
  }
}

Or similarly, if you had an animation that required the coordination of multiple videos you could make them start playing at the appropriate time in the animation, e.g.

@keyframes play {
  0% { video-play-state: auto; }
  100% { video-play-state: auto; }
}
@keyframes slide-in {
  0% { transform: translateX(100px); opacity: 0; }
}
@keyframes slide-out {
  100% { transform: translateX(-100px); opacity: 0; }
}
video {
  video-play-state: paused;
}
.video1 {
  video-play-state: paused;
  animation: slide-in 1s, play 100s, slide-out 1s 100s;
}
/* Video2 slides in after video1 finishes and plays and then slides out. */
.video2 {
  video-play-state: paused;
  animation: slide-in 1s 100s, play 100s 100s, slide-out 1s 200s;
}

We could also consider using video-play-state as an alternative to setting the autoplay attribute, e.g. video-play-state: playing could request that the video be playing automatically just as autoplay does.

@ydaniv
Copy link
Contributor

ydaniv commented Jan 28, 2025

Huge +1! This should also allow playing on :hover etc.

@flackr
Copy link
Contributor Author

flackr commented Jan 28, 2025

This should also allow playing on :hover etc.

Great use case! I added a snippet for it to the description.

@ydaniv
Copy link
Contributor

ydaniv commented Jan 29, 2025

Actually, I'm hoping I could hijack this proposal a bit and suggest a sort of an upgrade. The proposed usage here is via animations and view() timeline. So I'm wondering whether we could actually go all the way here and add something like video-trigger and even video-timeline?
video-trigger could get a qualified animation-trigger and then we could reuse the whole type functionality we have there, including using timeline and ranges directly, without using an extra animation in the middle to glue that together.

Regarding video-timeline, that might be a bit of a stretch, perhaps added in a separate issue, but basically using declared timelines for scrubbing a video.

@johannesodland
Copy link

Regarding video-timeline, that might be a bit of a stretch, perhaps added in a separate issue, but basically using declared timelines for scrubbing a video.

We are manually syncing the video.currentTime with scroll-timelines when we need to sync videos to scroll, so video-timeline would be really nice. It would hopefully allow the browser to buffer enough video to make the scrubbing performant as well.

@zaygraveyard
Copy link

Is there any chance this can be extended to include animated images (like GIFs)? 😅

@ydaniv
Copy link
Contributor

ydaniv commented Jan 30, 2025

We are manually syncing the video.currentTime with scroll-timelines when we need to sync videos to scroll, so video-timeline would be really nice.

This is basically the current method: https://codepen.io/ydaniv/pen/VwNraKB?editors=0010, just for reference.

It would hopefully allow the browser to buffer enough video to make the scrubbing performant as well.

It's not so much about buffering, like in the example above, I think it's more about how you compress your video in terms of I, B, and P frames, so that when the browser seeks between frames it appears to be smooth.
Perhaps if this was done internally the browser could also help there, instead of trying to blindly navigate between frames using currentTime.

@johannesodland
Copy link

It's not so much about buffering, like in the example above, I think it's more about how you compress your video in terms of I, B, and P frames, so that when the browser seeks between frames it appears to be smooth. Perhaps if this was done internally the browser could also help there, instead of trying to blindly navigate between frames using currentTime.

Yeah. Currently we compress videos specifically for scrubbing, but this increases the size of the videos. As you say, hopefully browsers can take the ‘video-timeline’ as a hint to process the video
Internally specifically for scrubbing. This would allow us to sync «regular» videos to the scroll.

@flackr
Copy link
Contributor Author

flackr commented Jan 30, 2025

@ydaniv I don't think hijacking this issue for VideoTimeline is a good idea. It has come up on multiple issues and deserves its own issue for discussion, I've opened #11611 for this.

If there are reasons that implementing video-playback-state prevents us from driving videos with timelines then we should discuss it however I think doing one doesn't preclude the other and the latter is likely awkward for the simple animation pausing case which should be simple to specify and implement.

@ydaniv
Copy link
Contributor

ydaniv commented Jan 30, 2025

@ydaniv I don't think hijacking this issue for VideoTimeline is a good idea.

Right, for sure. My intent was mostly to try and suggest adopting a more direct and rich interface for controlling the playback by using something like the animation-trigger API.
Though I agree using this via an animation is a nice and quick solution, it's a bit indirect and limited.
What if we could have a once playback type, besides play/pause? I can also see repeat being used, and even alternate in more obscure use-cases.
But mostly if we can have the timeline and ranges used directly for controlling playback and not have to use an animation in the middle.

It has come up on multiple issues and deserves its own issue for discussion, I've opened #11611 for this.

That's exciting! Thanks for opening.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants