Skip to content

1.3.0 — Chapter markers + multi-source timecodes

Choose a tag to compare

@aagedal aagedal released this 23 Apr 14:50
· 146 commits to main since this release

Added

  • Chapter markers across three container families:
    • MP4 / MOV / M4V: QuickTime text-track chapters (tref > chap pointing
      at a text/subt track whose stts-timed UTF-8 samples are the titles —
      written by DaVinci Resolve, Apple Compressor, iTunes, ffmpeg
      -map_chapters), with Nero udta > chpl as the fallback (x264, ffmpeg,
      MP4Box).
    • Matroska / WebM: top-level Chapters master element — every
      EditionEntry + ChapterAtom, honouring EditionFlagHidden and
      ChapterFlagHidden; supports both ChapLanguage and the newer
      ChapLanguageBCP47.
    • New VideoChapter struct (index, optional id, startTime,
      endTime, title, language, computed duration). Exposed via
      VideoMetadata.chapters.
  • Provenance-tagged timecodes: [Timecode] on VideoMetadata —
    every independent clip-level source (tmcdTrack, quicktimeUdta, xmpDM,
    xmpDMAlt, mxfMaterialPackage, mxfFilePackage, sonyNRT) recorded
    separately with optional frame-rate companion. The scalar timecode stays
    in sync with the first recorded value for backward compatibility.
    recordTimecode(value, source:) helper dedupes entries and appends a
    timecode mismatch: … warning when two sources disagree.
  • XMP timecode parsing — XMPData.startTimecode / .altTimecode
    decode xmpDM:startTimeCode / xmpDM:altTimecode, mapping timeFormat
    (24Timecode, 29.97Timecode, 2997DropTimecode, 50Timecode, …) to a
    numeric fps.
  • MXF TimecodeComponent labelling — the first-encountered component is
    tagged .mxfMaterialPackage, subsequent ones .mxfFilePackage (header
    metadata always puts MaterialPackage before SourcePackage).
  • Sony NRT LtcChangeTable — LtcChange@frameCount="0" now feeds a
    .sonyNRT entry in timecodes, accepting both the hex-encoded SMPTE 12M
    LTC word (XDCAM professional bodies) and the already-formatted
    HH:MM:SS:FF string (Alpha consumer bodies).
  • CLI --streams --format json now emits:
    • format.Timecodes — array of { value, source, frameRate } entries.
    • format.ChapterCount / ChapterStartTimes / ChapterEndTimes /
      ChapterDurations / ChapterTitles / ChapterLanguages.
    • Per-chapter rows in the streams array with StreamType="chapter",
      carrying Index, ChapterUID, StartTime, EndTime, Duration,
      Title, Language — mirrors ffprobe's -show_chapters layout.

Changed

  • QuickTime text chapter tracks are no longer reported as subtitles.
    Any track referenced via tref > chap (on any parent track — DaVinci
    writes it on every trak, ffmpeg's mov muxer writes it only on non-video
    traks) is now excluded from VideoMetadata.subtitleStreams, matching
    ffprobe's -select_streams s output exactly. Real user-facing
    subtitles (tx3g, stpp, wvtt, …) are unaffected.
  • Per-stream timecode is only set when the video track explicitly
    cross-references a tmcd track via tref > tmcd — matches ffprobe's
    behaviour of leaving per-stream tags empty for tmcd tracks that are
    only advertised at the clip level (e.g. Atomos Ninja ProRes RAW).

Fixed

  • DaVinci Resolve and ffmpeg-muxed MP4/MOV files no longer inflate the
    subtitle count by including the hidden chapter-text track.

Validation

Verified end-to-end against:

  • DaVinci Resolve MP4 + MOV exports (with 0, 1, and 2 real subtitle
    tracks alongside the chapter text track).
  • ffmpeg-remuxed MP4 with a second SRT-sourced subtitle track and
    chapters preserved via -map_chapters.
  • 90 GB Harry Potter Matroska with 37 chapters (English).