Skip to content

v1.0.36

Choose a tag to compare

@github-actions github-actions released this 24 Sep 04:49
· 319 commits to main since this release

Added

  • Transition design between shot groups (docs/transition_design.md, WORKFLOW §9C "过场设计"). Group boundaries become first-class objects: a per-episode design ledger directing/epNN/transition_design.json diagnoses every boundary (scene change / time jump / cast / lighting / narrative-block edge, the screenplay's 转场: line, the director's packaging notes), proposes a design per the project's transition mode and keeps the user's decisions; shot_list.transition_in stays the single final field and is only written back by the host (code/transition_design.py apply). transition_in gains join.style (a controlled xfade style family for dissolves: wipe / blur_through / zoom_through / iris / pixelize / fadegrays), inserts[] (boundary insert segments: title_card, establishing from the scene panorama (yaw sweep) or the master plate (Ken Burns), timelapse between two lighting schemes of the same anchor, bridge for a generated clip; 0.5–4 s each, ≤ 6 s per boundary, per-segment join_out seam and audio policy) and overlay_card (location/time text over the first seconds of the incoming group, no length change). render_transitions.py gains build (renders the segments and overlay PNGs by design+asset fingerprint into edit/epNN/transitions/<B-from-to>/) and preview (boundary preview clip: 2 s + transition + 2 s through the same filter chain as the final cut); inserts ride the existing pad path (inserted at the boundary, film lengthens by the sum, same timemap table for audio/subtitles) and the check gains insert_budget_ok, inserts_built and insert_frames_verified. The storyboard page shows a transition card between every two groups (collapsed to a thin line when nothing changes and it is a hard cut): diagnosis tags, the design chain (previous tail frame → seam → inserts → seam → next head frame), preview, accept / candidates / keep hard cut / edit text / feedback, plus a summary bar with the episode-level mode dropdown and the insert budget. Transition mode lives in the Video Rhythm dialog and the new-project wizard (settings.json#transitions): minimal (status quo), classic (default for new projects; existing projects without the section are minimal), cinematic, custom (the four sub-options — explanatory cards, time budget %, generative transitions, establishing first shot — are only shown for custom; presets derive them). The mode takes precedence over prose statements such as "no title cards" in the director's plan. The post page transition recipe accepts fade_white and a dissolve seam style and keeps inserts accepted on the storyboard page. All 11 language dictionaries updated.

  • Audio mix follows adopted post-production versions (code/mix_basis.py, modules/mix_manifest.py, WORKFLOW §8B ④). p8-mix used to read only the v0 master clips, so cut-outs / slow motion / inserted holds adopted on the Post page could only be applied afterwards by hard-slicing the finished mix along the timemap (BGM jumping at cut points, narration lines cut mid-sentence, music slowed together with slow motion). The mixing agent now takes its per-group sources from mix_basis.py sources (the group's current adopted version, otherwise the master; with measured durations, post-edit start times and the version's time_ops) and stamps assets/audio/final/epNN.mix.json on delivery. post_apply.py check gains mix_basis_current and finalize_episode.py consults the manifest: when it matches the current adopted pointers the post_versions timemap layer is no longer applied to the audio track / subtitles (boundary pads still are); a stale manifest whose mix already carries post-edit timing fails post_ok (H3P refuses to sign) and refuses to assemble until p8-mix is re-run; projects without a manifest keep the previous remap behaviour.

  • Unified upscale settings (genconfig.upscale, Generation Models page → "🔍 Upscale" tab under Digital Human): the upscale provider is now chosen explicitly and no longer follows the video provider. Providers: ffmpeg (built-in non-AI interpolation, default; filter / crf / preset), volcengine (Seedance 2.5 Draft mode: when active, Ark Seedance 2.5 groups generated at 480p are submitted with draft=true and the draft task id is recorded in grpNNN.meta.json#draft_task; upscaling then asks Ark to render the 1080p final from that id — 7-day validity, final resolution must be 1080p), minimax (Regenerate-2K with its own region / API key on the tab, model fixed to Regenerate-2K, applicability conditions listed on the tab), comfyui (SeedVR2-class workflows with their own connection and comfy/scale-* templates; the bundled template was renamed comfy/scale-seedvr2-api.json). There is deliberately no fallback: when the chosen provider fails preflight or errors, the upscale task fails and is reported to the user (selecting ffmpeg is the explicit way to ask for interpolation). genmedia.py upscale routes on this section only, auto-rescales 2K/1080p outputs to the delivery size, and merges an upscale{provider, method, params, source, target…} block into the clip's meta.json.

  • Final resolution 2K option in Output Settings (project settings and the new-project wizard).

  • Host artifact check for upscales (code/check_upscale_artifacts.py): interpolation outputs are judged by round-trip halo / smear / flicker; generative outputs (SeedVR2 / MiniMax / Draft-mode finals) by flicker + downsample-to-source SSIM, so real super-resolution is no longer failed by the halo detector.

  • Publish page (/preview/videos) now lists every group clip with its upscale method tag (interpolated / AI upscale / not upscaled) read from meta.json.

Changed

  • codex / pi engines gain gpt-6-sol and gpt-6-luna. Both appear at the top of the codex model dropdowns (top bar and per-agent model dialog); the pi dropdown keeps listing whatever pi --list-models returns. Smart Assignment for both engines now resolves the high tier to gpt-6-sol and the low tier to gpt-6-luna (codex: was gpt-6-astra / gpt-5.6-terra; pi: was openai-codex/gpt-5.6-sol / openai-codex/gpt-5.6-terra). The tier is resolved at dispatch time, so existing installs on a smart policy pick it up after a restart; the top-bar tooltips and all 11 i18n dictionaries are updated.

  • Post page: groups with new versions pending review are now obvious. The left group list shows a yellow v{n} pending review badge (plus a yellow edge bar) on any group that has a shot-editing / import / insert-hold version newer than its current pointer, a new Pending review filter lists them, and the defect / dispatched dots moved from the second line to the group-id line so they are no longer clipped by the status box. The right column gets a highlighted bar above Shot editing with Compare v{n} (A|B against the current version) and a yellow Set v{n} current button, so adopting a cut no longer requires opening the collapsed Shot editing panel. All 11 language dictionaries updated.

  • Output Settings: "Generate dialogue speech" is mandatory in post-production dubbing mode. In the project Output Settings dialog and the new-project wizard, choosing Post-production dubbing for Dialogue voice ticks Generate dialogue speech and locks it (a note says it is required in this mode); switching back to Native video audio unlocks it. The server normalises the setting on save (output.dialogue_voice=dubbing always stores output.dialogue_tts=true, including API calls and re-saved legacy projects), modules/dialogue_tts.enabled() treats dubbing projects as enabled even before they are re-saved, and the agent role prompt no longer describes a dubbing-without-library branch. All 11 language dictionaries updated.

  • Agents no longer run local speech recognition on their own. Only the transcription workstations (09-audio/audio-transcription, caption speech-align, digital-human dh0-transcribe, mashup alignment) may call faster-whisper / modules/transcription.py; every other agent is denied by the PreToolUse hook (.claude/hooks/orchestrator_guard.py) and by the shared runtime discipline, so a video-generation agent can no longer download Whisper weights just to "verify the dialogue track" after a clip is rendered. Explicit user requests go through the transcription agent (or a host-level VIDEOAGENTS_ALLOW_ASR=1).

  • The upscale agent SOUL and WORKFLOW §7B gain a hard rule: upscaling is only allowed through modules/genmedia.py upscale; agents must not hand-write ffmpeg scaling, bypass the routing, or reuse legacy per-project upscale scripts. The MiniMax Regenerate-2K skill injection was retired (the skill file became agents/08-video-gen/upscale/docs/minimax-regenerate-2k.md); selecting minimax on the Upscale tab is the only switch.

  • Shot timing in video prompts (shot_timing_bound, code/sync_shot_timing.py): each shot's duration_s from shot_list.json is now written into the group video prompt in the effective model's official form. Seedance 2.5 / Wan 3.0 get continuous integer-second segments (0-2秒:, sub-second cuts merged as 8-10秒(Shot 5–Shot 8):; 0-2s: on non-Chinese UIs) on the first shot of each segment; MiniMax H3 gets official cut timestamps At MM:SS.mmm, on Shot 2+; Seedance 2.0 stays untagged per its official guide (stale tags are stripped). The sync is idempotent (--write, original prompt backed up once) and the check enforces presence, continuity, the last segment ending at round(total_duration_s), and Σ duration_s == total_duration_s. Wired into the p7-prompt validation list and the prompt agent's SOUL/runtime contract.

  • Long take › Join method (duration.long_take_mode, shown in the new-project wizard and the Duration Settings dialog only while Long take is on): last_frame (default) chains every same-scene group boundary on the previous group's last-frame screenshot; tail_video chains on the previous group's last 2–3 s of video (.continuation.mp4 in video_refs), falling back to the last frame when the model takes no reference video, the tail is shorter than 2 s or the video budget is full. The choice applies regardless of the continuity plan's boundary_type: previously only a continuous boundary ever produced a tail video, and since continuity-planning marks reverse angles and reframes as cut, most projects never got one. boundary_type now only shapes the opening declaration the host writes into the prompt (continuous: extend forward, no cut at the opening; cut: same location/lighting/positions, then the planned framing) and is recorded as continuity_ref.boundary. Cross-scene boundaries, transitions and anchor: none remain hard breaks. Existing projects default to last_frame; after changing the join method re-run sync_continuity_refs.py --write (--prepare for groups whose predecessor is already rendered). A running instance must be restarted.

Fixed

  • code/render_transitions.py dropped the tail frames the edit step pads onto group clips: the segmented renderer referenced whole group files, so a timeline whose entries are longer than their clips (fengshen3 ep06: 10 groups padded by one frame each to cover the clip's native audio, recorded as tail_pad_frames) produced a cut_v2 10 frames short with the picture running 0.42 s ahead of the audio at the end (hard_cut_positions_intact FAIL, DEF-ep06-edit-0002). Every timeline entry now gets a frame plan (round(duration × fps) frames: taken from the clip from in, the remainder cloned from the last frame); only verbatim whole-file groups are stream-copied, padded or trimmed groups are re-encoded to exactly their planned length, render-run sources are built per input through filter_complex instead of the concat demuxer, and boundary requantisation uses the same frame plan (it previously bailed out on entries carrying timeline_in).

  • modules/timemap.compose mis-composed nested edits: a second-layer edit falling inside a first-layer interval (slow motion then cutting that same span, or partially deleting an inserted hold) was appended as a parallel op whose delta cancelled the first one, so effective_time_ops, build-cut in/out mapping and the legacy audio/subtitle remap were wrong for such version chains (fengshen3 ep06 grp019 composed to Δ0 instead of −0.71 s). Compose now scans source-basis breakpoints and derives each segment's output length through both layers.