One composable, two sources. The bars bind the reactive progress ref straight in the template — Vue's fine-grained reactivity updates just those bindings each frame, no component re-render.
duration
useProgress(4000)No media — the engine advances a timeline off the shared frame loop and reports progress each frame.
0%
Paused
Media
useProgress(videoRef) Same composable, fed a <video> ref. Progress tracks currentTime; the buttons drive playback, and scrubbing the native controls updates the bar too.
0%
Paused