Using FFmpeg with Docker

Docker containers: the easiest way to distribute softwares

What is interesting with Docker containers is that you can use them not only for deploying services to the cloud, but also to distribute softwares that you just need to run locally. It is especially useful when the software has a lot of dependencies and requires to be compiled like FFmpeg. With Docker containers, everything is inside and with just one command line, it just works!


FFmpeg dockerized

FFmpeg is a free software project and is the leading software for everything related to multimedia like video encoding, streaming and muxing.

The problem with FFmpeg is that it is not easy to install. You have to compile it which implies that you need to install a ton of dependencies and have a development environment setup! I’ve been doing this for a decade and it’s not that simple.

A typical FFmpeg image on Docker Hub is +350MB and I wanted it to be as small as possible. So I choose Alpine Linux which is a lightweight Linux distribution, and I ended up with an image of 106MB only. 70% smaller, not bad!

Here is the FFmpeg build configuration used in this image:

ffmpeg version 3.0 Copyright (c) 2000-2016 the FFmpeg developers
built with gcc 5.3.0 (Alpine 5.3.0)
configuration: --enable-version3 --enable-gpl --enable-nonfree --enable-small --enable-libmp3lame --enable-libx264 --enable-libx265 --enable-libvpx --enable-libtheora --enable-libvorbis --enable-libopus --enable-libass --enable-libwebp --enable-librtmp --enable-postproc --enable-avresample --enable-libfreetype --enable-openssl --disable-debug
libavutil 55. 17.103 / 55. 17.103
libavcodec 57. 24.102 / 57. 24.102
libavformat 57. 25.100 / 57. 25.100
libavdevice 57. 0.101 / 57. 0.101
libavfilter 6. 31.100 / 6. 31.100
libavresample 3. 0. 0 / 3. 0. 0
libswscale 4. 0.100 / 4. 0.100
libswresample 2. 0.101 / 2. 0.101
libpostproc 54. 0.100 / 54. 0.100

configuration:
--enable-version3
--enable-gpl
--enable-nonfree
--enable-small
--enable-libmp3lame
--enable-libx264
--enable-libx265
--enable-libvpx
--enable-libtheora
--enable-libvorbis
--enable-libopus
--enable-libass
--enable-libwebp
--enable-librtmp
--enable-postproc
--enable-avresample
--enable-libfreetype
--enable-openssl
--disable-debug

How to use FFmpeg with Docker

If you don’t have Docker installed yet, follow this guide.

Once Docker is properly setup, it is pretty straightforward to use the FFmpeg image. Instead of using the ffmpeg command line, you call docker to run the opencoconut/ffmpeg image in a container. That’s it!

$ docker run opencoconut/ffmpeg -i http://files.coconut.co.s3.amazonaws.com/test.mp4 -f webm -c:v libvpx -c:a libvorbis - > test.webm
It’s simple as that!

You should be aware of 2 caveats by using FFmpeg from a container:

  1. The input file must be publicly available on a web server since the container doesn’t have access to the local file system.
  2. The FFmpeg command must pipe the result to STDOUT, again for the same reason of not accessing the local file system.

The #2 is a big issue, because there are some technical limitations depending on the format you want to use. For instance, MP4, which is the most popular video format out there, can’t be used with a pipe as output. You will get this message if you try:

[mp4 @ 0x556c59f21260] muxer does not support non seekable output

To work around this problem, we can use the current path on the Docker host’s filesystem (your computer) as a volume inside the container with the “-v” option. So now we can access files on our local disk for input / output and use FFmpeg without these limitations.

$ docker run -v=`pwd`:/tmp/ffmpeg opencoconut/ffmpeg -i localfile.mp4 out.webm

This command is too long, so let’s create an alias by adding this line at the end of your ~/.bashrc or ~/.zshrc file:

alias ffmpeg='docker run -v=`pwd`:/tmp/ffmpeg opencoconut/ffmpeg'

Now FFmpeg can be used like it’s installed on your computer:

$ ffmpeg -i
ffmpeg version 3.0 Copyright (c) 2000-2016 the FFmpeg developers
built with gcc 5.3.0 (Alpine 5.3.0)
configuration: --enable-version3 --enable-gpl --enable-nonfree --enable-small --enable-libmp3lame --enable-libx264 --enable-libx265 --enable-libvpx --enable-libtheora --enable-libvorbis --enable-libopus --enable-libass --enable-libwebp --enable-librtmp --enable-postproc --enable-avresample --enable-libfreetype --enable-openssl --disable-debug
libavutil 55. 17.103 / 55. 17.103
libavcodec 57. 24.102 / 57. 24.102
libavformat 57. 25.100 / 57. 25.100
libavdevice 57. 0.101 / 57. 0.101
libavfilter 6. 31.100 / 6. 31.100
libavresample 3. 0. 0 / 3. 0. 0
libswscale 4. 0.100 / 4. 0.100
libswresample 2. 0.101 / 2. 0.101
libpostproc 54. 0.100 / 54. 0.100
Missing argument for option 'i'.
Error splitting the argument list: Invalid argument

Docker image versioning

The FFmpeg team releases a new version every 3 months on average and I wanted this Docker image to follow their version numbering scheme for sake of simplicity.

At this time, we only have two versions: 3.0 and git. The version 3.0 is the latest stable version and was released on February 15th, 2016. When using git, you will use the development version which is working fine 99% of the time.

By using docker run opencoconut/ffmpeg, you will use the latest stable version by default. To use a specific FFmpeg version, just run it like this:

$ docker run opencoconut/ffmpeg:3.0

You can find all versions on the Docker Hub tag page.


If you have any feedbacks, you can send me a message on Twitter or by email. The project is on Github, so feel free to contribute!