Improve Recordings loading (#10462)

* Show skeleton until video players finishes loading

* Clean up android logic

* Ensure mobile view video is consistent

* Cleanup

* Only show when not scrubbing

* Don't use loading

* Start preview at correct time too

* Fix react race condition

* Be wait for seek to show video player
This commit is contained in:
Nicolas Mowen
2024-03-15 06:52:38 -06:00
committed by GitHub
parent d882cb0f63
commit c66f552280
5 changed files with 63 additions and 18 deletions

View File

@@ -81,13 +81,27 @@ export class DynamicVideoController {
this.playerController.currentTime = seekSeconds;
if (play) {
this.playerController.play();
this.waitAndPlay();
} else {
this.playerController.pause();
}
}
}
waitAndPlay() {
return new Promise((resolve) => {
const onSeekedHandler = () => {
this.playerController.removeEventListener("seeked", onSeekedHandler);
this.playerController.play();
resolve(undefined);
};
this.playerController.addEventListener("seeked", onSeekedHandler, {
once: true,
});
});
}
seekToTimelineItem(timeline: Timeline) {
this.playerController.pause();
this.seekToTimestamp(timeline.timestamp + this.annotationOffset);

View File

@@ -90,12 +90,19 @@ export default function DynamicVideoPlayer({
// initial state
const [isLoading, setIsLoading] = useState(false);
const [source, setSource] = useState(
`${apiHost}vod/${camera}/start/${timeRange.start}/end/${timeRange.end}/master.m3u8`,
);
// start at correct time
useEffect(() => {
if (isScrubbing) {
setIsLoading(true);
}
}, [isScrubbing]);
const onPlayerLoaded = useCallback(() => {
if (!controller || !startTimestamp) {
return;
@@ -140,6 +147,7 @@ export default function DynamicVideoPlayer({
setSource(
`${apiHost}vod/${camera}/start/${timeRange.start}/end/${timeRange.end}/master.m3u8`,
);
setIsLoading(true);
controller.newPlayback({
recordings: recordings ?? [],
@@ -151,14 +159,17 @@ export default function DynamicVideoPlayer({
return (
<div className={`relative ${className ?? ""} cursor-pointer`}>
<div className={`w-full relative ${isScrubbing ? "hidden" : "visible"}`}>
<div
className={`w-full relative ${isScrubbing || isLoading ? "hidden" : "visible"}`}
>
<HlsVideoPlayer
className={` ${wideVideo ? "" : "aspect-video"}`}
className={`${wideVideo ? "" : "aspect-video"}`}
videoRef={playerRef}
currentSource={source}
onTimeUpdate={onTimeUpdate}
onPlayerLoaded={onPlayerLoaded}
onClipEnded={onClipEnded}
onPlaying={() => setIsLoading(false)}
>
{config && focusedItem && (
<TimelineEventOverlay
@@ -169,10 +180,11 @@ export default function DynamicVideoPlayer({
</HlsVideoPlayer>
</div>
<PreviewPlayer
className={`${isScrubbing ? "visible" : "hidden"} ${className ?? ""}`}
className={`${isScrubbing || isLoading ? "visible" : "hidden"} ${className ?? ""}`}
camera={camera}
timeRange={timeRange}
cameraPreviews={cameraPreviews}
startTime={startTimestamp}
onControllerReady={(previewController) => {
setPreviewController(previewController);
}}