dffmpeg
is a dockerized version of ffmpeg
. With dffmpeg
, any system that supports docker can have a fully functioning version of ffmpeg
without having to install any dependencies (besides docker).
dffmpeg
can be considered fully portable as the steps to have a working ffmpeg
will be exactly the same across all of your systems.- No dependencies installed on the host system
- Drop-in replacement for a locally-installed
ffmpeg
binary (for file-level commands) - Limited to no overhead executing
ffmpeg
within a docker container - Portability across all hosts: if docker can run on your system, you can have full
ffmpeg
support - No compiling/gathering dependencies: as a turnkey solution, all you have to do is run the initial setup script to have access to
ffmpeg
Once installed via the steps below, dffmpeg
is called exactly the same as ffmpeg
:
$ dffmpeg -i input.mp4 -vcodec libx264 output.mp4
$ dffmpeg -i /path/to/input.mkv -vcodec libx264 -acodec libfdk_aac /path/to/output.mkv
dffmpeg
consists of two parts:
- A docker image that has
ffmpeg
configured as its entrypoint - A bash executable to format
ffmpeg
commands to be run via docker
ffmpeg
, ffmpeg
is installed inside of a docker image and the image's entrypoint is configured to be the installed ffmpeg
binary.- An alpine linux docker image and its ffmpeg package
- An Arch Linux docker image and the Arch User Repository ("AUR") package ffmpeg-libfdk_aac
dffmpeg
provides dffmpeg.sh to be used as a drop-in replacement for ffmpeg. dffmpeg.sh is called in exactly the same manner as ffmpeg, but instead of a local ffmpeg binary (with all of its installed dependencies), dffmpeg executes ffmpeg from within a docker container.ffmpeg
as its entrypoint can be used by dffmpeg.sh
(to do so, simply change the dffmpeg_image_name
variable within dffmpeg.sh
from alpine-ffmpeg
to the name of the desired replacement image.Installing dffmpeg
consists of two main steps:
- Building a docker image that has
ffmpeg
as its entrypoint; and - Saving
dffmpeg.sh
to a path accessible by your system's$PATH
# Download dffmpeg.sh and the Dockerfile to build the default Arch Linux image implementation
git clone https://github.com/srwareham/dffmpeg.git
cd dffmpeg
# Build the default alpine linux image with the tag "alpine-ffmpeg"
./build.sh
# Copy dffmpeg.sh to a location that *should* be in the default $PATH setup for most systems
# (Also removes the file extension following unix executable naming conventions)
cp dffmpeg.sh /usr/local/bin/dffmpeg
Note: the ./build.sh
step may take awhile depending on the underlying image you choose. Images requiring large downloads and compilations may take a significant amount of time.
git clone https://github.com/srwareham/dffmpeg.git && cd dffmpeg && ./build.sh && cp dffmpeg.sh /usr/local/bin/dffmpeg
# Download dffmpeg.sh and the Dockerfile to build the default Arch Linux image implementation
git clone https://github.com/srwareham/dffmpeg.git
cd dffmpeg
# Modify the default image name from "alpine-ffmpeg" to that of your choosing (e.g., "arch-ffmpeg")
nano build.sh
<replace "image_name=alpine-ffmpeg" with "image_name=arch-ffmpeg" for example>
# Build the desired image with the tag specified above
./build.sh
# Copy dffmpeg.sh to a location that *should* be in the default $PATH setup for most systems
# (Also removes the file extension following unix executable naming conventions)
cp dffmpeg.sh /usr/local/bin/dffmpeg
To specify an ffmpeg
image of your own design, simply create a new subdirectory within "images." Inside, you will need to create a Dockerfile that has ffmpeg
configured as its entrypoint and a build.sh that builds the image with a name of your choosing.
Note:
- The name of your new image must be the same as the directory that contains it
- build.sh will be executed from within the directory that contains it (i.e., build.sh can take the form
docker build -t $image_name .
dffmpeg
currently only supports commands that actually process files from the local system. The script parses commands to determine which host directories need to be mounted to the guest container for input/output. As a result, two main types of commands are not supported
- Simple commands that do not perform any audio/video manipulations (e.g.,
ffmpeg -encoders
) - Complex commands that use redirection to perform audio/video manipulations (e.g., commands outside of the form:
ffmpeg ___ -i $path_to_file ___ $path_to_output
I personally have no use for 1, as it is fairly easy to simply enter the relevant ffmpeg
container via docker run --rm -it --entrypoint=/bin/sh $image_name
and then manually run any ffmpeg
containers from within. If interest exists in adding this feature, I would be happy to accept any pull requests or to otherwise implement some trivial edge cases into the existing script
ffmpeg
binary, I would be happy to look into the feasibility of porting such behavior to ffmpeg
. From my understanding of docker, it is possible to redirect stdin and stdout, so I would assume such features are possible.Due to the licensing on many popular libraries that can be used by ffmpeg, any version of ffmpeg
you install will require you to choose between install speed, install size, and feature set. In practice, you can choose ffmpeg
:
- Made quickly with some feature limitations and a relatively small install size; or
- Made slowly for:
- Expanded features
- Minimum install size.
In my experience, the two provided images should cover ~99% of use cases:
alpine-ffmpeg
for use case 1; andarch-ffmpeg
for use case 2.a.
For use case 1, the provided alpine implementation should be a more or less optimal approach.
arch-ffmpeg
implementation is not optimized for size and doesn't include every ffmpeg
feature. If space is not a concern, it would be relatively straightforward to replace included ffmpeg-libfdk_aac with ffmpeg-full-git and have every ffmpeg
feature. This was not originally chosen for the provided implementation because it requires much more compilation time, uses significantly more space, and is frequently broken by updates. If anyone would like to commit to maintaining such an implementation, I would be happy to host it here. It would also be fairly trivial to simply delete many unneeded files from the provided arch-ffmpeg
, I will probably do so eventually.ffmpeg
with all desired features, delete the compilation precursors, and simply keep the statically compiled binary. Having done this a few times, this process is extremely involved, involves lots of compilation time, requires more configuration than one might expect, and generally requires significant maintenance over time (source code structures, hosting providers, and configuration options frequently change). Although labor intensive, this process suits itself rather nicely to a dockerized solution: you can use a docker container to statically compile ffmpeg
, store the output binary in a docker volume, and then use a new container referencing this volume to execute any ffmpeg
tasks (and delete the compilation container). If you are interested in a starting point for such a solution, checkout my very similar project docker-ffmpeg-compiler.The default ffmpeg
container for this repository is uses the lightweight alpine linux distribution and its ffmpeg package.
~50MB
- Only ~50MB
- Very quick build time as no compilation is necessary
- Most popular codecs are included (see Cons)
- libfdk_aac not provided (libfdk_aac's license prevents it from being distributed in binary format. For libfdk_aac to be included, libfdk_aac would have to be manually compiled and then ffmpeg would have to be built with
--enable-libfdk-aac
configured
- libx264
- libx265
- libvpx
- libvpx-vp9
- libtheora
- aac
- libopus
- libvorbis
- libmp3lame
- flac
- alac
The Arch-Linux-based image provided in this repository uses an updated version of the docker image base/archlinux
to install ffmpeg-libfdk_aac from the Arch User Repository (AUR). To use this image, simply modify the top-level build.sh
by replacing image_name=alpine-ffmpeg
with image_name=arch-ffmpeg
before running build.sh
.
~1.3 GB
- Includes support for libfdk_aac and most popular audio/video codecs
- 1.3 GB (Note that if your system is already using an updated
base/archlinux
image withyaourt
, the actual space consumption offfmpeg
+ libraries is ~350MB - Long build process. The steps this image takes to build are:
- Downloads the
base/archlinux
if necessary- Creates an updated
base/archlinux
layer (updates databases/packages)- Creates a layer with yaourt setup
- Creates a layer with ffmpeg-libfdk_aac
- libx264
- libx265
- libvpx
- libvpx-vp9
- libtheora
- libfdk_aac
- aac
- libopus
- libvorbis
- libmp3lame
- flac
- alac