WittCode💻

How to Convert an MP4 to MP3 using FFmpeg in Docker

By

Learn how to convert an MP4 to an MP3 using FFmpeg inside a Docker container. We will also learn how to copy files from a Docker container to a host machine, what FFmpeg is, and what Docker build arguments are.

Table of Contents 📖

What is FFmpeg?

FFmpeg, or Fast Forwarding Moving Picture Experts Group, is a command line tool that allows us to process audio and video files. We can use it to add subtitles to video, change a video's contrast, stream video to a server, and much much more. For this demonstration, we will use FFmpeg to convert an MP4 file to an MP3 file.

Building the FFmpeg Dockerfile

As FFmpeg is a command line tool, we can easily spin up a Docker container that contains FFmpeg. There are premade images that contain FFmpeg already, but it is very simple to create our own custom image. For this demonstration, we will use Ubuntu version 24.04.

FROM ubuntu:24.04

Next, we just need to install FFmpeg using APT.

RUN apt update
RUN apt install -y ffmpeg

INFO: The -y flag is for non-interactive mode so we don't have to say yes/no to dependencies.

No lets set our working directory and define some build arguments.

WORKDIR /media
ARG VIDEO_INPUT_FILE
ARG AUDIO_OUTPUT_FILE

Build arguments are supplied to Docker at build time. These are going to be the input MP4 file and output MP3 file. However, build arguments are used at build time and not at runtime. This is an issue because we will run FFmpeg at runtime with the ENTRYPOINT command. We can work around this by passing the build arguments as environment variables.

ENV ENV_VIDEO_INPUT_FILE=${VIDEO_INPUT_FILE}
ENV ENV_AUDIO_OUTPUT_FILE=${AUDIO_OUTPUT_FILE}

ENVs are passed in as part of the environment so they are available at run time. Now lets copy the provided video file to the working directory.

COPY ${ENV_VIDEO_INPUT_FILE} .

Finally, we just need to run FFmpeg when the container starts up.

ENTRYPOINT ffmpeg -i ${ENV_VIDEO_INPUT_FILE} ${ENV_AUDIO_OUTPUT_FILE} -y
  • -i - The media input file.
  • -y - Overwrite output fiels without asking. This is so we can run this multiple times without creating a new container.

Creating the FFmpeg Image

Now lets build the image using docker build.

docker build --build-arg VIDEO_INPUT_FILE=<YOUR_VIDEO_INPUT_FILE> --build-arg AUDIO_OUTPUT_FILE=<YOUR_AUDIO_OUTPUT_FILE> -t ffmpeg-i
  • Specify the video input file with VIDEO_INPUT_FILE.
  • Specify the audio output file with AUDIO_OUTPUT_FILE.
  • Name the image ffmpeg-i.

Now we just need to build a container from this image.

docker run --name ffmpeg-c -v ./:/media ffmpeg-i
  • Name the container ffmpeg-c.
  • Specify a host volume mapping the current directory to /media in the container. This is important as it will sync the MP3 output file in the container to our host machine.

When running the container, output should be similar to the following:

Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'how-to-reload-nginx-configuration-periodically-docker.mp4':
Metadata:
  major_brand     : isom
  minor_version   : 512
  compatible_brands: isomiso2avc1mp41
  encoder         : Lavf60.3.100
Duration: 00:04:49.15, start: 0.000000, bitrate: 4023 kb/s
Stream #0:0[0x1](und): Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, bt709, progressive), 2560x1440 [SAR 1:1 DAR 16:9], 3713 kb/s, 60 fps, 60 tbr, 15360 tbn (default)
  Metadata:
    handler_name    : VideoHandler
    vendor_id       : [0][0][0][0]
Stream #0:1[0x2](und): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 298 kb/s (default)
  Metadata:
    handler_name    : SoundHandler
    vendor_id       : [0][0][0][0]
Stream mapping:
Stream #0:1 -> #0:0 (aac (native) -> mp3 (libmp3lame))
Press [q] to stop, [?] for help
Output #0, mp3, to 'output-aduio.mp3':
Metadata:
  major_brand     : isom
  minor_version   : 512
  compatible_brands: isomiso2avc1mp41
  TSSE            : Lavf60.16.100
Stream #0:0(und): Audio: mp3, 48000 Hz, stereo, fltp (default)
  Metadata:
    handler_name    : SoundHandler
    vendor_id       : [0][0][0][0]
    encoder         : Lavc60.31.102 libmp3lame
[out#0/mp3 @ 0xaaaae49e1910] video:0kB audio:4518kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.007348%
size=    4519kB time=00:04:49.12 bitrate= 128.0kbits/s speed=76.6x