Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Final Cut Pro FCPXML Support #22

Open
19 of 30 tasks
orchetect opened this issue Nov 23, 2023 · 4 comments
Open
19 of 30 tasks

Final Cut Pro FCPXML Support #22

orchetect opened this issue Nov 23, 2023 · 4 comments
Assignees
Labels
enhancement New feature or request fcpxml Final Cut Pro FCPXML

Comments

@orchetect
Copy link
Owner

orchetect commented Nov 23, 2023

Baseline

  • Support for parsing most common FCPXML elements into model objects, primarily with a view to extracting annotations such as markers, keywords, captions, etc.
  • Reasoning on the model:
    • Extracting elements (clips, markers) and calculating their absolute start timecode on the main timeline
    • Filtering and contextual data gathering for extracted events

Parsing and Element Extraction

  • sync-clip roles
  • mc-clip roles
  • analysis-marker
  • Method to parse top-level story elements that are immediate children of fcpxml
  • Detection for elements that are out of their containing clip's timecode bounds
    • write FCPXML utility method to detect if a clip or attribute (marker, caption, etc.) is out of bounds of the clip it's within
    • but also have a method that can recursively check up all the parent breadcrumbs to see if it's occluded from the main timeline
    • add property to ExtractionSettings to allow filtering out elements that are either partially or fully out-of-bounds, and therefore not visible on the main timeline
  • Change absoluteStart to inTime. Add outTime property to context, calculated from inTime + duration.
  • Add logic to convert sub-role names to their base role. ie: convert "Dialogue.Dialog-1" to "Dialogue"
  • Add progress reporting to element extraction (useful for very large FCPXML documents)

Frame Rate Scaling

Frame rate scaling for clips using conform-rate child element.

As support for timeline/media frame rate pairs are added, this table will be updated. (Project rates in the 1st column and media rates in subsequent columns.)

Project rate 23.98 24 25 29.97 29.97d 30 50 59.94 60
23.98 N/A ? X ? ? ? ?
24 X N/A X X
25 N/A
29.97 X ? N/A ? ? ? ?
29.97d X X N/A
30 X X N/A
50 N/A
59.94 X X N/A
60 X X N/A

X = implemented and unit tested
? = should work in theory, being reciprocals of already-tested rate pairs, but have not been explicitly unit tested

Authoring

  • Make all model attributes settable
  • Make all model children mutable / settable
  • Add a mechanism to be able to author elements by supplying their absolute start timecode value
  • API ergonomics and considerations

Refactors

  • Extensively implement throwing methods with propagated error handling
  • Refactor FCPXML to remove resources parameter in inits and force them to parse exclusively from the XML, including parsing out resources when necessary
  • Aggregate accumulation of Timecode can result in subframe aliasing where Final Cut Pro shows timecode for elements (markers, captions, keywords, etc.) 1-2 subframes off
    • may need to store atomically as CMTime or Fraction and convert to Timecode ad-hoc
    • not an issue when times fall on frame boundaries and do not have subframes
  • API adjustments and refactors to enable writing model contents to disk as FCPXML

Technical

  • Add pretty debugDescription output for Any* enum cases, etc.
  • Performance optimization: concurrency for FCPXML file parsing to increase performance
    • Each XML element's child notes could be parsed in parallel to speed up parsing. And that could happen with every element in the hierarchy.
  • Make types Sendable

To Investigate

  • Bundle FCPXML DTDs and validate input FCPXML files?
  • FCPXML note is a child element for clips, but an attribute for annotations
  • Implement predefined formats?
    Not sure if it's possible to sometimes only have the format string and no attributes like frameDuration, in which case we would need to add frame rate info for each one of these to derive it
  • read/write FCP clipboard contents (see Final Cut Pro clipboard data read/write #26)

Testing

  • Audio/video role attribute parsing & storage in structs
  • Edge cases involving new-line characters in notes or other text elements
  • Occlusion where elements with non-0 lanes extend past clip(s) beneath them
@orchetect orchetect added the enhancement New feature or request label Nov 23, 2023
@orchetect orchetect self-assigned this Nov 23, 2023
@orchetect orchetect pinned this issue Nov 23, 2023
@orchetect
Copy link
Owner Author

orchetect commented Nov 23, 2023

A TON of work has been put into this thus far. Like literally weeks, full-time. But this remains very much a living and breathing in-progress effort. It's very close to reaching a point of satisfactory capability, stability, and accuracy. The goal now is to fine tune, work out some bugs, cover edge cases, and add unit testing to further improve its rigidity so it can be production-ready.

Currently, the parsing model is not complete (ie: does not implement 100% of the FCP XML 1.11 DTD). It may in future, but there is no compelling reason other than completeness. There exists a lot of ancillary elements possible in the DTD that are somewhat irrelevant to the main goal of DAWFileKit at present, which is markers extraction and interchange.

Also, the model is primarily designed to be read-only and is not yet capable of writing the model to disk as XML. That is a very possible addition to DAWFileKit in future, but will require a substantial refactor and is not a priority at this time.

DAWFileKit is currently capable of parsing and reasoning on:

  • all resource types (asset, effect, format, locator, media, object-tracker, tracking-shape)
  • all structure elements (library, event, project, sequence, spine)
  • all story elements
    • all clip types (asset, audio, audition, clip, gap, mc-clip, ref-clip, sync-clip, title, video)
    • common annotations (markers, keywords, captions)

It's taken quite some time to start shaping the codebase and API into something more ergonomic and it's so much more effort than just writing an XML parser. FCPXML is a bit heady and labyrinthian, and takes time to get into to really understand and be able to reason on, and there's not a ton of great documentation out there.

Reasoning on the model to achieve things like this was challenging to get right:

  • calculating accurate absolute timecode positions for clips and annotations, including those nested within clips
  • interpolating information such as:
    • what are the effective/inherited audio or video roles for any given element?
    • is a clip or annotation out-of-bounds of its containing clip or or invisible due to the aggregate composite of all nested clips from the main timeline?

Multiple layers and references need to be considered and consulted to compile just one piece of reasoning datum such as these, and there are many ways to get it wrong. That's why it's taken so long to build and unit test.

@orchetect orchetect added the fcpxml Final Cut Pro FCPXML label Nov 25, 2023
@orchetect
Copy link
Owner Author

orchetect commented Dec 10, 2023

After a massive second-pass refactor, I'm getting close to stabilizing the API and getting a robust core feature set done.

  • The model takes the form of lightweight strongly-typed XMLElement wrappers.
  • Careful protocolization and computed properties give read and write access to the XML without having to deal with the XML itself.
  • No stored properties are utilized which allows for very performant XML traversal and data extraction.
  • Advanced filtering methods and element extraction algorithms make it very easy to scrape data from the XML, such as extracting markers.
  • Thorough support for calculating absolute time/timecode values for any element type from the standpoint of any parent container's timeline, including the main top-level timeline of course.
  • Thorough support for extracting roles for elements including default roles and similar interpolations that Final Cut Pro itself makes but does not necessarily encode into the XML.
  • Occlusion information is available for any element, reporting whether it is fully visible within its container, partially visible, or completely out of bounds. This can be calculated for the aggregate of multiple nested containers. This data can be used for filtering as well.
  • Lots more improvements and features
  • Improved scalability and maintainability

The goal is to have this pushed to a new release in the next week or so.

@orchetect
Copy link
Owner Author

The re-refactor is basically complete on fcpxml-refactor branch.

  • Unit tests are passing
  • There are substantial performance improvements for element extraction

There should be a forthcoming merge to main and release soon.

@orchetect
Copy link
Owner Author

Merged PR to main.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request fcpxml Final Cut Pro FCPXML
Projects
None yet
Development

No branches or pull requests

1 participant