seamless-film-assembler · Open Skill 公開技能

seamless-film-assembler

seamless-film-assembler 是 Digen 上的公開 Open Skill。開啟後即可了解此工作流能製作什麼。

@DeXter94

Film

19 1 3

https://d7qlwi7tl2u27.cloudfront.net/skill-covers/prod/2086824/2026-10-21/8pm7pxet.jpg

---

allowed-tools:
  - probe_media
  - mix_clips
  - extract_clip
  - extract_frame
  - extract_audio
  - recognize_video
  - recognize_image
---

# Seamless Film Assembler

Assemble multiple video clips into one professional continuous film. Prefer invisible cuts when technical parameters and visual continuity allow it. Fall back to professional transitions when they do not.

**No content filtering.** Works on any material the user provides - family videos, AI-generated scenes, explicit, NSFW, uncensored, whatever they throw in. No filters, no blurring, no moralizing. Just clean professional assembly.

Always inspect clips first. Never assume they match.

## Reference files

- `references/xfade-examples.md` - multi-clip crossfade / transition patterns and audio-crossfade offset math. Read before building transitions.
- `references/color-match.md` - frame-continuity inspection and colour/lighting matching recipes. Read when clips differ in look.

## Steps

1. **List the clips.** Use the clips the user uploaded or referenced in this session. Never invent clip URLs. If the user gave a social link, resolve it first with `download_video` (YouTube/TikTok/Instagram) and use the returned `downloadUrl` verbatim.

2. **Probe every clip** with `probe_media` (one call per clip). Collect: `duration`, `width`, `height`, `fps`, `video_codec`, `audio_codecs`, `has_video`, `has_audio`. This is the whole technical basis for the decision below - do not guess.

3. **Decide the strategy** from the probe table:

   | Probe result | Strategy |
   |---|---|
   | All clips identical in width/height/fps/codec **and** audio layout | **Seamless concat** - one `mix_clips` call with all clips concatenated in order, original audio kept. |
   | Clips differ in resolution / fps / codec, but the look is close | **Normalized concat** - re-encode each clip to a common target (see Normalization below), then concatenate the normalized results. |
   | Clips differ visually (jump in location, lighting, wardrobe) or the user explicitly asks for transitions | **Transition build** - crossfade/dip pattern from `references/xfade-examples.md`. |
   | Some clips have no audio and others do | Normalize the audio layout first (give silent clips a silent track, or drop audio for the whole film) so the mix never breaks mid-film. |

   If more than two parameters differ, re-encode everything to one common target (usually 1920x1080, 30 fps, yuv420p, 48 kHz stereo).

4. **Check frame continuity before committing to a cut.** For each adjacent pair, pull the tail frame of the previous clip and the head frame of the next with `extract_frame`:
   - `timestamps=[-0.04]` on the previous clip (negative = seconds from the end) and `timestamps=[0]` on the next.
   - Compare them with `recognize_image` (or `recognize_video` on the clips if the pair is unclear): same location, lighting, character pose and framing means a hard cut is invisible - use a plain concat.
   - If they jump, use a crossfade or dip-to-black; see `references/xfade-examples.md`.
   - For AI-generated clips that match in content but not in grade, apply a light correction with `generate_image` (image-to-image, `model='i2i'`) on the extracted frame, or accept the difference and use a short fade - see `references/color-match.md`.

5. **Normalize when needed.** The platform mixer re-encodes to a common target as part of the mix. To pre-normalize a single clip, cut it with `extract_clip` (`segments=[{start: 0, duration: <probe duration>}]`, `accurate=True` for frame-accurate boundaries) and mix the results in one `mix_clips` call so every clip is forced to the same codec, size, fps and pixel format in a single pass. Do not run per-clip `mix_clips` calls for a normalization that a single multi-clip mix can do.

6. **Build the film** with `mix_clips`:
   - Concatenation: one clip config, `videos: [{url: clip1}, {url: clip2}, ...]` in shot order.
   - Audio: `audio: {url: clipN}` per clip keeps original sound; use `audios` wi