Skip to content

Commit

Permalink
fix: Added seeking state to player UI
Browse files Browse the repository at this point in the history
  • Loading branch information
matvp91 committed Jan 4, 2025
1 parent c79cfba commit dbb8c52
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 8 deletions.
59 changes: 51 additions & 8 deletions packages/app/src/components/PlayerControls.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { Button } from "@nextui-org/react";
import { Events } from "@superstreamer/player";
import cn from "clsx";
import { useRef } from "react";
import { useEffect, useRef, useState } from "react";
import { Selection } from "./Selection";
import { usePlayerSelector } from "../context/PlayerContext";
import { usePlayer, usePlayerSelector } from "../context/PlayerContext";
import { useSeekbar } from "../hooks/useSeekbar";
import type { ReactNode, RefObject } from "react";

Expand Down Expand Up @@ -35,22 +36,45 @@ function PlayButton() {
}

function Seekbar() {
const { player } = usePlayer();
const seekableStart = usePlayerSelector((player) => player.seekableStart);
const time = usePlayerSelector((player) => player.time);
const duration = usePlayerSelector((player) => player.duration);
const seekTo = usePlayerSelector((player) => player.seekTo);

const [lastSeekTime, setLastSeekTime] = useState<number | null>(null);

const seekbar = useSeekbar({
min: seekableStart,
max: duration,
onSeeked: seekTo,
onSeeked: (time) => {
if (seekTo(time)) {
setLastSeekTime(time);
}
},
});

let percentage = Number.isNaN(duration)
? 0
: (time - seekableStart) / (duration - seekableStart);
if (percentage < 0) {
percentage = 0;
useEffect(() => {
if (!player) {
return;
}

const onSeekingChange = () => {
if (!player.seeking) {
setLastSeekTime(null);
}
};

player.on(Events.SEEKING_CHANGE, onSeekingChange);
return () => {
player.off(Events.SEEKING_CHANGE, onSeekingChange);
};
}, [player]);

const fakeTime = lastSeekTime ?? time;
let percentage = getPercentage(fakeTime, duration, seekableStart);
if (seekbar.seeking) {
percentage = seekbar.x;
}

return (
Expand Down Expand Up @@ -209,3 +233,22 @@ function hms(seconds: number) {
"00:00:00"
);
}

function getPercentage(time: number, duration: number, seekableStart: number) {
if (Number.isNaN(duration)) {
return 0;
}

let timeRel = time - seekableStart;
const durationRel = duration - seekableStart;

if (timeRel < 0) {
timeRel = 0;
} else if (timeRel > durationRel) {
timeRel = durationRel;
}

const percentage = timeRel / durationRel;

return percentage;
}
6 changes: 6 additions & 0 deletions packages/player/src/hls-player.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,11 +100,17 @@ export class HlsPlayer {
seekTo(time: number) {
assert(this.hls_);

if (this.state_?.interstitial) {
return false;
}

if (this.hls_.interstitialsManager) {
this.hls_.interstitialsManager.primary.seekTo(time);
} else {
this.media_.currentTime = time;
}

return true;
}

setQuality(height: number | null) {
Expand Down
3 changes: 3 additions & 0 deletions packages/player/src/state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ export class State implements StateProperties {

setInterstitial(interstitial: Interstitial | null) {
this.interstitial = interstitial;
this.setSeeking(false);
this.params_.onEvent(Events.INTERSTITIAL_CHANGE);
}

Expand Down Expand Up @@ -163,11 +164,13 @@ export class State implements StateProperties {
return;
}
this.seeking = seeking;
this.requestTimingSync();
this.params_.onEvent(Events.SEEKING_CHANGE);
}

setCuePoints(cuePoints: number[]) {
this.cuePoints = cuePoints;
this.requestTimingSync();
this.params_.onEvent(Events.CUEPOINTS_CHANGE);
}

Expand Down

0 comments on commit dbb8c52

Please sign in to comment.