@oh-story/dsh 0.1.8 → 0.1.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -14
- package/lib/client.js +237 -84
- package/lib/client.js.map +3 -3
- package/lib/drama/manifest.json +183 -77
- package/lib/drama/skills/short-drama/SKILL.md +5 -1
- package/lib/drama/skills/short-drama/scripts/creator_markdown_check.py +140 -9
- package/lib/drama/skills/short-drama/scripts/project_tool.py +11 -0
- package/lib/drama/skills/short-drama-assets/references/character-and-look.md +28 -0
- package/lib/drama/skills/short-drama-assets/references/continuity-lock.md +8 -2
- package/lib/drama/skills/short-drama-assets/references/voice-direction.md +28 -0
- package/lib/drama/skills/short-drama-edit/SKILL.md +146 -0
- package/lib/drama/skills/short-drama-edit/agents/openai.yaml +4 -0
- package/lib/drama/skills/short-drama-edit/assets/remotion/README.md +60 -0
- package/lib/drama/skills/short-drama-edit/assets/remotion/package.json +15 -0
- package/lib/drama/skills/short-drama-edit/assets/remotion/remotion.config.ts +6 -0
- package/lib/drama/skills/short-drama-edit/assets/remotion/src/Root.tsx +26 -0
- package/lib/drama/skills/short-drama-edit/assets/remotion/src/Subtitles.tsx +88 -0
- package/lib/drama/skills/short-drama-edit/assets/remotion/src/font.ts +46 -0
- package/lib/drama/skills/short-drama-edit/assets/remotion/src/index.ts +4 -0
- package/lib/drama/skills/short-drama-edit/assets/remotion/src/schema.ts +32 -0
- package/lib/drama/skills/short-drama-edit/assets/remotion/tsconfig.json +13 -0
- package/lib/drama/skills/short-drama-edit/assets//345/211/252/350/276/221/345/215/225.md +43 -0
- package/lib/drama/skills/short-drama-edit/references/cut-craft.md +38 -0
- package/lib/drama/skills/short-drama-edit/references/delivery-verify.md +29 -0
- package/lib/drama/skills/short-drama-edit/references/generated-footage.md +54 -0
- package/lib/drama/skills/short-drama-edit/references/sound-and-subtitles.md +60 -0
- package/lib/drama/skills/short-drama-edit/references/stage-contract.md +51 -0
- package/lib/drama/skills/short-drama-edit/scripts/edit_tool.py +1156 -0
- package/lib/drama/skills/short-drama-edit/scripts/selftest.py +520 -0
- package/lib/drama/skills/short-drama-image-prompts/SKILL.md +2 -0
- package/lib/drama/skills/short-drama-image-prompts/assets/image-prompts.md +5 -0
- package/lib/drama/skills/short-drama-image-prompts/assets/lookdev-prompts.md +3 -0
- package/lib/drama/skills/short-drama-image-prompts/references/common-recipe.md +11 -0
- package/lib/drama/skills/short-drama-novel-analyze/references/aggregation-and-entities.md +2 -2
- package/lib/drama/skills/short-drama-novel-analyze/references/chapter-extraction.md +4 -1
- package/lib/drama/skills/short-drama-produce/SKILL.md +29 -4
- package/lib/drama/skills/short-drama-produce/references/adapter-contract.md +22 -0
- package/lib/drama/skills/short-drama-produce/references/providers/minimax-h3-video.md +13 -12
- package/lib/drama/skills/short-drama-produce/references/providers/minimax-speech.md +41 -0
- package/lib/drama/skills/short-drama-produce/references/providers/seedance.md +7 -0
- package/lib/drama/skills/short-drama-produce/scripts/fixture_adapter.py +18 -1
- package/lib/drama/skills/short-drama-produce/scripts/production_tool.py +181 -2
- package/lib/drama/skills/short-drama-produce/scripts/provider_adapters.py +199 -3
- package/lib/drama/skills/short-drama-review/SKILL.md +2 -0
- package/lib/drama/skills/short-drama-review/references/production-quality-gates.md +7 -0
- package/lib/drama/skills/short-drama-review/references/rubric-visual-motion.md +10 -0
- package/lib/drama/skills/short-drama-storyboard/SKILL.md +12 -1
- package/lib/drama/skills/short-drama-storyboard/assets/keyframe-prompts.md +4 -0
- package/lib/drama/skills/short-drama-storyboard/references/lighting-craft.md +39 -0
- package/lib/drama/skills/short-drama-storyboard/references/shot-craft.md +78 -2
- package/lib/drama/skills/short-drama-storyboard/references/stage-contract.md +2 -0
- package/lib/drama/skills/short-drama-video-prompts/SKILL.md +12 -5
- package/lib/drama/skills/short-drama-video-prompts/references/camera-audio-continuity.md +17 -0
- package/lib/drama/skills/short-drama-video-prompts/references/minimax-h3.md +76 -7
- package/lib/drama/skills/short-drama-video-prompts/references/motion-recipe.md +5 -2
- package/lib/drama/skills/short-drama-video-prompts/references/performance-action-timing.md +21 -0
- package/lib/drama/skills/short-drama-video-prompts/references/production-prompt-grammar.md +6 -17
- package/lib/drama/skills/short-drama-video-prompts/references/seedance-2.0.md +12 -3
- package/lib/drama/skills/short-drama-video-prompts/references/seedance-2.5.md +61 -5
- package/lib/drama/skills/short-drama-video-prompts/references/stage-contract.md +3 -3
- package/lib/drama/skills/short-drama-write/SKILL.md +11 -2
- package/lib/drama/skills/short-drama-write/references/screenplay-format.md +6 -0
- package/lib/drama/skills/short-drama-write/references/stage-contract.md +1 -0
- package/lib/index.js +290 -90
- package/lib/index.js.map +4 -4
- package/lib/novel-to-game/README.md +299 -59
- package/lib/novel-to-game/README_ZH.md +299 -56
- package/lib/novel-to-game/VERSION +1 -1
- package/lib/novel-to-game/examples/jin-ping-mei/build/BUILD_BRIEF.md +3 -1
- package/lib/novel-to-game/examples/jin-ping-mei/build/app/RUN.md +11 -3
- package/lib/novel-to-game/examples/jin-ping-mei/build/app/css/new-guofeng.css +397 -8
- package/lib/novel-to-game/examples/jin-ping-mei/build/app/css/style.css +0 -31
- package/lib/novel-to-game/examples/jin-ping-mei/build/app/js/data.js +71 -73
- package/lib/novel-to-game/examples/jin-ping-mei/build/app/js/engine.js +78 -89
- package/lib/novel-to-game/examples/jin-ping-mei/build/app/js/main.js +37 -14
- package/lib/novel-to-game/examples/jin-ping-mei/build/app/js/text.js +5 -5
- package/lib/novel-to-game/examples/jin-ping-mei/build/app/package.json +2 -1
- package/lib/novel-to-game/examples/jin-ping-mei/qa/README.md +11 -16
- package/lib/novel-to-game/examples/jin-ping-mei/qa/verification.json +11 -11
- package/lib/novel-to-game/examples/jin-ping-mei/qa/verify_playable_model.mjs +23 -0
- package/lib/novel-to-game/manifest.json +77 -87
- package/lib/novel-to-game/skills/game-art-direction/SKILL.md +9 -35
- package/lib/novel-to-game/skills/game-art-direction/references/art-direction-method.md +27 -106
- package/lib/novel-to-game/skills/game-build/SKILL.md +17 -35
- package/lib/novel-to-game/skills/game-build/references/blender-asset-workflow.md +24 -0
- package/lib/novel-to-game/skills/game-build/references/build-brief-contract.md +45 -82
- package/lib/novel-to-game/skills/game-build/references/generative-media-pipeline.md +14 -45
- package/lib/novel-to-game/skills/game-build/references/playable-model-contract.md +30 -65
- package/lib/novel-to-game/skills/game-build/references/tts-production-contract.md +13 -27
- package/lib/novel-to-game/skills/game-concept/SKILL.md +16 -34
- package/lib/novel-to-game/skills/game-concept/references/concept-method.md +28 -75
- package/lib/novel-to-game/skills/game-qa/SKILL.md +9 -20
- package/lib/novel-to-game/skills/game-qa/references/test-design-method.md +10 -6
- package/lib/novel-to-game/skills/game-world-design/SKILL.md +19 -32
- package/lib/novel-to-game/skills/game-world-design/references/narrative-design-method.md +23 -72
- package/lib/novel-to-game/skills/game-world-design/references/numeric-design-method.md +14 -48
- package/lib/novel-to-game/skills/game-world-design/references/world-design-method.md +36 -103
- package/lib/novel-to-game/skills/novel-game-analyze/SKILL.md +9 -18
- package/lib/novel-to-game/skills/novel-game-analyze/references/gameability-protocol.md +4 -4
- package/lib/novel-to-game/skills/novel-to-game/SKILL.md +10 -27
- package/lib/novel-to-game/skills/novel-to-game/references/intake-method.md +5 -6
- package/lib/novel-to-game/skills/novel-to-game/references/pipeline-contract.md +6 -11
- package/lib/oh-story/manifest.json +419 -254
- package/lib/oh-story/roles/chapter-extractor.md +177 -237
- package/lib/oh-story/roles/character-designer.md +1 -1
- package/lib/oh-story/roles/consistency-checker.md +4 -4
- package/lib/oh-story/roles/narrative-writer.md +56 -243
- package/lib/oh-story/roles/story-architect.md +6 -6
- package/lib/oh-story/roles/story-explorer.md +11 -11
- package/lib/oh-story/skills/story/SKILL.md +13 -7
- package/lib/oh-story/skills/story/VERSION +1 -1
- package/lib/oh-story/skills/story/references/author-memory.md +61 -29
- package/lib/oh-story/skills/story/scripts/author_memory_commit.py +934 -170
- package/lib/oh-story/skills/story-cover/SKILL.md +10 -1
- package/lib/oh-story/skills/story-deslop/SKILL.md +54 -229
- package/lib/oh-story/skills/story-deslop/references/anti-ai-writing.md +29 -56
- package/lib/oh-story/skills/story-deslop/references/author-memory.md +61 -29
- package/lib/oh-story/skills/story-deslop/references/banned-words.md +3 -1
- package/lib/oh-story/skills/story-deslop/references/deslop-gates.md +154 -0
- package/lib/oh-story/skills/story-deslop/references/style-resolution.md +27 -0
- package/lib/oh-story/skills/story-deslop/scripts/author_memory_commit.py +934 -170
- package/lib/oh-story/skills/story-deslop/scripts/check-ai-patterns.js +6 -1
- package/lib/oh-story/skills/story-deslop/scripts/check-degeneration.js +39 -20
- package/lib/oh-story/skills/story-deslop/scripts/normalize-punctuation.js +10 -5
- package/lib/oh-story/skills/story-deslop/scripts/style-whitelist.js +39 -0
- package/lib/oh-story/skills/story-import/SKILL.md +78 -82
- package/lib/oh-story/skills/story-import/references/character-state-reverse.md +1 -1
- package/lib/oh-story/skills/story-import/references/format-and-structure.md +2 -2
- package/lib/oh-story/skills/story-import/references/state-tracking.md +4 -69
- package/lib/oh-story/skills/story-import/references/structure-mapping-long.md +10 -8
- package/lib/oh-story/skills/story-import/references/tracking-initialization.md +31 -0
- package/lib/oh-story/skills/story-import/references/tracking-transaction.md +9 -34
- package/lib/oh-story/skills/story-import/scripts/check-outline-contract.js +197 -15
- package/lib/oh-story/skills/story-import/scripts/tracking_commit.py +210 -2
- package/lib/oh-story/skills/story-import/scripts/wordcount_core.py +3 -0
- package/lib/oh-story/skills/story-long-analyze/SKILL.md +91 -258
- package/lib/oh-story/skills/story-long-analyze/references/author-facing.md +245 -0
- package/lib/oh-story/skills/story-long-analyze/references/deconstruction-notes.md +2 -2
- package/lib/oh-story/skills/story-long-analyze/references/inspiration-library.md +105 -0
- package/lib/oh-story/skills/story-long-analyze/references/material-decomposition.md +113 -105
- package/lib/oh-story/skills/story-long-analyze/references/output-templates.md +169 -125
- package/lib/oh-story/skills/story-long-analyze/references/pipeline-ops.md +172 -64
- package/lib/oh-story/skills/story-long-analyze/references/semantic-acceptance-fixtures.md +84 -0
- package/lib/oh-story/skills/story-long-analyze/references/style-profile-generator.md +42 -132
- package/lib/oh-story/skills/story-long-analyze/references/style-profile-protocol.md +5 -5
- package/lib/oh-story/skills/story-long-analyze/scripts/build_chapter_index.py +466 -0
- package/lib/oh-story/skills/story-long-analyze/scripts/inspect_existing_assets.py +702 -0
- package/lib/oh-story/skills/story-long-analyze/scripts/inspiration_index.py +864 -0
- package/lib/oh-story/skills/story-long-analyze/scripts/manage_analysis_run.py +1106 -0
- package/lib/oh-story/skills/story-long-analyze/scripts/render_relation_chart.py +425 -0
- package/lib/oh-story/skills/story-long-scan/SKILL.md +4 -1
- package/lib/oh-story/skills/story-long-write/SKILL.md +52 -216
- package/lib/oh-story/skills/story-long-write/references/anti-ai-writing.md +29 -56
- package/lib/oh-story/skills/story-long-write/references/artifact-protocols.md +72 -12
- package/lib/oh-story/skills/story-long-write/references/author-memory.md +61 -29
- package/lib/oh-story/skills/story-long-write/references/banned-words.md +3 -1
- package/lib/oh-story/skills/story-long-write/references/benchmark-recall.md +20 -0
- package/lib/oh-story/skills/story-long-write/references/cross-book-recall.md +26 -0
- package/lib/oh-story/skills/story-long-write/references/dialogue-mastery.md +10 -4
- package/lib/oh-story/skills/story-long-write/references/emotional-methods.md +2 -2
- package/lib/oh-story/skills/story-long-write/references/long-chapter-quality.md +6 -15
- package/lib/oh-story/skills/story-long-write/references/long-format.md +2 -0
- package/lib/oh-story/skills/story-long-write/references/outline-structure-theory.md +2 -0
- package/lib/oh-story/skills/story-long-write/references/project-files.md +110 -0
- package/lib/oh-story/skills/story-long-write/references/reader-contract-and-progression.md +12 -4
- package/lib/oh-story/skills/story-long-write/references/reference-index.md +86 -0
- package/lib/oh-story/skills/story-long-write/references/style-combat-face.md +1 -1
- package/lib/oh-story/skills/story-long-write/references/style-craft.md +9 -29
- package/lib/oh-story/skills/story-long-write/references/style-genre-modules.md +1 -1
- package/lib/oh-story/skills/story-long-write/references/style-resolution.md +27 -0
- package/lib/oh-story/skills/story-long-write/references/tracking-initialization.md +31 -0
- package/lib/oh-story/skills/story-long-write/references/tracking-transaction.md +9 -34
- package/lib/oh-story/skills/story-long-write/references/workflow-chapter.md +88 -118
- package/lib/oh-story/skills/story-long-write/references/workflow-daily.md +55 -119
- package/lib/oh-story/skills/story-long-write/references/workflow-revision.md +15 -11
- package/lib/oh-story/skills/story-long-write/references/workflow-setup.md +73 -54
- package/lib/oh-story/skills/story-long-write/references/writer-prompt-fallback.md +22 -0
- package/lib/oh-story/skills/story-long-write/references/writing-craft.md +63 -4
- package/lib/oh-story/skills/story-long-write/scripts/author_memory_commit.py +934 -170
- package/lib/oh-story/skills/story-long-write/scripts/build_writer_prompt.py +531 -0
- package/lib/oh-story/skills/story-long-write/scripts/check-ai-patterns.js +6 -1
- package/lib/oh-story/skills/story-long-write/scripts/check-degeneration.js +39 -20
- package/lib/oh-story/skills/story-long-write/scripts/check-outline-contract.js +197 -15
- package/lib/oh-story/skills/story-long-write/scripts/check-outline-copy.js +90 -23
- package/lib/oh-story/skills/story-long-write/scripts/normalize-punctuation.js +10 -5
- package/lib/oh-story/skills/story-long-write/scripts/outline_view.py +285 -0
- package/lib/oh-story/skills/story-long-write/scripts/storyctl.py +58 -0
- package/lib/oh-story/skills/story-long-write/scripts/style-whitelist.js +39 -0
- package/lib/oh-story/skills/story-long-write/scripts/tracking_commit.py +210 -2
- package/lib/oh-story/skills/story-long-write/scripts/wordcount_core.py +3 -0
- package/lib/oh-story/skills/story-review/SKILL.md +80 -87
- package/lib/oh-story/skills/story-review/references/anti-ai-writing.md +29 -56
- package/lib/oh-story/skills/story-review/references/author-memory.md +61 -29
- package/lib/oh-story/skills/story-review/references/banned-words.md +3 -1
- package/lib/oh-story/skills/story-review/references/dialogue-mastery.md +10 -4
- package/lib/oh-story/skills/story-review/references/review-quality.md +6 -12
- package/lib/oh-story/skills/story-review/references/style-resolution.md +27 -0
- package/lib/oh-story/skills/story-review/references/tracking-initialization.md +31 -0
- package/lib/oh-story/skills/story-review/references/tracking-transaction.md +9 -34
- package/lib/oh-story/skills/story-review/scripts/author_memory_commit.py +934 -170
- package/lib/oh-story/skills/story-review/scripts/check-ai-patterns.js +6 -1
- package/lib/oh-story/skills/story-review/scripts/check-degeneration.js +39 -20
- package/lib/oh-story/skills/story-review/scripts/normalize-punctuation.js +10 -5
- package/lib/oh-story/skills/story-review/scripts/style-whitelist.js +39 -0
- package/lib/oh-story/skills/story-review/scripts/tracking_commit.py +210 -2
- package/lib/oh-story/skills/story-review/scripts/wordcount_core.py +3 -0
- package/lib/oh-story/skills/story-setup/SKILL.md +58 -43
- package/lib/oh-story/skills/story-setup/references/agent-references/anti-ai-writing.md +29 -56
- package/lib/oh-story/skills/story-setup/references/agent-references/banned-words.md +3 -1
- package/lib/oh-story/skills/story-setup/references/agent-references/deslop-gates.md +154 -0
- package/lib/oh-story/skills/story-setup/references/agent-references/dialogue-mastery.md +10 -4
- package/lib/oh-story/skills/story-setup/references/agent-references/format-and-structure.md +2 -2
- package/lib/oh-story/skills/story-setup/references/agent-references/long-emotional-methods.md +2 -2
- package/lib/oh-story/skills/story-setup/references/agent-references/long-quality.md +1 -1
- package/lib/oh-story/skills/story-setup/references/agent-references/short-genre-formulas.md +1 -1
- package/lib/oh-story/skills/story-setup/references/agent-references/style-combat-face.md +1 -1
- package/lib/oh-story/skills/story-setup/references/agent-references/style-genre-modules.md +1 -1
- package/lib/oh-story/skills/story-setup/references/agent-references/style-resolution.md +27 -0
- package/lib/oh-story/skills/story-setup/references/agent-references/writing-craft.md +63 -4
- package/lib/oh-story/skills/story-setup/references/diagnostics.md +38 -0
- package/lib/oh-story/skills/story-short-analyze/SKILL.md +22 -3
- package/lib/oh-story/skills/story-short-analyze/references/analysis-writing-techniques.md +1 -1
- package/lib/oh-story/skills/story-short-analyze/references/material-decomposition.md +5 -1
- package/lib/oh-story/skills/story-short-analyze/references/source-story-quality.md +2 -2
- package/lib/oh-story/skills/story-short-scan/SKILL.md +5 -1
- package/lib/oh-story/skills/story-short-write/SKILL.md +15 -324
- package/lib/oh-story/skills/story-short-write/references/author-memory.md +61 -29
- package/lib/oh-story/skills/story-short-write/references/banned-words.md +3 -1
- package/lib/oh-story/skills/story-short-write/references/benchmark-recall.md +60 -0
- package/lib/oh-story/skills/story-short-write/references/dialogue-mastery.md +10 -4
- package/lib/oh-story/skills/story-short-write/references/genre-styles//344/270/226/346/203/205/346/211/223/350/204/270.md +2 -2
- package/lib/oh-story/skills/story-short-write/references/genre-styles//345/217/214/347/224/267/344/270/273.md +1 -1
- package/lib/oh-story/skills/story-short-write/references/genre-styles//345/244/215/344/273/207/346/211/223/350/204/270.md +3 -3
- package/lib/oh-story/skills/story-short-write/references/genre-styles//345/256/205/346/226/227/345/256/253/346/226/227.md +3 -3
- package/lib/oh-story/skills/story-short-write/references/genre-styles//346/200/273/350/243/201/350/261/252/351/227/250.md +3 -3
- package/lib/oh-story/skills/story-short-write/references/genre-styles//346/202/254/347/226/221.md +5 -5
- package/lib/oh-story/skills/story-short-write/references/genre-styles//346/260/221/344/277/227/346/200/252/350/260/210.md +4 -4
- package/lib/oh-story/skills/story-short-write/references/genre-styles//347/224/234/345/256/240.md +5 -5
- package/lib/oh-story/skills/story-short-write/references/genre-styles//350/277/275/345/246/273/347/201/253/350/221/254/345/234/272.md +3 -3
- package/lib/oh-story/skills/story-short-write/references/genre-writing-formulas.md +1 -1
- package/lib/oh-story/skills/story-short-write/references/genre-writing-techniques.md +1 -1
- package/lib/oh-story/skills/story-short-write/references/reference-index.md +55 -0
- package/lib/oh-story/skills/story-short-write/references/short-craft.md +12 -14
- package/lib/oh-story/skills/story-short-write/references/short-deslop.md +10 -10
- package/lib/oh-story/skills/story-short-write/references/short-format.md +3 -1
- package/lib/oh-story/skills/story-short-write/references/short-prose-quality.md +2 -2
- package/lib/oh-story/skills/story-short-write/references/style-resolution.md +27 -0
- package/lib/oh-story/skills/story-short-write/references/workflow-design.md +78 -0
- package/lib/oh-story/skills/story-short-write/references/workflow-draft.md +126 -0
- package/lib/oh-story/skills/story-short-write/references/workflow-revision.md +32 -0
- package/lib/oh-story/skills/story-short-write/references/writing-workflow.md +5 -5
- package/lib/oh-story/skills/story-short-write/scripts/author_memory_commit.py +934 -170
- package/lib/oh-story/skills/story-short-write/scripts/check-ai-patterns.js +6 -1
- package/lib/oh-story/skills/story-short-write/scripts/check-degeneration.js +39 -20
- package/lib/oh-story/skills/story-short-write/scripts/check-delivery-contract.js +34 -5
- package/lib/oh-story/skills/story-short-write/scripts/check-outline-copy.js +90 -23
- package/lib/oh-story/skills/story-short-write/scripts/normalize-punctuation.js +10 -5
- package/lib/oh-story/skills/story-short-write/scripts/style-whitelist.js +39 -0
- package/lib/types/client/drama-production-view.d.ts.map +1 -1
- package/lib/types/client/file-activity.d.ts +19 -1
- package/lib/types/client/file-activity.d.ts.map +1 -1
- package/lib/types/client/index.d.ts.map +1 -1
- package/lib/types/client/production-prompts.d.ts +7 -0
- package/lib/types/client/production-prompts.d.ts.map +1 -1
- package/lib/types/client/production-runtime.d.ts +33 -0
- package/lib/types/client/production-runtime.d.ts.map +1 -1
- package/lib/types/drama-adapters.d.ts +5 -3
- package/lib/types/drama-adapters.d.ts.map +1 -1
- package/lib/types/native-hooks.d.ts +52 -0
- package/lib/types/native-hooks.d.ts.map +1 -1
- package/lib/types/role-identity.d.ts +17 -0
- package/lib/types/role-identity.d.ts.map +1 -0
- package/lib/types/role-tool.d.ts.map +1 -1
- package/lib/types/skill-provider.d.ts.map +1 -1
- package/lib/video-recap/CHANGELOG.md +31 -1
- package/lib/video-recap/manifest.json +162 -162
- package/lib/video-recap/skills/video-assemble/scripts/artifacts.py +4 -9
- package/lib/video-recap/skills/video-assemble/scripts/assemble.py +47 -60
- package/lib/video-recap/skills/video-assemble/scripts/assembly_contract.py +77 -115
- package/lib/video-recap/skills/video-assemble/scripts/assembly_settings.py +41 -40
- package/lib/video-recap/skills/video-assemble/scripts/audio_automation.py +22 -32
- package/lib/video-recap/skills/video-assemble/scripts/audio_mix.py +102 -192
- package/lib/video-recap/skills/video-assemble/scripts/jianying_builders.py +14 -35
- package/lib/video-recap/skills/video-assemble/scripts/jianying_model.py +14 -12
- package/lib/video-recap/skills/video-assemble/scripts/jianying_optional.py +8 -9
- package/lib/video-recap/skills/video-assemble/scripts/jianying_schema.py +3 -14
- package/lib/video-recap/skills/video-assemble/scripts/jianying_timeline_contract.py +23 -12
- package/lib/video-recap/skills/video-assemble/scripts/jianying_tracks.py +1 -4
- package/lib/video-recap/skills/video-assemble/scripts/jianying_writer.py +24 -25
- package/lib/video-recap/skills/video-assemble/scripts/lib.py +31 -85
- package/lib/video-recap/skills/video-assemble/scripts/media.py +100 -144
- package/lib/video-recap/skills/video-assemble/scripts/narration_audio.py +101 -195
- package/lib/video-recap/skills/video-assemble/scripts/render_preflight.py +10 -21
- package/lib/video-recap/skills/video-assemble/scripts/source_subtitles.py +90 -169
- package/lib/video-recap/skills/video-assemble/scripts/subtitle_core.py +69 -122
- package/lib/video-recap/skills/video-assemble/scripts/subtitle_render.py +10 -17
- package/lib/video-recap/skills/video-assemble/scripts/timeline.py +33 -48
- package/lib/video-recap/skills/video-assemble/scripts/timeline_emit.py +14 -20
- package/lib/video-recap/skills/video-assemble/scripts/visual_render.py +135 -213
- package/lib/video-recap/skills/video-cut/scripts/cut_cli.py +49 -57
- package/lib/video-recap/skills/video-cut/scripts/cut_contract.py +38 -74
- package/lib/video-recap/skills/video-cut/scripts/cut_render.py +46 -95
- package/lib/video-recap/skills/video-cut/scripts/lib.py +23 -25
- package/lib/video-recap/skills/video-cut/scripts/media_geometry.py +70 -173
- package/lib/video-recap/skills/video-cut/scripts/narration_mapping.py +28 -53
- package/lib/video-recap/skills/video-cut/scripts/sentence_boundaries.py +162 -322
- package/lib/video-recap/skills/video-recap/references/timeline-and-jianying.md +6 -7
- package/lib/video-recap/skills/video-recap/scripts/doctor.py +104 -124
- package/lib/video-recap/skills/video-recap/scripts/final_qc.py +255 -412
- package/lib/video-recap/skills/video-recap/scripts/lib.py +30 -52
- package/lib/video-recap/skills/video-recap/scripts/materials.py +97 -120
- package/lib/video-recap/skills/video-recap/scripts/mimo_qc_client.py +7 -12
- package/lib/video-recap/skills/video-recap/scripts/mimo_qc_evidence.py +46 -97
- package/lib/video-recap/skills/video-recap/scripts/mimo_qc_observations.py +18 -36
- package/lib/video-recap/skills/video-recap/scripts/mimo_qc_payload.py +29 -47
- package/lib/video-recap/skills/video-recap/scripts/mimo_qc_report.py +43 -76
- package/lib/video-recap/skills/video-recap/scripts/mimo_qc_runner.py +2 -1
- package/lib/video-recap/skills/video-recap/scripts/qc_contract.py +2 -1
- package/lib/video-recap/skills/video-recap/scripts/recap_cli.py +2 -2
- package/lib/video-recap/skills/video-recap/scripts/recap_inspect.py +129 -145
- package/lib/video-recap/skills/video-recap/scripts/recap_review.py +27 -20
- package/lib/video-recap/skills/video-recap/scripts/recap_runner.py +20 -31
- package/lib/video-recap/skills/video-recap/scripts/recap_runtime.py +31 -106
- package/lib/video-recap/skills/video-recap/scripts/recap_stage_qc.py +43 -113
- package/lib/video-recap/skills/video-recap/scripts/recap_timeline.py +196 -377
- package/lib/video-recap/skills/video-script/scripts/agent_brief.py +1 -1
- package/lib/video-recap/skills/video-script/scripts/agent_text.py +63 -172
- package/lib/video-recap/skills/video-script/scripts/brief_context.py +80 -135
- package/lib/video-recap/skills/video-script/scripts/brief_inputs.py +125 -167
- package/lib/video-recap/skills/video-script/scripts/brief_timeline.py +93 -208
- package/lib/video-recap/skills/video-script/scripts/deslop_qc.py +20 -46
- package/lib/video-recap/skills/video-script/scripts/lib.py +30 -26
- package/lib/video-recap/skills/video-script/scripts/narration_lint.py +145 -140
- package/lib/video-recap/skills/video-script/scripts/review_response.py +12 -42
- package/lib/video-recap/skills/video-script/scripts/review_runner.py +0 -6
- package/lib/video-recap/skills/video-script/scripts/speech_ownership.py +39 -100
- package/lib/video-recap/skills/video-script/scripts/timeline_fusion.py +33 -124
- package/lib/video-recap/skills/video-understanding/scripts/agent_brief.py +1 -1
- package/lib/video-recap/skills/video-understanding/scripts/agent_text.py +63 -172
- package/lib/video-recap/skills/video-understanding/scripts/asr.py +1 -2
- package/lib/video-recap/skills/video-understanding/scripts/brief_context.py +80 -135
- package/lib/video-recap/skills/video-understanding/scripts/brief_inputs.py +125 -167
- package/lib/video-recap/skills/video-understanding/scripts/brief_timeline.py +93 -208
- package/lib/video-recap/skills/video-understanding/scripts/consolidate.py +1 -1
- package/lib/video-recap/skills/video-understanding/scripts/deslop_qc.py +20 -46
- package/lib/video-recap/skills/video-understanding/scripts/lib.py +31 -26
- package/lib/video-recap/skills/video-understanding/scripts/narration_lint.py +145 -140
- package/lib/video-recap/skills/video-understanding/scripts/speech_ownership.py +39 -100
- package/lib/video-recap/skills/video-understanding/scripts/timeline_fusion.py +33 -124
- package/lib/video-recap/skills/video-understanding/scripts/vlm.py +1 -4
- package/lib/video-recap/skills/video-voiceover/scripts/dub.py +7 -13
- package/lib/video-recap/skills/video-voiceover/scripts/fish_audio.py +12 -30
- package/lib/video-recap/skills/video-voiceover/scripts/lib.py +98 -131
- package/lib/video-recap/skills/video-voiceover/scripts/tts_audio.py +17 -28
- package/lib/video-recap/skills/video-voiceover/scripts/voiceover.py +151 -240
- package/package.json +45 -45
- package/lib/novel-to-game/skills/game-world-design/references/dialogue-design-method.md +0 -59
- package/lib/novel-to-game/skills/game-world-design/references/game-writing-craft.md +0 -53
- package/lib/novel-to-game/skills/novel-to-game/references/intake-benchmark-reference.md +0 -42
- package/lib/oh-story/skills/story-long-write/references/state-tracking.md +0 -108
|
@@ -41,13 +41,21 @@ MAX_ERROR_BODY_BYTES = 64 * 1024
|
|
|
41
41
|
TERMINAL_FAILURES = {"failed", "cancelled", "canceled", "timeout", "expired"}
|
|
42
42
|
SEEDANCE_RATIOS = {"adaptive", "1:1", "3:4", "4:3", "9:16", "16:9", "21:9"}
|
|
43
43
|
SEEDANCE_REFERENCE_ROLES = {
|
|
44
|
+
"first_frame": "image_url",
|
|
45
|
+
"last_frame": "image_url",
|
|
44
46
|
"reference_image": "image_url",
|
|
45
47
|
"reference_video": "video_url",
|
|
46
48
|
"reference_audio": "audio_url",
|
|
47
49
|
}
|
|
50
|
+
# One opening frame and one closing frame, because each names a single position
|
|
51
|
+
# in the take. Note what is deliberately absent: the sibling adapter forbids
|
|
52
|
+
# mixing frame conditioning with reference conditioning, and that rule belongs
|
|
53
|
+
# to that provider's reference, not to this one. Do not carry it across.
|
|
54
|
+
SEEDANCE_SINGULAR_ROLES = {"first_frame", "last_frame"}
|
|
48
55
|
MINIMAX_VIDEO_RATIOS = {"adaptive", "1:1", "3:4", "4:3", "9:16", "16:9", "21:9"}
|
|
49
56
|
MINIMAX_VIDEO_RESOLUTIONS = {"480P", "768P", "2K"}
|
|
50
57
|
MINIMAX_VIDEO_PROMPT_LIMIT = 7000
|
|
58
|
+
MINIMAX_SPEECH_TEXT_LIMIT = 5000
|
|
51
59
|
MINIMAX_VIDEO_ROLES = {
|
|
52
60
|
"first_frame": "image_url",
|
|
53
61
|
"last_frame": "image_url",
|
|
@@ -369,10 +377,18 @@ def compile_seedance_payload(
|
|
|
369
377
|
counters = {"image_url": 0, "video_url": 0, "audio_url": 0}
|
|
370
378
|
labels = {"image_url": "图片", "video_url": "视频", "audio_url": "音频"}
|
|
371
379
|
reference_tokens: list[str] = []
|
|
380
|
+
singular_seen: set[str] = set()
|
|
372
381
|
for role in reference_roles:
|
|
373
382
|
field = SEEDANCE_REFERENCE_ROLES.get(role)
|
|
374
383
|
if field is None:
|
|
375
384
|
raise ValueError(f"unsupported Seedance reference role: {role}")
|
|
385
|
+
if role in SEEDANCE_SINGULAR_ROLES:
|
|
386
|
+
if role in singular_seen:
|
|
387
|
+
raise ValueError(f"Seedance accepts one {role} reference")
|
|
388
|
+
singular_seen.add(role)
|
|
389
|
+
# A frame role still occupies a picture slot, so it keeps counting: the
|
|
390
|
+
# tokens are positional, and skipping one would point every later
|
|
391
|
+
# `@图片N` in the prose at the wrong picture.
|
|
376
392
|
counters[field] += 1
|
|
377
393
|
reference_tokens.append(f"@{labels[field]}{counters[field]}")
|
|
378
394
|
if task_type in {"edit", "extend"} and "reference_video" not in reference_roles:
|
|
@@ -738,6 +754,82 @@ def compile_gpt_image_2_payload(job: Mapping[str, Any]) -> dict[str, Any]:
|
|
|
738
754
|
}
|
|
739
755
|
|
|
740
756
|
|
|
757
|
+
MINIMAX_SPEECH_EMOTIONS = {
|
|
758
|
+
"happy", "sad", "angry", "fearful", "disgusted", "surprised", "neutral",
|
|
759
|
+
}
|
|
760
|
+
|
|
761
|
+
|
|
762
|
+
def compile_minimax_speech_payload(job: Mapping[str, Any]) -> dict[str, Any]:
|
|
763
|
+
"""Compile a tts job into the official MiniMax speech JSON body.
|
|
764
|
+
|
|
765
|
+
The voice catalogue is deliberately not enumerated here. Which preset voices
|
|
766
|
+
an account can reach depends on the model and the account, no published list
|
|
767
|
+
is authoritative for both, and a list frozen into this file would either
|
|
768
|
+
refuse a voice that works or vouch for one that does not. The document owns
|
|
769
|
+
the value and a reviewer reads it; the adapter only checks its shape.
|
|
770
|
+
"""
|
|
771
|
+
|
|
772
|
+
text, parameters = _require_job(job, "tts")
|
|
773
|
+
parameters = _take(
|
|
774
|
+
parameters,
|
|
775
|
+
{"model", "voice_id", "speed", "vol", "pitch", "emotion",
|
|
776
|
+
"sample_rate", "bitrate", "format"},
|
|
777
|
+
)
|
|
778
|
+
model = parameters.pop("model", "")
|
|
779
|
+
if not isinstance(model, str) or not model.strip():
|
|
780
|
+
raise ValueError("MiniMax speech model must be explicitly configured")
|
|
781
|
+
voice_id = parameters.pop("voice_id", "")
|
|
782
|
+
if not isinstance(voice_id, str) or not voice_id.strip() or voice_id != voice_id.strip():
|
|
783
|
+
raise ValueError("MiniMax speech requires a confirmed voice_id")
|
|
784
|
+
if len(text) > MINIMAX_SPEECH_TEXT_LIMIT:
|
|
785
|
+
raise ValueError("MiniMax speech text exceeds the provider limit")
|
|
786
|
+
|
|
787
|
+
target_format = Path(job["outputs"][0]).suffix.casefold().lstrip(".")
|
|
788
|
+
requested_format = parameters.pop("format", target_format)
|
|
789
|
+
if requested_format != target_format or requested_format not in {"mp3", "wav"}:
|
|
790
|
+
raise ValueError("MiniMax output format must match a supported target extension")
|
|
791
|
+
sample_rate = parameters.pop("sample_rate", 32000)
|
|
792
|
+
bitrate = parameters.pop("bitrate", 128000)
|
|
793
|
+
if sample_rate not in {16000, 24000, 32000, 44100}:
|
|
794
|
+
raise ValueError("unsupported MiniMax sample rate")
|
|
795
|
+
if bitrate not in {32000, 64000, 128000, 256000}:
|
|
796
|
+
raise ValueError("unsupported MiniMax bitrate")
|
|
797
|
+
|
|
798
|
+
voice_setting: dict[str, Any] = {"voice_id": voice_id}
|
|
799
|
+
emotion = parameters.pop("emotion", None)
|
|
800
|
+
if emotion is not None:
|
|
801
|
+
if emotion not in MINIMAX_SPEECH_EMOTIONS:
|
|
802
|
+
raise ValueError("unsupported MiniMax speech emotion")
|
|
803
|
+
voice_setting["emotion"] = emotion
|
|
804
|
+
for name, low, high in (("speed", 0.5, 2.0), ("vol", 0.1, 10.0)):
|
|
805
|
+
value = parameters.pop(name, None)
|
|
806
|
+
if value is None:
|
|
807
|
+
continue
|
|
808
|
+
if isinstance(value, bool) or not isinstance(value, (int, float)):
|
|
809
|
+
raise ValueError(f"MiniMax speech {name} must be a number")
|
|
810
|
+
if not low <= float(value) <= high:
|
|
811
|
+
raise ValueError(f"MiniMax speech {name} is outside the supported range")
|
|
812
|
+
voice_setting[name] = float(value)
|
|
813
|
+
pitch = parameters.pop("pitch", None)
|
|
814
|
+
if pitch is not None:
|
|
815
|
+
if isinstance(pitch, bool) or not isinstance(pitch, int) or not -12 <= pitch <= 12:
|
|
816
|
+
raise ValueError("MiniMax speech pitch is outside the supported range")
|
|
817
|
+
voice_setting["pitch"] = pitch
|
|
818
|
+
|
|
819
|
+
return {
|
|
820
|
+
"model": model.strip(),
|
|
821
|
+
"text": text,
|
|
822
|
+
"stream": False,
|
|
823
|
+
"output_format": "hex",
|
|
824
|
+
"voice_setting": voice_setting,
|
|
825
|
+
"audio_setting": {
|
|
826
|
+
"sample_rate": sample_rate,
|
|
827
|
+
"bitrate": bitrate,
|
|
828
|
+
"format": requested_format,
|
|
829
|
+
},
|
|
830
|
+
}
|
|
831
|
+
|
|
832
|
+
|
|
741
833
|
def compile_minimax_music_payload(job: Mapping[str, Any]) -> dict[str, Any]:
|
|
742
834
|
"""Compile an audio job into the official MiniMax Music 3.0 JSON body."""
|
|
743
835
|
prompt, parameters = _require_job(job, "music")
|
|
@@ -1134,8 +1226,45 @@ def _download(
|
|
|
1134
1226
|
return path
|
|
1135
1227
|
|
|
1136
1228
|
|
|
1229
|
+
def _record_handle(job: Mapping[str, Any], provider_job_id: str) -> None:
|
|
1230
|
+
"""Write the provider task id where the caller can find it after a crash.
|
|
1231
|
+
|
|
1232
|
+
A video task is billed at submission. Everything after that — polling,
|
|
1233
|
+
downloading — can be interrupted, and without this the caller is left with a
|
|
1234
|
+
live, already-paid task it has no id for. Written before the first poll, and
|
|
1235
|
+
deliberately best-effort: failing to record the handle must not fail a task
|
|
1236
|
+
that was submitted successfully.
|
|
1237
|
+
"""
|
|
1238
|
+
|
|
1239
|
+
destination = job.get("handle_path")
|
|
1240
|
+
if not isinstance(destination, str) or not destination:
|
|
1241
|
+
return
|
|
1242
|
+
try:
|
|
1243
|
+
path = Path(destination)
|
|
1244
|
+
path.parent.mkdir(parents=True, exist_ok=True)
|
|
1245
|
+
temporary = path.with_name(f".{path.name}.{os.getpid()}.tmp")
|
|
1246
|
+
temporary.write_text(
|
|
1247
|
+
json.dumps({"provider_job_id": provider_job_id}, ensure_ascii=True),
|
|
1248
|
+
encoding="utf-8",
|
|
1249
|
+
)
|
|
1250
|
+
temporary.replace(path)
|
|
1251
|
+
except OSError:
|
|
1252
|
+
return
|
|
1253
|
+
|
|
1254
|
+
|
|
1255
|
+
def _collect_target(job: Mapping[str, Any]) -> str | None:
|
|
1256
|
+
value = job.get("collect_provider_job_id")
|
|
1257
|
+
if isinstance(value, str) and value:
|
|
1258
|
+
return value
|
|
1259
|
+
return None
|
|
1260
|
+
|
|
1261
|
+
|
|
1137
1262
|
def _run_seedance(job: Mapping[str, Any]) -> tuple[Path, str]:
|
|
1138
1263
|
token = _credential("ARK_API_KEY")
|
|
1264
|
+
base = _base_url("SEEDANCE_BASE_URL", SEEDANCE_BASE_URL)
|
|
1265
|
+
collecting = _collect_target(job)
|
|
1266
|
+
if collecting is not None:
|
|
1267
|
+
return _poll_seedance(job, base=base, token=token, task_id=collecting)
|
|
1139
1268
|
model = os.environ.get("SEEDANCE_MODEL", "")
|
|
1140
1269
|
references = _reference_paths(job)
|
|
1141
1270
|
reference_roles = (
|
|
@@ -1155,7 +1284,6 @@ def _run_seedance(job: Mapping[str, Any]) -> tuple[Path, str]:
|
|
|
1155
1284
|
allowed_ratios=allowed_ratios,
|
|
1156
1285
|
duration_range=duration_range,
|
|
1157
1286
|
)
|
|
1158
|
-
base = _base_url("SEEDANCE_BASE_URL", SEEDANCE_BASE_URL)
|
|
1159
1287
|
created, _ = _request_json(
|
|
1160
1288
|
f"{base}/contents/generations/tasks",
|
|
1161
1289
|
provider="seedance",
|
|
@@ -1167,6 +1295,14 @@ def _run_seedance(job: Mapping[str, Any]) -> tuple[Path, str]:
|
|
|
1167
1295
|
raise AdapterFailure(
|
|
1168
1296
|
"Seedance did not return a task id", code="missing_task_id"
|
|
1169
1297
|
)
|
|
1298
|
+
# Billed from here on. Record the id before the first poll.
|
|
1299
|
+
_record_handle(job, task_id)
|
|
1300
|
+
return _poll_seedance(job, base=base, token=token, task_id=task_id)
|
|
1301
|
+
|
|
1302
|
+
|
|
1303
|
+
def _poll_seedance(
|
|
1304
|
+
job: Mapping[str, Any], *, base: str, token: str, task_id: str
|
|
1305
|
+
) -> tuple[Path, str]:
|
|
1170
1306
|
try:
|
|
1171
1307
|
interval = float(os.environ.get("SEEDANCE_POLL_INTERVAL", "5"))
|
|
1172
1308
|
deadline = time.monotonic() + float(os.environ.get("SEEDANCE_TIMEOUT_SECONDS", "1800"))
|
|
@@ -1328,8 +1464,50 @@ def _run_minimax(job: Mapping[str, Any]) -> tuple[Path, str | None]:
|
|
|
1328
1464
|
)
|
|
1329
1465
|
|
|
1330
1466
|
|
|
1467
|
+
def _run_minimax_speech(job: Mapping[str, Any]) -> tuple[Path, str | None]:
|
|
1468
|
+
token = _credential("MINIMAX_API_KEY")
|
|
1469
|
+
body = compile_minimax_speech_payload(job)
|
|
1470
|
+
base = _base_url("MINIMAX_BASE_URL", MINIMAX_BASE_URL)
|
|
1471
|
+
result, _ = _request_json(
|
|
1472
|
+
f"{base}/t2a_v2",
|
|
1473
|
+
provider="minimax-speech",
|
|
1474
|
+
body=body,
|
|
1475
|
+
token=token,
|
|
1476
|
+
)
|
|
1477
|
+
base_resp = result.get("base_resp")
|
|
1478
|
+
if not isinstance(base_resp, Mapping) or base_resp.get("status_code") != 0:
|
|
1479
|
+
raise AdapterFailure(
|
|
1480
|
+
"MiniMax speech synthesis failed",
|
|
1481
|
+
code=_provider_code(result) or "generation_failed",
|
|
1482
|
+
request_id=_safe_token(result.get("trace_id")),
|
|
1483
|
+
)
|
|
1484
|
+
data = result.get("data")
|
|
1485
|
+
audio = data.get("audio") if isinstance(data, Mapping) else None
|
|
1486
|
+
if not isinstance(audio, str) or not audio:
|
|
1487
|
+
raise AdapterFailure(
|
|
1488
|
+
"MiniMax did not return audio data",
|
|
1489
|
+
code="missing_audio",
|
|
1490
|
+
request_id=_safe_token(result.get("trace_id")),
|
|
1491
|
+
)
|
|
1492
|
+
try:
|
|
1493
|
+
content = bytes.fromhex(audio)
|
|
1494
|
+
except ValueError as exc:
|
|
1495
|
+
raise AdapterFailure("MiniMax returned invalid audio data") from exc
|
|
1496
|
+
if not content:
|
|
1497
|
+
raise AdapterFailure("MiniMax returned empty audio data")
|
|
1498
|
+
trace_id = result.get("trace_id")
|
|
1499
|
+
return (
|
|
1500
|
+
_temporary_output(job, job["outputs"][0], content),
|
|
1501
|
+
trace_id if isinstance(trace_id, str) else None,
|
|
1502
|
+
)
|
|
1503
|
+
|
|
1504
|
+
|
|
1331
1505
|
def _run_minimax_video(job: Mapping[str, Any]) -> tuple[Path, str]:
|
|
1332
1506
|
token = _credential("MINIMAX_API_KEY")
|
|
1507
|
+
base = _base_url("MINIMAX_VIDEO_BASE_URL", MINIMAX_VIDEO_BASE_URL)
|
|
1508
|
+
collecting = _collect_target(job)
|
|
1509
|
+
if collecting is not None:
|
|
1510
|
+
return _poll_minimax_video(job, base=base, token=token, task_id=collecting)
|
|
1333
1511
|
model = os.environ.get("MINIMAX_VIDEO_MODEL", "")
|
|
1334
1512
|
references = _reference_paths(job)
|
|
1335
1513
|
reference_roles = (
|
|
@@ -1350,7 +1528,6 @@ def _run_minimax_video(job: Mapping[str, Any]) -> tuple[Path, str]:
|
|
|
1350
1528
|
allowed_resolutions=resolutions,
|
|
1351
1529
|
duration_range=duration_range,
|
|
1352
1530
|
)
|
|
1353
|
-
base = _base_url("MINIMAX_VIDEO_BASE_URL", MINIMAX_VIDEO_BASE_URL)
|
|
1354
1531
|
created, _ = _request_json(
|
|
1355
1532
|
f"{base}/video_generation",
|
|
1356
1533
|
provider="minimax-h3",
|
|
@@ -1363,6 +1540,14 @@ def _run_minimax_video(job: Mapping[str, Any]) -> tuple[Path, str]:
|
|
|
1363
1540
|
"MiniMax did not return a task id",
|
|
1364
1541
|
code=_provider_code(created) or "missing_task_id",
|
|
1365
1542
|
)
|
|
1543
|
+
# Billed from here on. Record the id before the first poll.
|
|
1544
|
+
_record_handle(job, task_id)
|
|
1545
|
+
return _poll_minimax_video(job, base=base, token=token, task_id=task_id)
|
|
1546
|
+
|
|
1547
|
+
|
|
1548
|
+
def _poll_minimax_video(
|
|
1549
|
+
job: Mapping[str, Any], *, base: str, token: str, task_id: str
|
|
1550
|
+
) -> tuple[Path, str]:
|
|
1366
1551
|
try:
|
|
1367
1552
|
interval = float(os.environ.get("MINIMAX_VIDEO_POLL_INTERVAL", "5"))
|
|
1368
1553
|
deadline = time.monotonic() + float(
|
|
@@ -1429,8 +1614,15 @@ def _selftest() -> None:
|
|
|
1429
1614
|
"modality": "music", "prompt": "cinematic", "references": [],
|
|
1430
1615
|
"outputs": ["制作成果/a.mp3"], "parameters": {"lyrics": "[Verse]\nHello"},
|
|
1431
1616
|
}
|
|
1617
|
+
speech = {
|
|
1618
|
+
"modality": "tts", "prompt": "你们做了多久?", "references": [],
|
|
1619
|
+
"outputs": ["制作成果/a.mp3"],
|
|
1620
|
+
"parameters": {"model": "configured-speech-model", "voice_id": "a-preset"},
|
|
1621
|
+
}
|
|
1432
1622
|
if compile_gpt_image_2_payload(image)["model"] != OPENAI_MODEL:
|
|
1433
1623
|
raise RuntimeError("GPT Image 2 self-test failed")
|
|
1624
|
+
if compile_minimax_speech_payload(speech)["voice_setting"]["voice_id"] != "a-preset":
|
|
1625
|
+
raise RuntimeError("MiniMax speech self-test failed")
|
|
1434
1626
|
seedance = compile_seedance_payload(
|
|
1435
1627
|
video,
|
|
1436
1628
|
model="configured-model",
|
|
@@ -1498,7 +1690,10 @@ def main() -> int:
|
|
|
1498
1690
|
parser.add_argument(
|
|
1499
1691
|
"provider",
|
|
1500
1692
|
nargs="?",
|
|
1501
|
-
choices=(
|
|
1693
|
+
choices=(
|
|
1694
|
+
"seedance", "gpt-image-2", "minimax-music", "minimax-h3",
|
|
1695
|
+
"minimax-speech",
|
|
1696
|
+
),
|
|
1502
1697
|
)
|
|
1503
1698
|
parser.add_argument("--selftest", action="store_true")
|
|
1504
1699
|
args = parser.parse_args()
|
|
@@ -1516,6 +1711,7 @@ def main() -> int:
|
|
|
1516
1711
|
"gpt-image-2": _run_openai,
|
|
1517
1712
|
"minimax-music": _run_minimax,
|
|
1518
1713
|
"minimax-h3": _run_minimax_video,
|
|
1714
|
+
"minimax-speech": _run_minimax_speech,
|
|
1519
1715
|
}
|
|
1520
1716
|
path, provider_job_id = runners[args.provider](job)
|
|
1521
1717
|
response: dict[str, Any] = {
|
|
@@ -71,6 +71,8 @@ license: MIT
|
|
|
71
71
|
- 剧本对白、动作、声音、画面文字是否都有画面/声音承载;
|
|
72
72
|
- 人物、地点、道具状态和镜头起止是否连续;
|
|
73
73
|
- 提示词是否从准确起点到准确终点;
|
|
74
|
+
- 目标模型画音同轨时,声音内容、时序和发声边界是否与来源一致;无对白镜是否交代底声或静默
|
|
75
|
+
(`VID-22`、`VID-23`,见 [视觉运动审查表](references/rubric-visual-motion.md));
|
|
74
76
|
- 私有输入、凭据、绝对路径或内部流程文字是否泄漏。
|
|
75
77
|
|
|
76
78
|
缺少必要输入时只停止依赖它的判断,其他问题可以继续汇总。
|
|
@@ -71,6 +71,13 @@
|
|
|
71
71
|
- 角色名/资产引用进入台词内文;
|
|
72
72
|
- 音效、环境底噪与对白方向没有来源或相互遮蔽。
|
|
73
73
|
|
|
74
|
+
目标模型画音同轨时(`VID-23`),检查声音内容、时序、发声边界是否符合来源,
|
|
75
|
+
总结是否错误地引入不存在的声音层。无对白镜也应交代需要的底声或静默。
|
|
76
|
+
H3 无非画内配乐时,`non_diegetic_music: N/A` 是有效的空形式。
|
|
77
|
+
|
|
78
|
+
按实际遗漏、矛盾与影响报告问题,不因出现 `No dialogue` 或第二个否定句判错,
|
|
79
|
+
不把 H3 的小样本表现套到所有同轨模型上。相关证据指向同一个问题时合并报告。
|
|
80
|
+
|
|
74
81
|
### 5. 负面补丁淹没动作
|
|
75
82
|
|
|
76
83
|
为防止模型缺陷叠加大量禁令,真正的起点、动作、表演与终点被挤成几句。
|
|
@@ -86,6 +86,16 @@
|
|
|
86
86
|
- Does each media reference state its exact purpose, what may be copied, and what
|
|
87
87
|
must not be copied, rather than treating all visible pixels as authority?
|
|
88
88
|
|
|
89
|
+
For a copyable body (`VID-22`, `VID-23`), check that actions and sound match the
|
|
90
|
+
source and that the timeline accounts for the intended ambience or silence.
|
|
91
|
+
A summary must not introduce a layer absent from the shot. H3's
|
|
92
|
+
`non_diegetic_music: N/A` is a valid empty music layer.
|
|
93
|
+
|
|
94
|
+
Report a concrete contradiction, omission or ambiguity. A negative clause is
|
|
95
|
+
not a defect by itself; do not impose a clause count or assume that negation
|
|
96
|
+
causes the model to generate the excluded content. Keep model-specific
|
|
97
|
+
observations scoped to their tested model and execution path.
|
|
98
|
+
|
|
89
99
|
For a pickup or alternate, ask these separately:
|
|
90
100
|
|
|
91
101
|
- Does the pickup/alternate name its master by visible `MOTION-...` heading?
|
|
@@ -7,7 +7,8 @@ license: MIT
|
|
|
7
7
|
# 短剧分镜与冻结关键帧
|
|
8
8
|
|
|
9
9
|
把剧本和视觉事实转成有镜头职责、空间连续性和可冻结起点的 `剧集/<EP>/分镜.md`。
|
|
10
|
-
每镜使用二级标题 `## SHOT-...`,同镜下用 `### 冻结关键帧提示词`
|
|
10
|
+
每镜使用二级标题 `## SHOT-...`,同镜下用 `### 冻结关键帧提示词` 写起始帧正文;
|
|
11
|
+
需要时另加 `### 收尾关键帧提示词` 写终点正文。
|
|
11
12
|
|
|
12
13
|
## Quick Start
|
|
13
14
|
|
|
@@ -49,8 +50,13 @@ license: MIT
|
|
|
49
50
|
先用已接受集长换成明确时间边界再分镜;例如 60 秒作品的“后半段首次出现”不得早于 30 秒。
|
|
50
51
|
3. 每镜写清唯一职责、来源、时长、景别/机位、起点、唯一主要动作、终点和声音;用
|
|
51
52
|
`起点 → 唯一动作 → 终点` 直接说明人物、双手与持物怎样完成本镜状态转换。三条依据留到第 6 步。
|
|
53
|
+
有对白、VO 或 OS 时,先按原文和人物说话方式估算完整发声时间,再安排不能重叠的动作、停顿与
|
|
54
|
+
末尾反应;把估时依据简写在本镜「声音」里。具体做法见 [对白估时](references/shot-craft.md#对白估时)。
|
|
52
55
|
4. 锁定人物朝向、位置、视线、持物、出入口、屏幕方向和必要状态;上游已有会限制动作空间的持续关系时,把关系投影进本镜起点与终点。
|
|
53
56
|
5. 冻结关键帧只投影镜头起点;删除终点才出现的文字、动作、姿态或道具状态。
|
|
57
|
+
镜头的职责落在收尾那一下时,另写 `### 收尾关键帧提示词` 投影**终点**——同一格画面的
|
|
58
|
+
另一端,规则完全对称:删除起点才有、终点已经不在的东西。它是可选的,写法与取舍见
|
|
59
|
+
[首尾成对](references/shot-craft.md#首尾成对)。
|
|
54
60
|
6. 关键帧成稿后,先从成稿正文读出这一格里需要保持身份、造型或地理的人物、地点和道具,
|
|
55
61
|
再用同一份清单一次填满三条依据:
|
|
56
62
|
|
|
@@ -69,6 +75,10 @@ license: MIT
|
|
|
69
75
|
|
|
70
76
|
- 每镜有唯一职责、明确来源、可见起止状态和合理时长。「来源」以《剧本.md》里真实存在的场景 ID 开头,
|
|
71
77
|
ID 之后可以跟必要短引文,跨场次的镜头用 `、` 连写多条;`creator_markdown_check.py` 会核对每个 ID 都解析得到。
|
|
78
|
+
- 「来源」短引文应对应本镜承担的动作或声音。正文提到画外人物时,可在视觉依据写
|
|
79
|
+
`;画外:<类别>「<名称>」`;这只声明其不在画面,不能代替必要动作的落实。
|
|
80
|
+
需要看见的动作应另有镜头承载,或说明为何省略。
|
|
81
|
+
|
|
72
82
|
- 剧本里的每个场景都要有镜头承载。确实决定不拍某一场时,在《分镜.md》正文开头写一行
|
|
73
83
|
`- 未拍场次:<场景 ID>(理由:……)`,多项用 `;` 连接。SHT-01 一直允许带理由的省略,
|
|
74
84
|
但省略和漏拍在成稿文档里长得一模一样,所以理由要写下来,而不是留在对话里。
|
|
@@ -138,6 +148,7 @@ license: MIT
|
|
|
138
148
|
- 关键场次比较导演方案:[场次视觉计划](references/scene-visual-plan.md)
|
|
139
149
|
- 检查原文是否都有画面承载:[Coverage Audition](references/coverage-audition.md)
|
|
140
150
|
- 多人、群体和复杂空间调度:[调度手册](references/blocking-playbooks.md)
|
|
151
|
+
- 谁被照亮、怎么写才执行得出:[光的设计](references/lighting-craft.md)
|
|
141
152
|
- 冻结瞬间、注意中心和可读性:[关键帧手艺](references/keyframe-craft.md)
|
|
142
153
|
- 漫剧/二维漫画形态的共享画风词汇:[漫剧关键帧词表](references/comic-keyframe-lexicon.md)
|
|
143
154
|
- 剧本事实到关键帧的完整示例:[剧本到关键帧](references/screenplay-to-keyframe-example.md)
|
|
@@ -4,6 +4,10 @@
|
|
|
4
4
|
每次导出都记下配方版本;文本被手改时,先预览恢复、
|
|
5
5
|
采用或合并的结果。
|
|
6
6
|
|
|
7
|
+
**这份模板属于结构化管线**(`keyframes.jsonl` 一路)。creator-first 项目的《分镜.md》骨架
|
|
8
|
+
以 `SKILL.md` 为准:`## SHOT-... · 中文名`,关键帧正文标题是 `### 冻结关键帧提示词`。
|
|
9
|
+
不要把这里的加粗字段名、`KEY-...` 或 `### 可复制通用提示词` 搬进 creator-first 文档。
|
|
10
|
+
|
|
7
11
|
```markdown
|
|
8
12
|
# EP<编号> · 冻结关键帧提示词
|
|
9
13
|
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# 光的设计
|
|
2
|
+
|
|
3
|
+
## 分工
|
|
4
|
+
|
|
5
|
+
- 《视觉设定.md》的地点条目记录光源、窗户位置和已经确定的光线状态。
|
|
6
|
+
- 分镜选择本镜的注意中心,说明哪些脸、动作或证据必须可读。
|
|
7
|
+
- 提示词把这些选择写成可观察的画面结果。
|
|
8
|
+
|
|
9
|
+
开灯、停电和时段变化会改变场景事实,应来自剧本或已接受的视觉设定。
|
|
10
|
+
|
|
11
|
+
## 按镜头职责设计
|
|
12
|
+
|
|
13
|
+
先确定观众需要看清什么,再选择亮暗关系、光比与背景分离程度。
|
|
14
|
+
需要读表情时保留相关面部细节;需要隐藏身份时可以用剪影或遮暗。
|
|
15
|
+
关注点可以靠亮度、色彩、轮廓或局部对比突出,不要求它总是全画面最亮的部分。
|
|
16
|
+
|
|
17
|
+
竖屏按实际构图检查人物与背景是否分得开。近景中的脸部光线、多人纵深中的背景光,
|
|
18
|
+
各自承担不同信息;不要仅按画幅省略环境或默认加轮廓光。
|
|
19
|
+
|
|
20
|
+
## 把光位与画面效果一起写清
|
|
21
|
+
|
|
22
|
+
光位术语后补充它在画面上的结果,并明确左右指画面还是人物自身。例如:
|
|
23
|
+
|
|
24
|
+
> 主光来自画面左侧;画面左侧脸颊较亮,另一侧留柔和阴影,眼睛仍可辨认。
|
|
25
|
+
|
|
26
|
+
仅写「电影感、氛围感强」不足以决定画面。一次图片模型对照中,描述受光结果比只写
|
|
27
|
+
光位更稳定;这可以作为起步写法,不能据此保证其他模型或视频同样执行。
|
|
28
|
+
暗部深度、边缘亮光和背景亮度按本镜需要写,不把例子中的效果全部照搬。
|
|
29
|
+
|
|
30
|
+
## 参考板与跨镜连续性
|
|
31
|
+
|
|
32
|
+
参考板的均匀照明用于看清形制,不自动成为每个镜头的打光方案。
|
|
33
|
+
绑定角色板时说明保留身份与造型;本镜的光仍依据场景事实。
|
|
34
|
+
|
|
35
|
+
同一连续场景维持光源关系与既定色调;视角、取景范围和人物位置变化可以带来正常的
|
|
36
|
+
画面亮度差异。不要要求所有镜头的平均 RGB 相同。
|
|
37
|
+
|
|
38
|
+
生成后对比相邻镜头中可比较的脸、衣物或场景表面。曝光和白平衡的小幅偏差交给剪辑
|
|
39
|
+
校正;光源方向或剧情光态错误回上游修订。测量用于定位差异,是否有问题仍结合画面判断。
|
|
@@ -14,8 +14,12 @@
|
|
|
14
14
|
3. [场面调度与地理](#场面调度与地理)
|
|
15
15
|
4. [景别与摄影机动机](#景别与摄影机动机)
|
|
16
16
|
5. [时长与切镜](#时长与切镜)
|
|
17
|
-
6. [
|
|
18
|
-
7. [
|
|
17
|
+
6. [视觉方向选择](#视觉方向选择-sht-07)
|
|
18
|
+
7. [相连边界](#相连边界-con-01)
|
|
19
|
+
8. [首尾成对](#首尾成对)
|
|
20
|
+
9. [一镜到底还是切开](#一镜到底还是切开)
|
|
21
|
+
10. [常见问题](#常见问题)
|
|
22
|
+
11. [审查问题](#审查问题)
|
|
19
23
|
|
|
20
24
|
## 先落实原文,再追求画面
|
|
21
25
|
|
|
@@ -65,6 +69,14 @@
|
|
|
65
69
|
镜头可以负责建立空间、让观众站到某个人物一边、展示证据、暂缓信息、转移权力、
|
|
66
70
|
表现反应,或让后果无法回避。“中景展示人物说话”不算足够的镜头目的。
|
|
67
71
|
|
|
72
|
+
### 承受者的反应
|
|
73
|
+
|
|
74
|
+
**`SHT-27 · reviewed_invariant`**:打击、否定或翻盘需要观众理解其后果时,
|
|
75
|
+
分镜应安排可读的承受者反应或其他后果载体。
|
|
76
|
+
可以用独立反应镜、双人镜内的调度、清楚的群像反应、声音或物件状态承载。
|
|
77
|
+
现有画面已经清楚就不必补镜;需要保留反应或承受者不在场时,注明叙事安排。
|
|
78
|
+
审查按后果能否被理解判断,不按人数、景别或反应镜数量判断。
|
|
79
|
+
|
|
68
80
|
### 观众可见性 (`SHT-12`)
|
|
69
81
|
|
|
70
82
|
构图同时决定观众此刻能知道什么。每个事实单独写一条观众可见性判断:绑定准确场景 ID,说明
|
|
@@ -124,6 +136,22 @@
|
|
|
124
136
|
要观众读到什么反而没人回答。判断标准始终是必须被读到的信息存在于哪个尺度——证据在
|
|
125
137
|
指节上就给大特写,后果在两人距离上就不该切近。
|
|
126
138
|
|
|
139
|
+
### 竖屏把可用的景别收窄了
|
|
140
|
+
|
|
141
|
+
上面那张表是横平竖直的电影景别谱系。**竖屏不是把它裁窄,是让其中两档变得难用**。
|
|
142
|
+
|
|
143
|
+
机制很简单:远景和全景靠的是**横向铺开的信息**——谁站在谁旁边、队伍有多长、这个人
|
|
144
|
+
离出口有多远。9:16 的横向只有 16:9 的三分之一强,同样的信息铺进去要么挤成一条,
|
|
145
|
+
要么小到读不出。所以竖屏短剧的实际用法以中景、近景、特写为主,远景与全景出现得少。
|
|
146
|
+
|
|
147
|
+
但这**不是禁令,是换一种排法**:竖屏的空间要靠**纵深**而不是横向来交代——前景、中景、
|
|
148
|
+
后景分层,用门框、桌沿、台阶、人的前后遮挡把关系立起来(见
|
|
149
|
+
[竖屏多人调度](blocking-playbooks.md#1-竖屏多人调度))。做到了这一点,竖屏一样能给全景;
|
|
150
|
+
做不到就不要用这一档去承担交代空间的职责,改用一个更近的镜头单独给一次。
|
|
151
|
+
|
|
152
|
+
**竖屏的横向视野窄,观众的视线本来就被逼到画面中央**,这既是小景别好用的原因,
|
|
153
|
+
也是大景别失效的原因——同一件事的两面。
|
|
154
|
+
|
|
127
155
|
只有注意或关系发生变化时才改变景别和角度。场面声音变大,不等于镜头必须从全景一路
|
|
128
156
|
推到大特写。反过来,一旦决定切镜,新镜就要在景别、角度或人物关系里至少改变一项;
|
|
129
157
|
相邻两镜完全同景别、同角度、同关系时,这次切镜没有职责,应当改变收放或并回一镜。
|
|
@@ -156,6 +184,24 @@
|
|
|
156
184
|
在变化处切镜:新信息、新目光、新决定、新空间关系、新威胁、新证据或节奏变化。
|
|
157
185
|
不要只为换角度而重复同一个动作。给反应留下足够时间,让观众读懂后果。
|
|
158
186
|
|
|
187
|
+
### 对白估时
|
|
188
|
+
|
|
189
|
+
**`craft_default`**:先排完整声音事件,再确定镜长。不要先选一个短镜长,再要求人物加快语速把台词塞进去。
|
|
190
|
+
|
|
191
|
+
- 有同一句、同语言、同表演方式的录音或配音时,使用实际发声区间;文件首尾静默与句内停顿分开核对,
|
|
192
|
+
不把整个文件长度当作纯说话时间。没有音频时按原文、人物语速、情绪和换气估一个区间,明确标为
|
|
193
|
+
「文本估计」,不要声称已实测。项目已校准的语速可以辅助估算;数字、缩写按实际读法考虑,不能只数可见字符。
|
|
194
|
+
- 顺序说话的多句或多人对白累加,句间停顿与听者反应按实际顺序加入。边说边抬眼等确能并行的动作
|
|
195
|
+
与对白共用时间;必须等话说完才发生的动作另占时间。不要重复计算已包含在录音或估计里的停顿。
|
|
196
|
+
- 在本镜「声音」中简写依据,例如「对白按克制语气文本估计 8–10 秒(含句内停顿);开口前 0.5 秒,
|
|
197
|
+
说完后的反应 1 秒;抬眼与对白并行」。此例按估计上沿需要 11.5 秒;若目标是 H3,向上取到 12 秒,
|
|
198
|
+
余下 0.5 秒安排在已有终点停留。数字只是此例的预算,不是统一余量或官方语速。
|
|
199
|
+
- 取容得下时间线的合法时长;超过模型上限时按语义和可见状态闭合点拆镜,并检查整集总时长。
|
|
200
|
+
已接受镜长或集长固定且放不下时,说明冲突并提出延长、拆镜或剧本修订;不擅自删词或把正常对白改成快读。
|
|
201
|
+
|
|
202
|
+
文本估计是规划依据,实际生成后还需听完整性、语速和尾音。没有录音、配音或生成结果时,不把估计写成
|
|
203
|
+
秒级准确的声音控制承诺;纯动作镜无需补对白预算。
|
|
204
|
+
|
|
159
205
|
## 视觉方向选择 (`SHT-07`)
|
|
160
206
|
|
|
161
207
|
焦段语言、节奏、固定机位、手持或形式化调度属于 `taste_option`,读取创作者已接受的
|
|
@@ -188,3 +234,33 @@
|
|
|
188
234
|
- 是否绑定了准确的造型、观察视角、道具状态、双手状态和文字政策?
|
|
189
235
|
- 结束边界是否为下一镜提供清楚的开始状态?
|
|
190
236
|
- 删除或合并本镜,会不会丢失故事意义?
|
|
237
|
+
|
|
238
|
+
## 首尾成对
|
|
239
|
+
|
|
240
|
+
终点的可见状态对本镜重要,且目标模型支持尾帧时,可以补写
|
|
241
|
+
`### 收尾关键帧提示词`。它只描述终点,不混入起点或中间动作。
|
|
242
|
+
若起终状态相同,或变化发生在画外,通常无需另做尾帧。
|
|
243
|
+
|
|
244
|
+
Seedance 2.5 的一个镜头对照中,绑定尾帧改善了末帧落位;这不是所有模型和动作的保证。
|
|
245
|
+
生成后仍检查中间动作、节奏和终点,不能只比较最后一帧。
|
|
246
|
+
|
|
247
|
+
当前生产工具从 `分镜.md` 的 `SHOT-...` 只提取「冻结关键帧提示词」,即首帧。
|
|
248
|
+
要在套件内生产尾帧,交图片提示词阶段建立单独的 `IMG-...` 条目,注明来自本 SHOT 的
|
|
249
|
+
终点、保留已确认的视觉依据,再以该条目作为 image job 的来源。不得用首帧选择器提交尾帧正文。
|
|
250
|
+
实际图片生成后按目标方言绑定 `用途:结束帧`。
|
|
251
|
+
|
|
252
|
+
## 一镜到底还是切开
|
|
253
|
+
|
|
254
|
+
先看这场戏需要什么,再考虑生成与修订成本。
|
|
255
|
+
|
|
256
|
+
- 连续等待、沉默、空间调度或完整表演,可考虑一镜到底。
|
|
257
|
+
- 需要选择不同表演、突出反应或精确安排切点,可考虑分开生成再剪。
|
|
258
|
+
- 长段生成一处失败可能需要重出更多素材;分开生成则需要额外处理跨镜一致性。
|
|
259
|
+
|
|
260
|
+
一次 Seedance 2.5 对白场次实测出现过长镜头发声时间过早的问题。
|
|
261
|
+
有严格落点时应检查目标模型的时序能力并试听,不能保证分成镜头就能锁定每句发声时间。
|
|
262
|
+
长镜头也可以在剪辑中截取,是否保留完整时长由叙事决定。
|
|
263
|
+
|
|
264
|
+
多镜容器是在一次生成里安排多个切口;一镜到底则不切镜。
|
|
265
|
+
容器可减少提交次数,但不自动保证跨镜一致性,也仍可在生成后剪辑。
|
|
266
|
+
各镜合并时重新整理参考素材与编号,并核对结果中的实际切点。
|
|
@@ -37,6 +37,8 @@
|
|
|
37
37
|
| SHT-23 | structural_invariant | An omitted reference choice is not consent to text-to-video. After reference discovery, each shot either binds all verified real images as `REF-...`, declares creator-supplied pictures as `PLAN-...` slots that locate an existing `IMG-...` board or `SHOT-...` keyframe, preserves partial bindings while naming the still-missing start/identity/geography/prop images, or records the creator's explicit text-to-video choice. A prompt entry, plausible filename, or text description never counts as a real image, and a `PLAN-...` slot never claims one: it states that the picture is supplied outside the project at generation time, which is why it cannot be sent to production. |
|
|
38
38
|
| SHT-24 | reviewed_invariant | A visual basis describes this frame, not the episode's cast list. Each declared 控制 scope stays within what this frame can carry, and a binding is not carried forward merely because the subject remains in the scene. |
|
|
39
39
|
| SHT-25 | structural_invariant | Every real reference image a shot binds declares one 用途 from the closed set 身份/造型状态/地理/构图/尺度/效果/起始帧/结束帧/风格, so the shot can say which start frame and which identity/geography/prop pictures a downstream job sends. At most one 起始帧 and one 结束帧 per shot, and 结束帧 requires 起始帧. |
|
|
40
|
+
| SHT-26 | structural_invariant | A shot's 来源 is its claim on the screenplay: whatever it quotes, this shot is the one that films it. Every 视觉设定 entry the quote calls by name is therefore either in this shot's 视觉依据 or declared 画外 there. Quoting an action performed by someone the frame never shows takes that action off every list — no other shot claims it and nothing reports it missing, so it simply never gets filmed, and the gap only surfaces when a person watches the finished film. The check matches entry names rather than 画面代称, because a 来源 quote comes from 剧本.md; an entry that opted out with `画面代称:无` stays out of this check too. |
|
|
41
|
+
| SHT-27 | reviewed_invariant | When understanding a beat requires seeing its effect on a character, provide a readable reaction or consequence. A separate shot, staging within a shared shot, sound, or an object may carry it. Judge legibility against the intended reveal; do not require a shot count or exclude group shots by default. |
|
|
40
42
|
|
|
41
43
|
### `CON`
|
|
42
44
|
|
|
@@ -74,19 +74,25 @@ license: MIT
|
|
|
74
74
|
多槽参考与首/尾帧在同一请求内互斥的模型,起始帧也随整组走多槽参考,不拆成两套输入。
|
|
75
75
|
5. 核对本镜时长落在目标模型档案的原生区间内;不在区间内就回到分镜修订,不能写完提示词后留给
|
|
76
76
|
adapter 报错,也不能在正文里暗自改变时长。
|
|
77
|
+
有对白、VO 或 OS 时,同时核对分镜「声音」中的估时依据与实际可用发声窗口;缺少依据就按
|
|
78
|
+
[对白预算](references/performance-action-timing.md#对白预算) 补做判断。秒段加总正确不代表台词说得完。
|
|
77
79
|
6. 写不能动的边框:图生视频以参考帧和视觉设定锁定;文生视频把必要静态事实写入「静态视觉锚点」和可复制正文。
|
|
78
80
|
7. 原样读取分镜的「起点 → 唯一动作 → 终点」,确认人物、双手和持物的状态转换都发生在镜内。
|
|
79
81
|
8. 写“静态锚点 → 起点 → 唯一动作(触发、接触、落点)→ 次级反应 → 运镜 → 声音 → 终点”,
|
|
80
82
|
必要时用秒数分段;下一镜从这个终点继续,不另造镜外转换。
|
|
81
83
|
9. 只在真实参考帧已经说明静态外观时删除重复描述;《视觉设定.md》连续性锁的锁面不在可删之列。
|
|
82
|
-
10.
|
|
84
|
+
10. 把限制动作空间的已确认关系写成贯穿本镜的正向可见状态,只安排关系允许的动作通道;只有分镜明确改变关系时才写变化过程。优先用可见状态说明边界,必要时保留明确的排除条件。
|
|
83
85
|
11. 逐镜读取文字义务。除非剧本或创作者明确要求,正文用本镜已解析的视频提示词语言直接写明任何时刻都不生成非画内字幕、caption 和对白文字叠加,不能只写抽象的“文字层为空”;这条默认与旗帜、标牌、屏幕等画内文字独立。画内 `exact_readable` 逐字写明字符、语言、承载面和位置,不能用全局 `no-text` 覆盖。
|
|
84
86
|
12. 声音同轨时,把允许的发声按来源、说话人、口语语言和顺序写成完整时间线;每句从原文首字到末字,
|
|
85
87
|
且逐字对白在单镜可复制正文中只出现一次。视觉动作段只按时间和说话人引用该声音事件,不再抄一遍
|
|
86
88
|
台词。事件外回到已声明的环境声或静默。Brief、剧本或声音方向已经明确禁止外语前导、语气词、
|
|
87
89
|
额外人声或重复时,把这些**已确认的发声边界**在完整时间线末尾合并写一次;不靠“只包含”让执行端
|
|
88
|
-
|
|
89
|
-
|
|
90
|
+
猜,也不自行扩充新的禁用类别。时间线总结只列本镜实际有的声音层。
|
|
91
|
+
无对白镜写清底声或静默及其覆盖区间;嘴部动作按剧本表演,不默认强制闭嘴。
|
|
92
|
+
非画内配乐按目标方言声明,有需要时明确写空。
|
|
93
|
+
13. 成稿时检查动作、声音和限制条件是否清楚且相容。正面状态有助于表达目标,必要的否定条件
|
|
94
|
+
可以保留;不按否定句数量判错。确认不跨下一镜、不要求互斥动作、不让人物或道具瞬移变形。
|
|
95
|
+
|
|
90
96
|
14. 用户要整集就完成整集,镜头组只是内部批次。
|
|
91
97
|
15. 同一连续时空中相邻正式生成段、且目标档案支持续接时,默认选择“从上一段生成结果续接”;
|
|
92
98
|
一镜一生成只决定每次装一个镜头,不等于各镜独立文生。只有创作者明确要求独立重生成,或上游
|
|
@@ -107,11 +113,12 @@ license: MIT
|
|
|
107
113
|
- 运镜与人物动作不争夺注意力;复杂运镜必须有叙事理由。
|
|
108
114
|
- 声音只写该镜需要的对白、画外音、环境或转场职责,不擅自补歌词。
|
|
109
115
|
- 非画内字幕、caption 和对白文字叠加默认不生成;正文直接声明全镜任何时刻都不生成这些内容,不用抽象工作流术语代替执行指令。只有剧本或创作者明确要求才开启。画内精确文字是独立允许集合,不因关闭字幕而消失,也不让未批准文字混入。
|
|
110
|
-
- 同轨对白/VO/OS
|
|
116
|
+
- 同轨对白/VO/OS 同时写逐字文本、口语语言和发声边界;不添加来源没有的声源或重复限制。
|
|
117
|
+
- 无对白镜同样说明底声或静默;时间线总结与实际声音层一致。H3 无非画内配乐时写 `non_diegetic_music: N/A`。
|
|
111
118
|
- 正文里被引号或 `<d>` 包起来的中文必须逐字来自《剧本.md》,画内标牌文字可来自《视觉设定.md》;
|
|
112
119
|
分镜自己写下的画内文字与声音同样算数。`creator_markdown_check.py` 会核对四字以上的引文(VID-25)。
|
|
113
120
|
台词不在剧本里就回到写作技能改剧本,不在提示词里改。
|
|
114
|
-
-
|
|
121
|
+
- 上游持续关系用贯穿状态和允许动作通道表达,避免重复限制或冲突动作。
|
|
115
122
|
- 本镜命中的连续性锁,锁面原样出现在可复制正文里;颜色、材质、形制这类跨镜不变事实不靠模型记忆。
|
|
116
123
|
- 正文可直接复制,不含占位符、流程说明、文件路径或 QA 结论。
|
|
117
124
|
|
|
@@ -80,6 +80,23 @@ Camera behavior 要回答“观众注意为什么在此刻改变”。常见动
|
|
|
80
80
|
|
|
81
81
|
这里不是同时 lock 和 move。若 transition 改变 shot 已接受的 camera design,仍需 storyboard 同意。
|
|
82
82
|
|
|
83
|
+
### 摄影机与主体的相对运动
|
|
84
|
+
|
|
85
|
+
主体快跑与摄影机缓推可以同时成立,关键是写清两者的相对关系与画面结果。
|
|
86
|
+
需要跟随时说明跟随方向和构图;需要人物离开画面时,保留缓推或固定机位也可以。
|
|
87
|
+
不能为了消除速度差异而改写上游已确定的运镜。
|
|
88
|
+
|
|
89
|
+
### 运动说明
|
|
90
|
+
|
|
91
|
+
按本镜需要说明运动方式、方向、速度或触发时机、终点以及要保持的空间关系。
|
|
92
|
+
与上一节的起点和落点一起核对,不要求每次恰好四项。
|
|
93
|
+
|
|
94
|
+
### 运镜术语属于方言
|
|
95
|
+
|
|
96
|
+
推轨、变焦、摇、甩、升降这些词在不同目标模型里的解析并不一致——有的模型的官方指南
|
|
97
|
+
推荐 `push in` 而完全不收录 `dolly in`。**不要把一个模型上验证过的运镜词表照搬到另一个
|
|
98
|
+
模型的正文里**;术语与写法以目标模型的方言文档为准,方言里没有记载的词按未验证对待。
|
|
99
|
+
|
|
83
100
|
### 非冲突但可能过载
|
|
84
101
|
|
|
85
102
|
pan 同时微调焦点、handheld 带自然呼吸、dolly 配合轻微 tilt 未必矛盾;是否太复杂由 reviewer 结合 purpose 判断,不能靠 camera 动词计数硬挡。
|