feat(backend): add video scene preview generation and endpoint
All checks were successful
Build and Publish Docker Image / deploy (push) Successful in 1m52s
All checks were successful
Build and Publish Docker Image / deploy (push) Successful in 1m52s
- Register a new route `GET /d/{boxID}/scene/{fileID}` to serve video scene previews.
- Implement the `VideoScenesPreview` handler to serve existing previews or generate them on-demand.
- Add helper functions to analyze video frames (e.g., luma calculation to filter out dark frames) and render the final scene thumbnail.
- Update the `fileView` struct to include scene URL and status fields.
This commit is contained in:
@@ -16,6 +16,7 @@
|
||||
sourceURL: preview.dataset.sourceUrl || "",
|
||||
downloadURL: preview.dataset.downloadUrl || "",
|
||||
iconURL: preview.dataset.iconUrl || "",
|
||||
sceneURL: preview.dataset.sceneUrl || "",
|
||||
activeMode: "",
|
||||
defaultMode: "default",
|
||||
pendingMode: "",
|
||||
@@ -24,6 +25,7 @@
|
||||
rawLoaded: false,
|
||||
prismLoaded: false,
|
||||
renderLoaded: false,
|
||||
sceneLoaded: false,
|
||||
renderFullscreenFallback: false,
|
||||
confirmedLargeModes: {},
|
||||
tabs: []
|
||||
@@ -35,6 +37,7 @@
|
||||
defaultPane: preview.querySelector("[data-default-preview]"),
|
||||
imagePane: preview.querySelector("[data-image-preview]"),
|
||||
videoPane: preview.querySelector("[data-video-preview]"),
|
||||
videoScenesPane: preview.querySelector("[data-video-scenes-preview]"),
|
||||
browserAudioPane: preview.querySelector("[data-browser-audio-preview]"),
|
||||
rawPane: preview.querySelector("[data-raw-preview]"),
|
||||
rawOutput: preview.querySelector("[data-raw-output]"),
|
||||
@@ -90,6 +93,9 @@
|
||||
|
||||
if (type.isVideo) {
|
||||
tabs.push({ mode: "video", label: "Video Preview" });
|
||||
if (state.sceneURL && els.videoScenesPane) {
|
||||
tabs.push({ mode: "scenes", label: "Scenes Preview" });
|
||||
}
|
||||
return tabs;
|
||||
}
|
||||
|
||||
@@ -181,6 +187,9 @@
|
||||
show(els.imagePane);
|
||||
} else if (mode === "video") {
|
||||
show(els.videoPane);
|
||||
} else if (mode === "scenes") {
|
||||
show(els.videoScenesPane);
|
||||
ensureScenesPreview();
|
||||
} else if (mode === "browser-audio") {
|
||||
show(els.browserAudioPane);
|
||||
} else if (mode === "raw") {
|
||||
@@ -403,6 +412,7 @@
|
||||
hide(els.defaultPane);
|
||||
hide(els.imagePane);
|
||||
hide(els.videoPane);
|
||||
hide(els.videoScenesPane);
|
||||
hide(els.browserAudioPane);
|
||||
hide(els.rawPane);
|
||||
hide(els.codePane);
|
||||
@@ -498,6 +508,7 @@
|
||||
"default": "Default",
|
||||
"image": "Image preview",
|
||||
"video": "Video preview",
|
||||
"scenes": "Scenes preview",
|
||||
"browser-audio": "Browser preview",
|
||||
"raw": "Raw preview",
|
||||
"code": "Code preview",
|
||||
@@ -506,6 +517,18 @@
|
||||
return labels[mode] || "Preview";
|
||||
}
|
||||
|
||||
function ensureScenesPreview() {
|
||||
if (state.sceneLoaded || !els.videoScenesPane) {
|
||||
return;
|
||||
}
|
||||
var src = els.videoScenesPane.dataset.sceneSrc || state.sceneURL;
|
||||
if (!src) {
|
||||
return;
|
||||
}
|
||||
els.videoScenesPane.src = src;
|
||||
state.sceneLoaded = true;
|
||||
}
|
||||
|
||||
function loadPrism() {
|
||||
if (window.Prism) {
|
||||
return Promise.resolve();
|
||||
|
||||
Reference in New Issue
Block a user