-
-
Notifications
You must be signed in to change notification settings - Fork 646
feat(2d): add playbackRate signal to Video component #831
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
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't have a way to test it rn but shouldn't fastSeekedVideo
set the playbackRate
attribute on the actual video element too?
Seems like the current implementation would cause the video to constantly get out of sync with the playback.
1712e05
to
7f0b42d
Compare
Whenever the |
Sorry, didn't notice you were using the HTML attribute to store the value. import videoA from './videoA.mp4';
import videoB from './videoB.mp4';
// ...
const video = createRef<Video>();
view.add(<Video ref={video} src={videoA} playbackRate={2} />);
// this will reset the playback rate back to 1:
video().src(videoB); |
You're right, the current approach won't work in that scenario. I'll try to rewrite it by removing the getter and setter and reactively set the value on the video instead. |
@rmhartog class Example {
@initial(1)
@signal()
public declare readonly playbackRate: SimpleSignal<number, this>;
protected getPlaybackRate() {
// invoke the native getter:
return this.playbackRate.context.getter();
}
protected setPlaybackRate(playbackRate: number) {
// invoke the native setter:
this.playbackRate.context.setter(playbackRate);
// do some other things:
const video = this.video();
video.playbackRate = playbackRate;
if (playbackRate === 0) {
this.pause();
} else {
const time = useThread().time;
const start = time();
const offset = this.time();
this.time(() => this.clampTime(offset + (time() - start) * playbackRate));
}
}
} |
7f0b42d
to
1a9efd5
Compare
Thanks @aarthificial, that was the missing piece! I've updated the code to imperatively update the time signal if the playbackRate changes and the video is playing, but the |
1a9efd5
to
b9253e3
Compare
Removed the superfluous getter method, think I've covered all comments @aarthificial! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One more thing, setPlaybackRate
pauses the video when the value is 0
but this behavior is not reflected in fastSeekVideo
so there's a possibility that the video won't get paused after the source is changed. It should be easy to fix by expanding this condition at line 208:
const playing = this.playing() && time < video.duration;
b9253e3
to
9141acd
Compare
Updated based on your feedback, last main question for me is the |
9141acd
to
6e1047a
Compare
I'd go for something like this: The `playbackRate` of a `Video` cannot be reactive.
Make sure to use a concrete value and not a function:
```ts
// wrong ✗
video.playbackRate(() => 7);
// correct ✓
video.playbackRate(7);
```
If you're using a signal, extract its value before passing it to the property:
```ts
// wrong ✗
video.playbackRate(mySignal);
// correct ✓
video.playbackRate(mySignal());
``` |
6e1047a
to
109f0f1
Compare
@rmhartog @aarthificial Is there any limits on playbackrate values, can we go more than 16x? |
Added a
playbackRate
signal to the Video component that mirrorsHTMLMediaElement.playbackRate
.Solves #711.