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
ffmpegbinary (for file-level commands) - Limited to no overhead executing
ffmpegwithin a docker container - Portability across all hosts: if docker can run on your system, you can have full
ffmpegsupport - 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.mkvdffmpeg consists of two parts:
- A docker image that has
ffmpegconfigured as its entrypoint - A bash executable to format
ffmpegcommands 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
ffmpegas its entrypoint; and - Saving
dffmpeg.shto 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/dffmpegNote: 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/dffmpegTo 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-ffmpegfor use case 1; andarch-ffmpegfor 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-aacconfigured
- 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/archlinuximage withyaourt, the actual space consumption offfmpeg+ libraries is ~350MB - Long build process. The steps this image takes to build are:
- Downloads the
base/archlinuxif necessary- Creates an updated
base/archlinuxlayer (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