Skip to content

Commit 52ae3db

Browse files
committed
feat(player): new changeClipStart and changeClipEnd on remote control
ref #1330
1 parent 71d4594 commit 52ae3db

5 files changed

Lines changed: 101 additions & 23 deletions

File tree

packages/vidstack/src/core/api/media-request-events.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import type { ScreenOrientationLockType } from '../../foundation/orientation/typ
55
export interface MediaRequestEvents {
66
'media-airplay-request': MediaAirPlayRequestEvent;
77
'media-audio-track-change-request': MediaAudioTrackChangeRequestEvent;
8+
'media-clip-start-change-request': MediaClipStartChangeRequestEvent;
9+
'media-clip-end-change-request': MediaClipEndChangeRequestEvent;
810
'media-duration-change-request': MediaDurationChangeRequestEvent;
911
'media-enter-fullscreen-request': MediaEnterFullscreenRequestEvent;
1012
'media-exit-fullscreen-request': MediaExitFullscreenRequestEvent;
@@ -94,6 +96,24 @@ export type MediaFullscreenRequestTarget = 'prefer-media' | 'media' | 'provider'
9496
*/
9597
export interface MediaAudioTrackChangeRequestEvent extends DOMEvent<number> {}
9698

99+
/**
100+
* Fired when requesting to change the clip start time. The event `detail` specifies the new start
101+
* time in seconds.
102+
*
103+
* @bubbles
104+
* @composed
105+
*/
106+
export interface MediaClipStartChangeRequestEvent extends DOMEvent<number> {}
107+
108+
/**
109+
* Fired when requesting to change the clip end time. The event `detail` specifies the new end
110+
* time in seconds.
111+
*
112+
* @bubbles
113+
* @composed
114+
*/
115+
export interface MediaClipEndChangeRequestEvent extends DOMEvent<number> {}
116+
97117
/**
98118
* Fired when requesting to change the length of the media. The event `detail` specifies the
99119
* new length in seconds.

packages/vidstack/src/core/state/media-request-manager.ts

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -469,15 +469,31 @@ export class MediaRequestManager extends MediaPlayerController implements MediaR
469469
}
470470
}
471471

472-
['media-duration-change-request'](event: RE.MediaDurationChangeRequestEvent) {
473-
const { providedDuration } = this.$state;
474-
providedDuration.set(event.detail);
472+
['media-clip-start-change-request'](event: RE.MediaClipStartChangeRequestEvent) {
473+
const { clipStartTime } = this.$state;
474+
clipStartTime.set(event.detail);
475+
}
476+
477+
['media-clip-end-change-request'](event: RE.MediaClipEndChangeRequestEvent) {
478+
const { clipEndTime } = this.$state;
479+
clipEndTime.set(event.detail);
475480
this.dispatch('duration-change', {
476481
detail: event.detail,
477482
trigger: event,
478483
});
479484
}
480485

486+
['media-duration-change-request'](event: RE.MediaDurationChangeRequestEvent) {
487+
const { providedDuration, clipEndTime } = this.$state;
488+
providedDuration.set(event.detail);
489+
if (clipEndTime() <= 0) {
490+
this.dispatch('duration-change', {
491+
detail: event.detail,
492+
trigger: event,
493+
});
494+
}
495+
}
496+
481497
['media-audio-track-change-request'](event: RE.MediaAudioTrackChangeRequestEvent) {
482498
const { logger, audioTracks } = this._media;
483499

packages/vidstack/src/core/state/media-state-manager.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -554,7 +554,7 @@ export class MediaStateManager extends MediaPlayerController {
554554
}
555555

556556
['duration-change'](event: ME.MediaDurationChangeEvent) {
557-
const { live, intrinsicDuration, providedDuration, ended } = this.$state,
557+
const { live, intrinsicDuration, providedDuration, clipEndTime, ended } = this.$state,
558558
time = event.detail;
559559

560560
if (!live()) {
@@ -563,7 +563,7 @@ export class MediaStateManager extends MediaPlayerController {
563563
if (ended()) this._onEndPrecisionChange(event);
564564
}
565565

566-
if (providedDuration()) {
566+
if (providedDuration() > 0 || clipEndTime() > 0) {
567567
event.stopImmediatePropagation();
568568
}
569569
}

packages/vidstack/src/core/state/media-state-sync.ts

Lines changed: 34 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -13,20 +13,28 @@ export class MediaStateSync extends MediaPlayerController {
1313
if (__SERVER__) return;
1414

1515
if (__DEV__) effect(this._watchLogLevel.bind(this));
16-
effect(this._watchMetadata.bind(this));
17-
effect(this._watchAutoplay.bind(this));
18-
effect(this._watchClipTimes.bind(this));
19-
effect(this._watchControls.bind(this));
20-
effect(this._watchCrossOrigin.bind(this));
21-
effect(this._watchDuration.bind(this));
22-
effect(this._watchLive.bind(this));
23-
effect(this._watchLiveEdge.bind(this));
24-
effect(this._watchLiveTolerance.bind(this));
25-
effect(this._watchLoop.bind(this));
26-
effect(this._watchPlaysInline.bind(this));
27-
effect(this._watchPoster.bind(this));
28-
effect(this._watchProvidedTypes.bind(this));
29-
effect(this._watchTitle.bind(this));
16+
17+
const effects = [
18+
this._watchMetadata,
19+
this._watchAutoplay,
20+
this._watchClipStartTime,
21+
this._watchClipEndTime,
22+
this._watchControls,
23+
this._watchCrossOrigin,
24+
this._watchDuration,
25+
this._watchLive,
26+
this._watchLiveEdge,
27+
this._watchLiveTolerance,
28+
this._watchLoop,
29+
this._watchPlaysInline,
30+
this._watchPoster,
31+
this._watchProvidedTypes,
32+
this._watchTitle,
33+
];
34+
35+
for (const callback of effects) {
36+
effect(callback.bind(this));
37+
}
3038
}
3139

3240
private _init() {
@@ -125,10 +133,18 @@ export class MediaStateSync extends MediaPlayerController {
125133
this.dispatch('plays-inline-change', { detail: inline });
126134
}
127135

128-
private _watchClipTimes() {
129-
const { clipStartTime, clipEndTime } = this.$props;
130-
this.$state.clipStartTime.set(clipStartTime());
131-
this.$state.clipEndTime.set(clipEndTime());
136+
private _watchClipStartTime() {
137+
const { clipStartTime } = this.$props;
138+
this.dispatch('media-clip-start-change-request', {
139+
detail: clipStartTime(),
140+
});
141+
}
142+
143+
private _watchClipEndTime() {
144+
const { clipEndTime } = this.$props;
145+
this.dispatch('media-clip-end-change-request', {
146+
detail: clipEndTime(),
147+
});
132148
}
133149

134150
private _watchLive() {

packages/vidstack/src/core/state/remote-control.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,32 @@ export class MediaRemoteControl {
217217
this._dispatchRequest('media-duration-change-request', trigger, duration);
218218
}
219219

220+
/**
221+
* Dispatch a request to update the clip start time. This is the time at which media playback
222+
* should start at.
223+
*
224+
* @example
225+
* ```ts
226+
* remote.changeClipStart(100); // start at 100 seconds
227+
* ```
228+
*/
229+
changeClipStart(startTime: number, trigger?: Event) {
230+
this._dispatchRequest('media-clip-start-change-request', trigger, startTime);
231+
}
232+
233+
/**
234+
* Dispatch a request to update the clip end time. This is the time at which media playback
235+
* should end at.
236+
*
237+
* @example
238+
* ```ts
239+
* remote.changeClipEnd(100); // end at 100 seconds
240+
* ```
241+
*/
242+
changeClipEnd(endTime: number, trigger?: Event) {
243+
this._dispatchRequest('media-clip-end-change-request', trigger, endTime);
244+
}
245+
220246
/**
221247
* Dispatch a request to update the media volume to the given `volume` level which is a value
222248
* between 0 and 1.

0 commit comments

Comments
 (0)