Monday, April 12, 2010

automating repetitive tasks by scripting Cinelerra, part II

This is a follow up to my earlier article:
/2010/01/automating-repetitive-tasks-by.html

Saving Time
In this entry, I discuss writing a shell script that automatically adds a second video track to your Cinelerra project. This comes in handy for projects that you do repeatedly. For example, a weekly podcast that uses a standard watermark.

For instance, I produce a monthly podcast for my band. You can see the pig watermark in the screen cap below:


In Cinelerra, the pig watermark is created by adding a second video track to my base Cinelerra project. This second video track includes a jpg stretched to the length of the first video track. Also, there is a chroma key effect applied to the pig track in order for it to be transparent against the background of the jam video.

The two items, a graphic of a pig and a video track with the image of the pig and applied effects are represented by XML in the Cinelerra EDL. Remember, the Cinelerra EDL (edit decision list) is the XML file that represents all the edits that you've performed in creating your video masterpiece. It looks like this:


In this blog post, I will show you a shell script that inserts these two chunks of XML into a basic Cinelerra project file. For my script to work properly, note that the base project needs at least one video track and at least one label. I'll get into the reason for that later. The basic project file can also have audio tracks as well.

The Asset, the Asset EDL and the Video Track EDL
One asset and two sections of XML represent the video track of the pig:
1) Here is the graphic of the pig, as a Google Doc.

2) Here is the EDL of the asset (pig2.jpg):

The EDL is also available in a Google Doc.

3) Here is the EDL of the video track of the pig:

The full EDL is also available as a Google Doc.

Since I use the pig watermark on each podcast, I reuse the two chunks of XML above for each installment of my monthly podcast. So I've saved both the asset and the video track XML above from an older project to separate files (pigAsset.txt and pigVideoTrack.txt). Using the shell script, I will insert both of these files at the appropriate places in my base Cinelerra project (my latest podcast). To make life simple, my base project has only one track, the video track of the band rehearsal.

Disclaimer
You're probably saying that this seems like a lot of work and you maybe getting confused. Well..it kind of is a pain in the ass, but it will be worth it when you can whip out a shell script and automatically add your watermark to your project! But I digress..

Shell Script Fun
Here is the meat of the script:
PWD=/mnt/scripts/scriptsTimeline/addPig
ASSET=$PWD/pigAsset.txt
TRACK=$PWD/pigVideoTrack.txt
OLDLENGTH=85965
NEWLENGTH=$(videoLength.sh $INPUT)

echo "OLDLENGTH is $OLDLENGTH"
echo "NEWLENGTH is $NEWLENGTH"
echo "INPUT is $INPUT"
echo "OUTPUT is $OUTPUT"

# adds both via a pipe WORKING
sed -e "s/^<\/ASSETS>/<\!-- $REM -->/g" $INPUT | sed -e "/<\!-- $REM -->/r $ASSET" | sed -e "/LABEL TIME/,/^<\/LABELS/{ /<\/LABELS>/r $TRACK
}" | sed -e "s/$OLDLENGTH/$NEWLENGTH/g" > $OUTPUT

The full script is here, again as a Google Doc.

The core of the script revolves around a neat bit of sed (stream editor) trickery that I mentioned in my first scripting article. In this case, the core function of the script does something similar, but still hinges upon the appearance of labels in the EDL ("LABEL TIME") as a positional reference within the EDL to perform the insertion:
sed -e "s/^<\/ASSETS>/<\!-- $REM -->/g" $INPUT | sed -e "/<\!-- $REM -->/r $ASSET" | sed -e "/LABEL TIME/,/^<\/LABELS/{ /<\/LABELS>/r $TRACK
}" | sed -e "s/$OLDLENGTH/$NEWLENGTH/g"


If we break this command apart, we see that it does a few things:
1) it adds the pig as an asset (the $ASSET constant in the second sed command) to a project (the $INPUT constant listed in the first sed command)
sed -e "s/^<\/ASSETS>/<\!-- $REM -->/g" $INPUT | sed -e "/<\!-- $REM -->/r $ASSET" 

2) it adds a video track of said pig (the $TRACK constant) with this part of the command
| sed -e "/LABEL TIME/,/^<\/LABELS/{ /<\/LABELS>/r $TRACK

3) to make the new track the same length as the new track, it calculates the length of the base track and then substitutes that value for the initial length of the pig track.
| sed -e "s/$OLDLENGTH/$NEWLENGTH/g"

Now, I threw a curveball in there with that NEWLENGTH constant. This number is the current length of the video track in your input file and it is calculated via a second, slightly shorter script called "videoLength.sh".

Here is the Google Doc of that script.

Putting It All Together
To test how the script adds a track, download the following components to the same directory:
1) the jpg of the pig, save as pig2.jpg
2) the xml representing the pig, save as pigAsset.txt
3) the xml representing a new video track with effects, save as pigVideoTrack.txt
4) a test Cinelerra project, save as testProject.xml
5) the script, save as addPig.sh
6) the videoLength shell script

Don't forget to make both scripts executable:
chmod a+x addPig.sh
chmod a+x videoLength.sh, save as videoLength.sh

Script usage:
./addPig.sh [inputEDLfile] [outputEDLfile]

ex.
./addPig.sh testProject.xml trackAdded.xml

You may want to load testProject.xml into Cinelerra first to see that it only has one track. The script will create a new EDL file once it is run. Once you run the script, load your output EDL into Cinelerra. You should see the new track with the associated effects. The track should be the same length as testProject's video track.

Most likely, though, you won't see the pig, just because the pig is not in the same asset directory as the EDL specifies. Simply change pigAsset.txt to reference the pig into the proper directory, rerun the script and all should be good!

Summary
These scripts definitely can be improved upon, especially by someone who has better tools than sed to manipulate XML. But it was fun to automate a mundane task in Cinelerra. Now I don't have to manually add that watermark to my project anymore and neither do you!

the mule