Skip to content

Commit

Permalink
apply persisted start time
Browse files Browse the repository at this point in the history
  • Loading branch information
suterma committed Dec 30, 2023
1 parent 874a168 commit 24a671b
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 22 deletions.
11 changes: 8 additions & 3 deletions src/code/media/YoutubeMediaHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ export default class YouTubeMediaHandler implements IMediaHandler {

updateCurrentTime(): void {
const currentTime = this.currentTime;
this.debugLog(`updateCurrentTime:${currentTime}`);
this.onCurrentTimeChanged.emit(currentTime);
if (this._player.getPlayerState() == PlayerState.PLAYING) {
window.requestAnimationFrame(() => this.updateCurrentTime());
Expand Down Expand Up @@ -198,13 +199,13 @@ export default class YouTubeMediaHandler implements IMediaHandler {

/** Flag, whether the player is currently playing
* @remarks When the player was playing, any buffering event still is
* considered as playing
* considered as playing.
* @devdoc The current time is only updated, when a meaningful position
* is available.
*/
private _isPlaying = false;

handleStateChange(state: PlayerState): void {
this.updateCurrentTime();

console.debug(
`YouTubeMediaHandler::onStateChange:${PlayerState[state]}`,
);
Expand All @@ -216,10 +217,12 @@ export default class YouTubeMediaHandler implements IMediaHandler {
break;
case PlayerState.ENDED:
/* occurs when the video has ended */
this.updateCurrentTime();
this._isPlaying = false;
this.onEnded.emit();
break;
case PlayerState.PLAYING:
this.updateCurrentTime();
if (!this._isPlaying) {
this._isPlaying = true;
//Upon reception of this event, playback has already started. Fade-in is required if not yet ongoing.
Expand All @@ -232,6 +235,7 @@ export default class YouTubeMediaHandler implements IMediaHandler {
}
break;
case PlayerState.PAUSED:
this.updateCurrentTime();
this._isPlaying = false;
this.onPausedChanged.emit(true);
//Upon reception of this event, playback has already paused.
Expand All @@ -242,6 +246,7 @@ export default class YouTubeMediaHandler implements IMediaHandler {
// NOTE: Buffering does not affect the reported playback state
break;
case PlayerState.VIDEO_CUED:
this.updateCurrentTime();
this._isPlaying = false;
this.onPausedChanged.emit(true);
this.onCanPlay.emit();
Expand Down
18 changes: 4 additions & 14 deletions src/components/track/MediaTrack.vue
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,7 @@
:key="track.Id"
:title="track.Name"
:mediaUrl="mediaUrl"
:start="track.PlayheadPosition"
:trackId="track.Id"
:cues="track.Cues"
:trackPreRoll="track.PreRoll"
Expand All @@ -412,6 +413,7 @@
:key="track.Id"
:title="track.Name"
:url="mediaUrl"
:start="track.PlayheadPosition"
:trackId="track.Id"
:cues="track.Cues"
:trackPreRoll="track.PreRoll"
Expand Down Expand Up @@ -999,25 +1001,13 @@ onUnmounted(() => {
isMounted.value = false;
});
/** The initial playback position, to be applied once after the media is playable
* @remarks The value is retrieved once per component lifetime from
* the persistent storage
*/
let initialPlayheadPosition: number | null = null;
onBeforeMount(() => {
// provide the initial position once
if (props.track?.PlayheadPosition) {
initialPlayheadPosition = props.track.PlayheadPosition;
}
});
// --- Transport ---
/** The playback progress in the current track, in [seconds]
* @remarks This is used for cue event handling within the set of cues, like creating a new cue at the current position
* @devdoc Start with the initial playhead position, which might be non-zero already
*/
const currentPosition = ref(0);
const currentPosition = ref(props.track.PlayheadPosition ?? 0);
provide(currentPositionInjectionKey, readonly(currentPosition));
/** The playback progress in the current track, as a readonly, formatted, displayable text
Expand Down
19 changes: 17 additions & 2 deletions src/components/track/TrackMediaElement.vue
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
<video
controls
:id="mediaElementId"
:src="props.mediaUrl"
:src="mediaUrlWithFragment"
ref="mediaElement"
class="video"
:class="{
Expand All @@ -66,7 +66,7 @@
<!-- use the audio element -->
<audio
:id="mediaElementId"
:src="props.mediaUrl"
:src="mediaUrlWithFragment"
ref="mediaElement"
class="video"
:class="{
Expand Down Expand Up @@ -209,6 +209,15 @@ const props = defineProps({
required: false,
},
/** The start time
* @remark If set, the initial playback position is set to this time, in [seconds], after the resource can be played.
*/
start: {
type: null as unknown as PropType<number | null>,
default: null,
required: false,
},
/** The track id
* @remarks Used to have a unique id on the encapsulated video element
*/
Expand Down Expand Up @@ -407,6 +416,12 @@ const fadeOutDuration = computed(() => {
// --- Transport ---
/** Returns the appliccable mediaUrl with a possible fragment for the start time */
const mediaUrlWithFragment = computed(() => {
const fragment = props.start ? '#t=' + props.start : '';
return props.mediaUrl + fragment;
});
watchEffect(() => {
const fader = mediaHandler.value?.fader;
if (fader) {
Expand Down
5 changes: 2 additions & 3 deletions src/components/track/TrackYouTubeElement.vue
Original file line number Diff line number Diff line change
Expand Up @@ -195,9 +195,8 @@ const {
// Setting the playlist to the one video enables looping the single video itself
// See https://stackoverflow.com/a/25781957/79485
playlist: videoId.value,
start: Math.round(
props.start ?? 0,
) /* MUST be an integer number, otherwise the video starts from the beginning */,
// MUST be an integer number, otherwise the video starts from the beginning
start: props.start ? Math.round(props.start) : undefined,
rel: 0,
},
cookie: true,
Expand Down

0 comments on commit 24a671b

Please sign in to comment.