mirror of
https://github.com/storytold/craft-libs.git
synced 2026-11-13 18:54:45 +00:00
* craft-media: write and read MP4/MOV chapter lists
WriterOptions::chapters (Chapter { start, title }, starts in the movie
timescale) makes Mp4Writer write a chapter list in the two forms players
read:
- a QuickTime chapter track (a disabled text track referenced by
tref/chap from the first video or audio track, one UTF-8 sample with an
encd atom per chapter) for QuickTime / AVFoundation, and
- a Nero udta/chpl list (version 1, 100 ns units) for VLC and
ffprobe -show_chapters.
Chapters are normalized (sorted, one per start, inside the movie, at most
255 chapters with 255-byte titles cut at a character boundary, control
characters replaced) and a late first chapter is placed with an empty
edit. FragmentedWriter writes chpl only. The demuxer reads both forms
back: Mp4File::chpl_chapters and Mp4File::read_chapters(src).
Ported from FilmCraft's own isobmff crate (storytold/filmcraft#2821, for
storytold/filmcraft#2747), now that FilmCraft uses craft-media.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* craft-media: read chapters only from enabled tracks, inside the edit, with bounded titles
read_chapters took a tref/chap from any track, though QuickTime requires the referencing track to be
enabled. It ignored the chapter track's edit list, so a chapter before the edit start became a second
chapter at zero and samples past its end were returned. It kept titles of any length.
Now a disabled host is skipped; chapters outside the first non-empty edit are dropped, and one spanning
its start begins there; each sample read is capped at 4098 bytes and titles are cut to
MAX_CHAPTER_TITLE_BYTES, which bounds what is kept. Later edits are still ignored.
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* craft-media: a chapter title longer than the sample read keeps its start
A sample declaring more title than the 4096 bytes read parsed to nothing, so the
chapter lost its whole title rather than being cut to MAX_CHAPTER_TITLE_BYTES.
A sample cut by the read now decodes what it holds; one read whole but declaring
more than it has is still no title.
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>