Play: the Journey of a Simple Command Line

When dealing with shots, it’s important to get a continuity check. It means the ability to see those shots together to preview them as a sequence.
It can happen at any time during the whole process, from the layout (to check if a shot’s framing and timing are working well within the sequence) or during the animation (to check if the motion continuity and rhythm work), to the compositing (to check if the colours or effects match between shots).

We could use our favourite video editing software (from Blender VSE to Premiere, Avid, etc.), or dedicated software like DaVinci Resolve or the expensive Nuke Studio. But you might not have a license or you might want something lighter than opening such a big app, looking for the project and loading it. For that, big studios often have their own sequence player or rely on an extensive use of Tweak’s RV, an expensive but powerful video player. Let’s see what we can do with free software.

This article is not technical, it’s about the process to find a solution.

The goal is to create a simple command line, easy to remember and use by artists. But before that, we need two things: locating the videos using a well organised naming convention. And then we need to play them in the right order. Because an editor could have swapped two shots, or deleted some of them, and they don’t need to be played any more.


  • Creating simple commands saves you tons of time in your project
  • Shot order and their timing is crucial information you should learn to handle
  • melt is a video player working on Linux and doing exactly what we needed: a bout à bout or continuity preview of the shots of a given sequence.

Knowing the order

At the studio we work from an Adobe Premiere xml export. But it should work with any editing software capable of exporting such xml (pretty standard). We have one Premiere project per sequence and any time there is a change in the edit, from the animatic up until the end of production, we parse that xml and save useful information.
That information is at least stored in a simple csv text file including: the shot name, the time-in and time-out from the edit timeline and the duration.

For example, AG4_S01_EDIT_20180219.csv (AG4 is the episode, S01 the sequence, and the suffix is the edit date February 19, 2018) contains:

shot start end duration
AG4_S01_P001 1 112 112
AG4_S01_P002 113 354 242
AG4_S01_P004 355 419 65
AG4_S01_P003 420 519 100
AG4_S01_P006 520 539 20

In this case, shot 4 is before shot 3 and there is no shot 5.

Timing information is the base unit of any shot in a project. Keep in mind this is very primordial information to handle in any project: collect, save and use it wisely.

Fetching the previews

Saving assets, like preview movies, with the right name in the right place was already the subject of our article about naming conventions. So you should have a clear convention and rely on it to find files.

In our case, for any movie preview of any shot for any given working version, we save the video in a folder next to that given task. So if there are 10 versions of Blender animation files, we will have 10 movies matching those versions with an informative name such as (that file being version 13 of the Animation department, of shot 4, sequence 3 of the DIL project).

Knowing where to find such files could be enough. But we were lazy, and we made it so that anytime you generate such a movie, another copy is made. That copy goes to a folder called CURRENT in the EDIT folder of the sequence. The file is renamed after the shot without more information, such as, overriding the previous version of the movie.
So the CURRENT folder is always up to date with the latest previews from any department. This is the folder the Adobe Premiere project is using. This saves the hassle of having to update footage links all the time. And the timeline is always up to date. There are downsides, like changing shots lengths, but that does not happen often.
A more efficient way could be with symlinks instead of copies, but it’s a mess in a multi-OS environment (Linux/Windows).

At that point we have a folder containing the last version of any shot for any department. We know where to locate those files and the csv is providing the order. We need something to play them!

Finding a player

I want to have a simple way of playing such files in the right order. I could run a script calling ffmpeg to stick all the movies together when needed. But that would be heavy and long if I were to do it often. I need software capable of reading a playlist of movies, in real time. Tweak RV does that well, but I’ll talk about that specialised solution later and stick with open source for now. The obvious could be trying well-known solutions:

  • VLC: a simple playlist (xspf or m3u) could work. But VLC had some small freezes when going from a media to another. Which is no good when you check animation and need to have a precise transition without any latency.
  • DJV_view: which we like as an image sequence player, but does not support multi-shots, as far as we know.
  • Blender VSE: could work, but the real time playing is having troubles without generating proxies. And it’s overkill regarding the goal of the tool.

At that point I found a little command called melt. “Melt was developed as a test tool for the MLT framework. It can be thought of as a powerful, if somewhat obscure, multitrack command line oriented video editor”. That sounded perfect. Actually there is a lot of fun things to do with melt, but we will focus on just playing one movie after another.

The default melt command is super simple to use: melt [...]

Apart from its weird shortcuts, the player is light, opens quickly, starts to play the videos in the provided order, seamlessly and without noticeable latency, and it’s simple. Perfect!

As for installing it, apt-get install melt will do the job! At least on Debian-based distributions.

Make it easy

Now that we know where the videos are and how to play them, let’s make it easy for users. I created the play command. Play asks you to provide at least the sequence you want to play.

So for example : play 3 will play sequence S03 (we skipped the S0 for speed). The script is executed and checks if sequence 3 exists, it fetches the latest csv file in the EDIT folder, parses it and gets the list of shots. It then prepares a command line, adding the shots in the edit order. Finally, the command is ready, it’s executed and melts opens and loads the movies.

We can now play any sequence of the project, with a simple and short command line. We are already saving a lot of time.

I added more options as the artist required them:

  • play 3 10 11 12 will play shots 10, 11 and 12 from sequence 3
  • play 11 --range 20:35 plays a range between shots 20 and 35 in the edit list of sequence 11
  • play 11 -r :15 for all the shots from the beginning until shot 15
  • play 11 -r 20: to play from shot 20 to the end of the sequence

Such range features are useful on long sequences when you just want to check the shots you are working on.

Here is what it looks like (on unfinished layout previews from Dilili a Paris, by Michel Ocelot; copyright: Nord-Ouest Films, Studio O.), specifying 3 shots which are quickly opened and read as a single sequence:

More options

In some cases, melt is too limited for our usage and you might need another player. Adding optional parameters was the way. As I said we use djv_view but it can read only one shot. Nonetheless, the play command is faster to type than searching for the movie of a shot. Typing play 15 10 -dj will open shot 10 of sequence 15 in djv_view.

At the studio we also have RV licenses. Any command listed above, with the -rv parameters will open the sequence in RV. That was useful with the -compo parameter which loads the compositing output image sequence instead of the compressed movie file. It’s way heavier, of course, but you can check the final output in RV quickly.
play 8 -r :10 -rv -compo will play the composited image sequences from the first shot until shot 10 of sequence 8, in RV.

Going further

We created specific commands based on play, like compare in which you specify a shot, and it lists all available versions from any department. You pick some of them and it creates an RV session with comparing tools (like real time blending modes or sliders).
This is the kind of command we used a lot when delivering the 1300 shots of the feature film Dilili in Paris to check baked scenes against the last animation file, before delivery. Such commands were making faster and easier detections of missing assets or animation issues.
Don’t forget, when you have to do something many times there is often a script to build and make your life easier.

There are many features to improve. For example, fade in/fade out between shots are not handled. It could be something we will consider in the future, maybe creating a workflow around OpenTimelineIO.

Note that such scripts should be project-agnostic. So you can use them all over your productions. In our case the project is still hardcoded within the script. So it’s not working on all our projects at the same time (BAD!). Yet, it would be easy to add a parameter. But we avoided asking the user to specify the project in the play command to gain speed.

A GUI might also be handy. And another super cool feature could be to be able to switch the department while playing. So you can compare the last animations with the animatic or the compositing at any time with simple shortcuts.

Anyway, there are always features to add, we just lack of time and have to choose our priorities. 🙂

To conclude

The code of that script is less interesting than the concept of it. But we saved a python snippet online so you can have a look on github.

So what do we need to keep in mind here? When you have to deal with lots of video sequences, and lots of updates, such commands are pretty easy and cool to create. It helps your team and speeds up everything. You don’t have to look for the shot order, the movie folders, etc. Let the machine do that tedious and boring work. Simple scripts can save a project.

Feel free to comment or contribute to the discussion. Maybe you do know a better solution you would recommend?:)

Show CommentsClose Comments

Leave a comment