Command-line for Editors, Part 4: Extracting the first-frame timecode value from a video file

When you write scripts that process video files, you’ll often need to perform operations based on the starting timecode of each video file. Being able to automatically parse these timecode values from a script is super useful, and thankfully there are many ways to do this using command-line tools.

Here’s a grab-bag of various methods that I’ve used over the years to accomplish this.

Using MediaInfo

MediaInfo is an absolutely essential tool if you’re using the command-line to work with media files. There’s also a graphical user interface version, which can be used by mere mortals who don’t want to get their hands dirty in the command line (although I much prefer using the Invisor app on macOS, which uses the MediaInfo engine, and let’s you quickly see the differences between metadata fields across multiple files at once).

This command extracts the first-frame timecode from SOURCECLIP.MOV:

mediainfo --Inform="Other;%TimeCode_FirstFrame%" /path/to/SOURCECLIP.MOV

TIP: On macOS and Linux, you can drag a file from the Finder or file manager GUI, and drop it directly onto the Terminal window to have it automatically fill in the fully-qualified path to that file. This saves you from having to manually type in the path yourself.

Using ffprobe

ffprobe is a utility included in the standard installation of the amazing (and free) ffmpeg media processing tool, and it’s extremely useful for parsing metadata out of media files. The command syntax is a little more complex than MediaInfo, but you can get really granular with the parsing rules.

ffprobe -v error -select_streams v:0 -show_entries  format_tags=timecode:stream_tags=timecode -of default=noprint_wrappers=1:nokey=1 /path/to/SOURCECLIP.MOV

Using Apple Compressor

Not many people know that Apple’s Compressor app also has a command-line interface (CLI) that you can use to submit Compressor jobs via a Terminal script. To get the starting timecode of SOURCEFILE.mov, you can run the following command:

/Applications/Compressor.app/Contents/MacOS/Compressor -checkstream /path/to/SOURCEFILE.mov 2>&1 | grep "start-time" | cut -d',' -f3 | awk '{print $2}’

By itself, the Compressor CLI (using the -checkstream option) dumps out metadata that looks like this:

Mel@localhost:~$ /Applications/Compressor.app/Contents/MacOS/Compressor -checkstream /Users/Mel/Downloads/SOURCEFILE.mov    

High level stream analysis:file:///Users/Mel/Downloads/SOURCEFILE.mov
Frame rate: 23.976024, duration :00:01:00:02, start-time: 00:59:55:00
Encoded bounds: 1920 x 1080
Pixel aspect: 1.000000, Will display at bounds: 1920 x 1080, displayAspect: 1.777778
Audio description: Linear PCM, 24 bit little-endian signed integer, 2 channels, 48000 Hz
Stereo (L R)

That’s a lot of unnecessary data, so to isolate the “start-time” timecode value, we send Compressor’s CLI output to three other standard Unix commands, grep, cut and awk. We use pipes (the | symbols) to pass the output of one command to the input of another command, like a virtual assembly line.

The grep command is used to display only the lines that contains the specified search string (technically a “regular expression” match). This whittles the output down to a single line of data, which is much more manageable to work with:

Mel@localhost:~$ /Applications/Compressor.app/Contents/MacOS/Compressor -checkstream /Users/Mel/Downloads/SOURCEFILE.mov 2>&1 | grep "start-time" 

Frame rate: 23.976024, duration :00:01:00:02, start-time: 00:59:55:00

That weird looking 2>&1 part is a redirection symbol, which is a method of separating—or combining—the error messages from a command from its actual output (known as STDERR and STDOUT, respectively).

We then pass the output of grep to the input of the cut command. Looking at the data, notice that the “Frame rate”, “duration” and “start-time” data are separated by commas. We can use this pattern to focus in on the data in the start-time field.

Mel@localhost:~$ /Applications/Compressor.app/Contents/MacOS/Compressor -checkstream /Users/Mel/Downloads/SOURCEFILE.mov 2>&1 | grep "start-time" | cut -d',' -f3 

 start-time: 00:59:55:00

The -d',' flag instructs the cut command to separate the input data based on a delimiter, in this case commas. The -f3 flag further extracts the separated data based on the 3rd “field” of comma-separated data, which whittles down the data even further.

Finally, we send the output of the cut command to another command called awk, which is a great tool for parsing data based on patterns in text files or data streams.

The awk command takes a line of the input data and similarly to the cut -f syntax, splits the line into fields based on a delimiter. By default, awk uses whitespace as the delimiter, and stores each split field into sequentially numbered variables ($1, $2, $3, etc).

So in this case, the awk '{print $2}' command outputs the second field of the whitespace delimited line, which results in the output of the timecode value by itself (If we used $1 instead, it would output the string start-time:):

Mel@localhost:~$ /Applications/Compressor.app/Contents/MacOS/Compressor -checkstream /Users/Mel/Downloads/SOURCEFILE.mov 2>&1 | grep "start-time" | cut -d',' -f3 | awk '{print $2}'

00:59:55:00

The use of multiple different Unix tools within the same processing chain is one of the hallmarks of the Unix philosophy. Each tool does one thing, and one thing well. You can pass data between those tools using pipes to accomplish very sophisticated tasks!

Using REDLine (for R3D files only)

You can extract the timecode value of RED .r3d files using the REDLine command-line tool, which is installed as part of the free REDCINE-X PRO app.

redline -i SOURCEFILE.r3d —printMeta 1 | grep -i TC

This outputs the start and end timecode values of both the Edgecode and Time of Day timecode tracks

Abs TC:	16:00:57:11
Edge TC:	01:03:40:14
End Abs TC:	16:01:04:07
End Edge TC:	01:03:47:10

Using MPlayer

MPlayer is a free, cross-platform, open source video player that can also be controlled via the command line.

This command tells the Player CLI to just dump the metadata for source file without actually playing it, then uses grep and cut to filter out the actual timecode value, similar to the Apple Compressor example.

2>/dev/null is another Bash redirection symbol that outputs any error messages from the player command to /dev/null, which is a virtual “device” on Unix based systems that acts like a one-way black hole for anything that is written to it. It’s commonly used to discard unwanted output from commands, so they don’t pollute your screen or data processing pipelines in your scripts.

mplayer -vo null -ao null -frames 0 -identify /path/to/SOURCEFILE.mov  2>/dev/null | grep ID_CLIP_INFO_VALUE4 | cut -d'=' -f2