Table of Contents

Olive Video Editor: an insight of the OVEXML file format

Olive Video Editor is the most open video editor in the world. From its completely configurable render pipeline to its open source codebase, every aspect of it is designed to provide users with as much control as possible over both their work and their workflow.

The project can be saved as an XML file

A feature that I really apreciated is the ability to save the project file into an XML file (with the .ovexml extension). Being addicted to the GNU/Linux command line and ffmpeg I immediately tried to convert an Olive project into an ffmpeg script.

A walk inside the OVEXML

Here I explain some findings on an OVEXML file created with Olive v.0.2.

Beware that the project I worked on is a really simple one! Only two tracks (one video and one audio), video is always locked with the audio, the clips are just concatenated without transition effects, gaps, etc. Parsing the OVEXML of such a project is feasible, any extra feature could make the job too challenging.

My goal was to print the sequence of clips used into a project, showing for each clip the footage filename, the start frame and the length. The aim is to make a list of unused footages to trash, and perhaps to build a timeline script to make a rendering using ffmpeg on the Linux command line.

The first challenge was to find the link from the top level node of the project (the org.olivevideoeditor.Olive.sequence) down to the lower level nodes org.olivevideoeditor.Olive.footage (e.g. the media files on the computer disk). In this walk I had to figure out how to get the clip starting frame and its length.

The nodes to walk into the XML structure are the following:

Olive.sequenceOlive.trackOlive.transformOlive.footage

On each step we must relay to the <connections> tag of the parent node, to find the ptr attribute of the child, something like:

<node version="1" id="org.olivevideoeditor.Olive.sequence" ptr="140198067417568">
    <connections>
        <connection input="track_in_0" element="0">
            <output>140198067323392</output>
        </connection>
        <connection input="track_in_1" element="0">
            <output>140198067446864</output>
        </connection>
    </connections>

When following an audio track, you have to search for a volume node instead of the transform. Starting frame and length of the clip is into the clip node, something like this:

<node version="1" id="org.olivevideoeditor.Olive.clip" ptr="140198067454352">
    <input id="length_in">
        <primary>
            <standard>
                <track>1001/200</track>
            </standard>
        </primary>
        </input>
        <input id="media_in_in">
            <primary>
                <standard>
                    <track>0/1</track>
                </standard>
            </primary>
        </input>

As you can see the frame numbers are represented as rational numbers. Being my footages shot at 29.97 FPS (i.e. 30000/1001) the math is as follow: 1001 / 200 * 30000 / 1001 = 150 (i.e. 150 frames clip length). Beware to perform always the multiplications before the divisions, so that you surely get a whole number, without approximation.

The most challenging part was to understand how the clips are ordered into the timeline. Unfortunately the <content> nodes into the track are listed rougly in the order they are added to the project, the order does not correspond to the timeline order.

We have instead to look at the <input id="arraymap_in"> tag of the track:

<node version="1" id="org.olivevideoeditor.Olive.track" ptr="139716158571008">
    <input id="arraymap_in">
        <primary>
             <standard>
                 <track>AwAAAAgAAAAFAAAABwAAAAYAAAA=</track>
             </standard>
         </primary>
     </input>

The ASCII string AwAAAAgAAAAFAAAABwAAAAYAAAA= is actually a base64 encoded binary string that you can decode on the command line into a binary file:

echo 'AwAAAAgAAAAFAAAABwAAAAYAAAA='  | base64 -d > arraymap_in

And then open it with an hex editor:

03 00 00 00 │ 08 00 00 00 │ 05 00 00 00 │ 07 00 00 00 │ 06 00 00 00

Hence the timeline sequence of clip elements: #3, #8, #5, #7 and #6 (32 bit unsigned integers, little endian).

Proof of concept program

Here you can find my Python script that I used to parse an Olive Editor project file, the output is the ordered list of all the clips used, with the footage filename, the start frame and the length of the clip (in frames).

olive-ovexml-list-clips-in-project.py