Skip to content

Final Cut Pro clipboard data read/write #26

Open
@orchetect

Description

@orchetect

Related to #22, out of curiosity I poked around at the clipboard content Final Cut Pro uses when copying markers from the application.

It may be possible to add methods to DAWFileKit to read/write FCP clipboard contents.

FCP uses the following UTI type:

extension NSPasteboard.PasteboardType {
    /// Final Cut Pro's pasteboard UTI type. The content is a binary plist.
    static let finalCutPro = Self("com.apple.flexo.proFFPasteboardUTI")
}

The content of the data is a binary plist. Converted to XML, this is what it looks like:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>ffpasteboardcopiedtypes</key>
    <dict>
        <key>pb_anchoredObject</key>
        <dict>
            <key>count</key>
            <integer>1</integer>
        </dict>
    </dict>
    <key>ffpasteboardobject</key>
    <data>
        <!-- base64-encoded data -->
    </data>
    <key>kffmodelobjectIDs</key>
    <array/>
</dict>

The ffpasteboardobject data blob contains a binary plist payload encoded by NSKeyedArchiver.

ffpasteboardobject

The root object is NSDictionary so it should be possible to deserialize the archive into a dictionary. It's not immediately apparent if the dictionary structure is similar to FCP XML.

ffpasteboardobject-root-obj

ffpasteboardobject-root-obj2

It definitely contains the selected markers from Final Cut Pro marker list and their details (start, duration, name).

ffpasteboardobject-marker

However, attempting to directly unarchive the data will produce errors because proprietary FCP classes are included in the archived data.

try NSKeyedUnarchiver.unarchivedObject(
    ofClasses: [NSDictionary.self, NSMutableArray.self],
    from: data
)
Error Domain=NSCocoaErrorDomain Code=4864 "*** -[NSKeyedUnarchiver decodeObjectForKey:]: cannot decode object of class (FFAnchoredCollection) for key (NS.objects) because no class named "FFAnchoredCollection" was found; the class needs to be defined in source code or linked in from a library (ensure the class is part of the correct target).

fcp-classes

I'm not sure if Apple's ProExtension framework (which contains some FCP objects) has these classes. Worth checking out.

This means it may be necessary to manually parse the archived data, or at least selectively unarchive its children instead of attempting to unarchive the entire root dictionary. (It does not seem practical to try to model all known proprietary class types for the unarchiver to use.)

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestfcpxmlFinal Cut Pro FCPXML

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions