{
onOpen();
+ setPreviewError(false);
+
+ const snapshotUrl = getSnapshotUrl?.();
+ if (snapshotUrl) {
+ setPreviewUrl(snapshotUrl);
+ return;
+ }
if (video) {
const videoSize = [video.clientWidth, video.clientHeight];
@@ -345,7 +359,7 @@ function FrigatePlusUploadButton({
if (context) {
context.drawImage(video, 0, 0, videoSize[0], videoSize[1]);
- setVideoImg(canvas.toDataURL("image/webp"));
+ setPreviewUrl(canvas.toDataURL("image/webp"));
}
}
}}
@@ -362,14 +376,29 @@ function FrigatePlusUploadButton({
{t("submitFrigatePlus.title")}
-
+ {previewError ? (
+
+
+ {t("submitFrigatePlus.previewError")}
+
+ ) : (
+
setPreviewError(true)}
+ />
+ )}
-
- {t("submitFrigatePlus.submit")}
-
{t("button.cancel", { ns: "common" })}
+
+ {t("submitFrigatePlus.submit")}
+
diff --git a/web/src/components/player/dynamic/DynamicVideoPlayer.tsx b/web/src/components/player/dynamic/DynamicVideoPlayer.tsx
index c8d95090d..5b864aea5 100644
--- a/web/src/components/player/dynamic/DynamicVideoPlayer.tsx
+++ b/web/src/components/player/dynamic/DynamicVideoPlayer.tsx
@@ -181,6 +181,21 @@ export default function DynamicVideoPlayer({
[camera, controller],
);
+ const getSnapshotUrlForPlus = useCallback(
+ (playTime: number) => {
+ if (!controller) {
+ return undefined;
+ }
+
+ const time = controller.getProgress(playTime);
+ if (!time) {
+ return undefined;
+ }
+ return `${apiHost}api/${camera}/recordings/${time}/snapshot.jpg?height=500`;
+ },
+ [apiHost, camera, controller],
+ );
+
// state of playback player
const recordingParams = useMemo(
@@ -312,6 +327,7 @@ export default function DynamicVideoPlayer({
}}
setFullResolution={setFullResolution}
onUploadFrame={onUploadFrameToPlus}
+ getSnapshotUrl={getSnapshotUrlForPlus}
toggleFullscreen={toggleFullscreen}
onError={(error) => {
if (error == "stalled" && !isScrubbing) {