Files
Dylan M. TaylorandNetterSilver 2f8f9ad8c9 craft-timeline: exact media time, reports, ALE and CMX 3600 EDL (from FilmCraft) (#911)
* craft-timeline: exact media time, reports, media paths, ALE and CMX 3600 EDL

New crate for editorial timeline interchange (#782), moved from FilmCraft at
4bec22bd:

- time: filmcraft-time whole (Tick, FrameRate, TimeRange, SMPTE timecode,
  feet+frames, typed-timecode parsing) with its tests.
- report: Report / Level / ReportEntry.
- path: file URL and path conversion, relative references joined to a folder.
- rate: timebase+ntsc and floating rates to exact rates, MAX_RATE.
- ale: AleDoc, parse, write, standard heading and columns.
- edl: the parser (events, lines, timecode fields, M2, AUD, comment extensions),
  the frame-rate guess, and the line layout of the writer, on frame counts.
- Format, detect_text, decode_text.

Each format module gives the document as the format writes it. Mapping onto an
application's timeline stays in the application.

* craft-timeline: strip a UTF-8 byte order mark when parsing ALE files

An ALE saved with a BOM was refused as "not an ALE file": the mark made the
first line something other than "Heading".

Ported from storytold/filmcraft#4531.

---------

Co-authored-by: NetterSilver <133535268+Silvertree2010@users.noreply.github.com>
2026-11-11 17:32:53 -05:00
..

craft-timeline

Editorial timeline interchange: the parts every reader and writer of an edit shares, and the text formats that are documents of their own.

Module What
time Exact media time. A Tick is 1/254 016 000 000 s, which divides evenly into every broadcast frame duration and every common audio sample duration; FrameRate is an exact rational; SMPTE timecode (drop and non-drop), feet+frames and typed-timecode parsing are displays of ticks. Every conversion is total: a zero or negative rate gives zero, not a division by zero, and results saturate at the storage limits.
rate Frame-rate conventions of documents: timebase + ntsc, floating rates snapped to exact ones, the highest rate an importer accepts (MAX_RATE).
report Report: what an import or export could not represent exactly, identical messages merged with a count.
path Media references: file:// URLs (localhost, drive letters, UNC hosts, percent-encoding) to and from paths, and relative references joined to a document's folder. Lexical only.
ale Avid Log Exchange: AleDoc (heading, columns, rows), parse, write, the standard heading and columns.
edl CMX 3600 edit decision lists: parse to the list as written (events, their lines and timecode fields, M2, AUD, clip-name, source-file, effect-name and locator comments), write for events the caller built, channel codes, reel names, the frame-rate guess.
crate root Format (EDL, xmeml, FCPXML, OTIO, AAF, OMF), detect_text, decode_text.

No file I/O. Each format module gives the document as the format writes it; mapping it onto an application's timeline (which media a reel is, what a dissolve overlaps) stays in the application. AAF and OMF are in craft-aaf.

Feature serde: Serialize / Deserialize for the time, report and Format types.

Specifications

Written from public descriptions only: SMPTE ST 12-1 (timecode); the CMX 3600 EDL format as documented by its users (event lines, FCM, M2, and the common * FROM CLIP NAME:, * SOURCE FILE:, * LOC: comment extensions); Avid's published description of ALE; RFC 8089 (file URIs).

Origin

Moved from FilmCraft's filmcraft-time (whole) and filmcraft-interchange (ale, the parser and line layout of edl, the path and rate helpers of common, Report, Format).

Hostile input

Parsers are line-oriented over text the caller already holds, so memory is bounded by the input. Timecode fields beyond i64 are refused; audio channels outside 1..=99 are refused and reported; an FPS heading that is not a positive finite rate up to 100 000 is no rate. Tests cover each.