feat(seed): per-scene loop video + thumbnail for every scene
Each scene now carries both a still (content.scenes.image) AND a short ~1.5s LOOP
video (content.scenes.demo), so the studio scene cards show a looping preview, not
a static swatch.
- LOOP_SCENES = {CharacterStory, LogoMotion3D}: their scenes get a dedicated
per-scene loop ({tid}-{asp}-c{n}-loop.mp4 / {tid}-{asp}-loop.mp4); other
templates fall back to their full preview MP4.
- Renders 42 loops: LogoMotion3D ×3 (frames 30–74) + CharacterStory 13 scenes ×3
aspects (frames (n-1)*90+20 … +64), each a 45-frame / 1.5s clip mid-scene.
- Seed sets image + snapshot_url + demo per scene; verified all 42 serve 200 and
the DB wires each scene to its own still + loop.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -101,6 +101,10 @@ TEXTCOLORS = {
|
|||||||
# the matching render, not the 16:9 cropped). Others reuse the single 16:9 preview.
|
# the matching render, not the 16:9 cropped). Others reuse the single 16:9 preview.
|
||||||
PERASPECT_VIDEO = {"AppShowcase3D", "CharacterStory", "LogoMotion3D"}
|
PERASPECT_VIDEO = {"AppShowcase3D", "CharacterStory", "LogoMotion3D"}
|
||||||
|
|
||||||
|
# Templates that ship a short ~1.5s LOOP video PER SCENE (scene.demo), so the studio
|
||||||
|
# scene cards play a looping preview. Others fall back to the full preview MP4.
|
||||||
|
LOOP_SCENES = {"CharacterStory", "LogoMotion3D"}
|
||||||
|
|
||||||
# Templates whose content is split across MANY scenes (key c1..cN), one editable
|
# Templates whose content is split across MANY scenes (key c1..cN), one editable
|
||||||
# scene card per beat. value = scene count; texts are assigned 2-per-scene in order.
|
# scene card per beat. value = scene count; texts are assigned 2-per-scene in order.
|
||||||
MULTISCENE = {"CharacterStory": len(CS_BEATS)}
|
MULTISCENE = {"CharacterStory": len(CS_BEATS)}
|
||||||
@@ -143,18 +147,20 @@ for idx, (tid, slug, name, desc, dur, texts, (accent, sec, bg)) in enumerate(T):
|
|||||||
# one editable scene card per beat; 2 text fields (title+caption) each.
|
# one editable scene card per beat; 2 text fields (title+caption) each.
|
||||||
for sc in range(1, nscenes + 1):
|
for sc in range(1, nscenes + 1):
|
||||||
skid = uid(f"s-{tid}-{asp}-{sc}")
|
skid = uid(f"s-{tid}-{asp}-{sc}")
|
||||||
scimg = f"{MINIO}/template-media/{tid}-{asp}-c{sc}.png" # per-scene rendered still
|
scimg = f"{MINIO}/template-media/{tid}-{asp}-c{sc}.png" # per-scene still
|
||||||
|
scdemo = f"{MINIO}/template-media/{tid}-{asp}-c{sc}-loop.mp4" if tid in LOOP_SCENES else pvideo
|
||||||
out.append(
|
out.append(
|
||||||
"INSERT INTO content.scenes (id,project_id,key,title,image,snapshot_url,scene_color_svg,default_duration_sec,sort) VALUES ("
|
"INSERT INTO content.scenes (id,project_id,key,title,image,snapshot_url,demo,scene_color_svg,default_duration_sec,sort) VALUES ("
|
||||||
f"{q(skid)},{q(pid)},{q('c'+str(sc))},{q('صحنه '+str(sc))},{q(scimg)},{q(scimg)},{q(swatch_svg([accent,sec,bg,txt]))},{SCENE_SECONDS},{sc-1});")
|
f"{q(skid)},{q(pid)},{q('c'+str(sc))},{q('صحنه '+str(sc))},{q(scimg)},{q(scimg)},{q(scdemo)},{q(swatch_svg([accent,sec,bg,txt]))},{SCENE_SECONDS},{sc-1});")
|
||||||
for pos, (k, title, val) in enumerate(texts[(sc - 1) * 2: sc * 2]):
|
for pos, (k, title, val) in enumerate(texts[(sc - 1) * 2: sc * 2]):
|
||||||
out.append(
|
out.append(
|
||||||
"INSERT INTO content.scene_content_elements (id,scene_id,key,title,type,default_value,position_in_container,direction_layer_value) VALUES ("
|
"INSERT INTO content.scene_content_elements (id,scene_id,key,title,type,default_value,position_in_container,direction_layer_value) VALUES ("
|
||||||
f"{q(uid(f'ce-{tid}-{asp}-{k}'))},{q(skid)},{q(k)},{q(title)},'Text',{q(val)},{pos},1);")
|
f"{q(uid(f'ce-{tid}-{asp}-{k}'))},{q(skid)},{q(k)},{q(title)},'Text',{q(val)},{pos},1);")
|
||||||
else:
|
else:
|
||||||
|
scdemo = f"{MINIO}/template-media/{tid}-{asp}-loop.mp4" if tid in LOOP_SCENES else pvideo
|
||||||
out.append(
|
out.append(
|
||||||
"INSERT INTO content.scenes (id,project_id,key,title,image,snapshot_url,scene_color_svg,default_duration_sec,sort) VALUES ("
|
"INSERT INTO content.scenes (id,project_id,key,title,image,snapshot_url,demo,scene_color_svg,default_duration_sec,sort) VALUES ("
|
||||||
f"{q(sid)},{q(pid)},'c1','صحنه ۱',{q(thumb)},{q(thumb)},{q(swatch_svg([accent,sec,bg,txt]))},{dur},0);")
|
f"{q(sid)},{q(pid)},'c1','صحنه ۱',{q(thumb)},{q(thumb)},{q(scdemo)},{q(swatch_svg([accent,sec,bg,txt]))},{dur},0);")
|
||||||
for pos, (k, title, val) in enumerate(texts):
|
for pos, (k, title, val) in enumerate(texts):
|
||||||
out.append(
|
out.append(
|
||||||
"INSERT INTO content.scene_content_elements (id,scene_id,key,title,type,default_value,position_in_container,direction_layer_value) VALUES ("
|
"INSERT INTO content.scene_content_elements (id,scene_id,key,title,type,default_value,position_in_container,direction_layer_value) VALUES ("
|
||||||
|
|||||||
Reference in New Issue
Block a user