From f61290121d63a6c6ca0260508ebe0bc8d33d8d4b Mon Sep 17 00:00:00 2001 From: 738NGX Date: Fri, 26 Dec 2025 15:30:22 +0800 Subject: [PATCH 1/3] support video play back without asset loading --- src/stores/constructRenderState.js | 18 ++++++--- vt/specs/video/background.yaml | 53 +++++++++++++++++++++++++ vt/specs/video/visual.yaml | 63 ++++++++++++++++++++++++++++++ vt/static/main.js | 10 ++++- 4 files changed, 136 insertions(+), 8 deletions(-) create mode 100644 vt/specs/video/background.yaml create mode 100644 vt/specs/video/visual.yaml diff --git a/src/stores/constructRenderState.js b/src/stores/constructRenderState.js index 12ec5882..bce8e66d 100644 --- a/src/stores/constructRenderState.js +++ b/src/stores/constructRenderState.js @@ -76,17 +76,20 @@ export const addBackgroundOrCg = ( } if (presentationState.background.resourceId) { - const { images = {} } = resources; - const background = images[presentationState.background.resourceId]; + const { images = {}, videos = {} } = resources; + const background = images[presentationState.background.resourceId] || videos[presentationState.background.resourceId]; if (background) { + const isVideo = videos[presentationState.background.resourceId] !== undefined; storyContainer.children.push({ id: `bg-cg-${presentationState.background.resourceId}`, - type: "sprite", + type: isVideo ? "video" : "sprite", x: 0, y: 0, src: background.fileId, width: background.width, height: background.height, + loop: isVideo ? true : undefined, + volume: isVideo ? 1000 : undefined, }); } } @@ -279,14 +282,15 @@ export const addVisuals = (state, { presentationState, resources }) => { for (const item of items) { // Check if both resourceId and resourceType exist, and resourceType is "image" if (item.resourceId) { - const { images = {} } = resources; - let resource = images[item.resourceId]; + const { images = {}, videos = {} } = resources; + let resource = images[item.resourceId] || videos[item.resourceId]; if (resource) { + const isVideo = videos[item.resourceId] !== undefined; const transform = resources.transforms[item.transformId]; storyContainer.children.push({ id: `visual-${item.id}`, - type: "sprite", + type: isVideo ? "video" : "sprite", src: resource.fileId, width: resource.width, height: resource.height, @@ -297,6 +301,8 @@ export const addVisuals = (state, { presentationState, resources }) => { rotation: transform.rotation, scaleX: transform.scaleX, scaleY: transform.scaleY, + loop: isVideo ? true : undefined, + volume: isVideo ? 1000 : undefined, }); } } diff --git a/vt/specs/video/background.yaml b/vt/specs/video/background.yaml new file mode 100644 index 00000000..58994a0b --- /dev/null +++ b/vt/specs/video/background.yaml @@ -0,0 +1,53 @@ +--- +title: "Video Background" +description: Test video playback as background +--- +l10n: + packages: + eklekfjwalefj: + label: English + lang: en + keys: {} + +screen: + width: 1920 + height: 1080 + backgroundColor: "#000000" + +resources: + layouts: + base1: + elements: + - id: bg-rect + type: rect + fill: "#000000" + width: 1920 + height: 1080 + click: + actionPayload: + actions: + nextLine: {} + + videos: + video_sample_resource: + fileId: video_sample + width: 1920 + height: 1080 + +story: + initialSceneId: videoScene + scenes: + videoScene: + name: Video Scene + initialSectionId: videoSection + sections: + videoSection: + name: Video Section + lines: + - id: line1 + actions: + base: + resourceId: base1 + background: + resourceId: video_sample_resource + resourceType: video diff --git a/vt/specs/video/visual.yaml b/vt/specs/video/visual.yaml new file mode 100644 index 00000000..e395ff66 --- /dev/null +++ b/vt/specs/video/visual.yaml @@ -0,0 +1,63 @@ +--- +title: "Video Visual" +description: Test video playback as visual element +--- +l10n: + packages: + eklekfjwalefj: + label: English + lang: en + keys: {} + +screen: + width: 1920 + height: 1080 + backgroundColor: "#000000" + +resources: + layouts: + base1: + elements: + - id: bg-rect + type: rect + fill: "#000000" + width: 1920 + height: 1080 + click: + actionPayload: + actions: + nextLine: {} + + videos: + video_sample_resource: + fileId: video_sample + width: 1920 + height: 1080 + + transforms: + centerPos: + x: 960 + y: 540 + anchorX: 0.5 + anchorY: 0.5 + +story: + initialSceneId: videoScene + scenes: + videoScene: + name: Video Scene + initialSectionId: videoSection + sections: + videoSection: + name: Video Section + lines: + - id: line1 + actions: + base: + resourceId: base1 + visual: + items: + - id: video-visual + resourceId: video_sample_resource + resourceType: video + transformId: centerPos diff --git a/vt/static/main.js b/vt/static/main.js index 2318dda8..fa76fc46 100644 --- a/vt/static/main.js +++ b/vt/static/main.js @@ -12,7 +12,8 @@ import createRouteGraphics, { textRevealingPlugin, tweenPlugin, soundPlugin, -} from "https://cdn.jsdelivr.net/npm/route-graphics@0.0.15/+esm" + videoPlugin, +} from "https://cdn.jsdelivr.net/npm/route-graphics@0.0.16/+esm" const projectData = parse(window.yamlContent); @@ -97,6 +98,10 @@ const init = async () => { "horizontal_idle_thumb": { url: "/public/horizontal_idle_thumb.png", type: "image/png" + }, + "video_sample": { + url: "/public/video_sample.mp4", + type: "video/mp4" } }; @@ -113,7 +118,8 @@ const init = async () => { spritePlugin, sliderPlugin, containerPlugin, - textRevealingPlugin + textRevealingPlugin, + videoPlugin ], animations: [ tweenPlugin From 079a78b5bbd8937abebcfb0014be41abd04d69ec Mon Sep 17 00:00:00 2001 From: 738NGX Date: Fri, 26 Dec 2025 15:46:35 +0800 Subject: [PATCH 2/3] update --- src/stores/constructRenderState.js | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/src/stores/constructRenderState.js b/src/stores/constructRenderState.js index bce8e66d..d0076fc1 100644 --- a/src/stores/constructRenderState.js +++ b/src/stores/constructRenderState.js @@ -80,7 +80,7 @@ export const addBackgroundOrCg = ( const background = images[presentationState.background.resourceId] || videos[presentationState.background.resourceId]; if (background) { const isVideo = videos[presentationState.background.resourceId] !== undefined; - storyContainer.children.push({ + const element = { id: `bg-cg-${presentationState.background.resourceId}`, type: isVideo ? "video" : "sprite", x: 0, @@ -88,9 +88,14 @@ export const addBackgroundOrCg = ( src: background.fileId, width: background.width, height: background.height, - loop: isVideo ? true : undefined, - volume: isVideo ? 1000 : undefined, - }); + }; + + if (isVideo) { + element.loop = background.loop ?? false; + element.volume = background.volume ?? 500; + } + + storyContainer.children.push(element); } } @@ -288,7 +293,7 @@ export const addVisuals = (state, { presentationState, resources }) => { if (resource) { const isVideo = videos[item.resourceId] !== undefined; const transform = resources.transforms[item.transformId]; - storyContainer.children.push({ + const element = { id: `visual-${item.id}`, type: isVideo ? "video" : "sprite", src: resource.fileId, @@ -301,9 +306,14 @@ export const addVisuals = (state, { presentationState, resources }) => { rotation: transform.rotation, scaleX: transform.scaleX, scaleY: transform.scaleY, - loop: isVideo ? true : undefined, - volume: isVideo ? 1000 : undefined, - }); + }; + + if (isVideo) { + element.loop = resource.loop ?? false; + element.volume = resource.volume ?? 500; + } + + storyContainer.children.push(element); } } From a820d3cbf19e4d870ed60a600ac957624264c57a Mon Sep 17 00:00:00 2001 From: 738NGX Date: Fri, 26 Dec 2025 15:53:27 +0800 Subject: [PATCH 3/3] lint --- src/stores/constructRenderState.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/stores/constructRenderState.js b/src/stores/constructRenderState.js index d0076fc1..3f5096a7 100644 --- a/src/stores/constructRenderState.js +++ b/src/stores/constructRenderState.js @@ -77,9 +77,12 @@ export const addBackgroundOrCg = ( if (presentationState.background.resourceId) { const { images = {}, videos = {} } = resources; - const background = images[presentationState.background.resourceId] || videos[presentationState.background.resourceId]; + const background = + images[presentationState.background.resourceId] || + videos[presentationState.background.resourceId]; if (background) { - const isVideo = videos[presentationState.background.resourceId] !== undefined; + const isVideo = + videos[presentationState.background.resourceId] !== undefined; const element = { id: `bg-cg-${presentationState.background.resourceId}`, type: isVideo ? "video" : "sprite",