RSS

ffmpeg Convert Video Audio Examples

How to use ffmpeg to convert video and audio format with examples.

Install ffmpeg

On Mac OS X, install with brew :

$ brew install ffmpeg

On Debian Linux:

$ sudo apt-get install ffmpeg

Convert audio file format to .mp3

Convert to mp3 format with libmp3lame

LAME (libmp3lame) is a high quality MPEG Audio Layer III (MP3) encoder. LAME is now regarded as the top MP3 encoder for mid-high bitrates and variable bit rate (VBR). Quality and speed enhancements continue to be made, making LAME likely the only MP3 encoder still actively developed.

Use libmp3lame to encode mp3 file, ffmpeg need compiled with --enable-libmp3lame.

Note: After converted to mp3, the mp3tag also updated to keep the original audio info.

Encoding mp3 with a fixed bitrate

Convert .wav, .ape to .mp3 with 320kb/s bitrate (the highest quality) example:

$ ffmpeg -i foo.ape -codec:a libmp3lame -b:a 320k output.mp3
Input #0, ape, from 'foo.ape':
  Metadata:
    Title           : xx
    Artist          : xx
    Album           : xx
    Track           : xx
    Genre           : xx
    ALBUM ARTIST    : xx
  Duration: 00:04:13.19, start: 0.000000, bitrate: 774 kb/s
  Stream #0:0: Audio: ape (APE  / 0x20455041), 44100 Hz, stereo, s16p
Stream mapping:
  Stream #0:0 -> #0:0 (ape (native) -> mp3 (libmp3lame))
Press [q] to stop, [?] for help
Output #0, mp3, to 'output.mp3':
  Metadata:
    TIT2            : xx
    TPE1            : xx
    TALB            : xx
    TRCK            : xx
    TCON            : xx
    ALBUM ARTIST    : xx
    TSSE            : Lavf59.16.100
  Stream #0:0: Audio: mp3, 44100 Hz, stereo, s16p, 320 kb/s
    Metadata:
      encoder         : Lavc59.18.100 libmp3lame
size=    9893kB time=00:04:13.20 bitrate= 320.1kbits/s speed=49.7x
video:0kB audio:9892kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.012410%

Convert any audio format (.wav, .ape, .aiff, .flac etc) to .mp3 with 320kb/s bitrate (the highest quality) and also keep metadata example:

ffmpeg -i "$filename" -codec:a libmp3lame -b:a 320k -map_metadata 0 -id3v2_version 3 "$output"

Encoding mp3 with variable bitrate

Use the best variable rate with -q:a 0, the bitrate range is 220-260kb/s, example:

$ ffmpeg -i foo.ape -codec:a libmp3lame -q:a 0 output.mp3
Input #0, ape, from 'foo.ape':
  Metadata:
    Title           : xx
    Artist          : xx
    Album           : xx
    Track           : xx
    Genre           : xx
    ALBUM ARTIST    : xx
  Duration: 00:04:13.19, start: 0.000000, bitrate: 774 kb/s
  Stream #0:0: Audio: ape (APE  / 0x20455041), 44100 Hz, stereo, s16p
Stream mapping:
  Stream #0:0 -> #0:0 (ape (native) -> mp3 (libmp3lame))
Press [q] to stop, [?] for help
Output #0, mp3, to 'output.mp3':
  Metadata:
    TIT2            : xx
    TPE1            : xx
    TALB            : xx
    TRCK            : xx
    TCON            : xx
    ALBUM ARTIST    : xx
    TSSE            : Lavf59.27.100
  Stream #0:0: Audio: mp3, 44100 Hz, stereo, s16p
    Metadata:
      encoder         : Lavc59.37.100 libmp3lame
size=    7545kB time=00:04:13.20 bitrate= 244.1kbits/s speed=55.8x
video:0kB audio:7544kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.005450%

Note: Since mp3 format is lossy encoding, use best variable bitrate -q:a 0 can get similar quality with fixed bitrate -b:a 320k but smaller file size.

Default mp3 encoding quality

If do not specific encoding quality, the default is 128kb/s, see the last two lines of following example:

$ ffmpeg -i foo.ape output.mp3
Input #0, ape, from 'foo.ape':
  Metadata:
    Title           : xx
    Artist          : xx
    Album           : xx
    Track           : xx
    Genre           : xx
    ALBUM ARTIST    : xx
  Duration: 00:04:13.19, start: 0.000000, bitrate: 774 kb/s
  Stream #0:0: Audio: ape (APE  / 0x20455041), 44100 Hz, stereo, s16p
Stream mapping:
  Stream #0:0 -> #0:0 (ape (native) -> mp3 (libmp3lame))
Press [q] to stop, [?] for help
Output #0, mp3, to 'output.mp3':
  Metadata:
    TIT2            : xx
    TPE1            : xx
    TALB            : xx
    TRCK            : xx
    TCON            : xx
    ALBUM ARTIST    : xx
    TSSE            : Lavf59.16.100
  Stream #0:0: Audio: mp3, 44100 Hz, stereo, s16p
    Metadata:
      encoder         : Lavc59.18.100 libmp3lame
size=    3957kB time=00:04:13.20 bitrate= 128.0kbits/s speed=  48x
video:0kB audio:3957kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.010391%

Extract audio from video file

$ ffmpeg -i foo.webm -vn -acodec libmp3lame -q:a 0 output.mp3
-vn                 disable video
-acodec libmp3lame  force audio use libmp3lame codec

Convert any video format to .mp4

MP4 is widely used because it is highly compatible with most devices and platforms, offers efficient compression for small file sizes without sacrificing quality, and supports various types of multimedia content including video, audio, text, and images. It is ideal for streaming, editing, and general multimedia use, making it a versatile and standardized format.

Convert to .mp4 may also compress video and save space, suitable transfer to mobile device.

To convert a video to MP4 using FFmpeg with x264 encoding, you can use the following command in the terminal:

ffmpeg -i "$input" -map_metadata 0 -crf 17 -c:v libx264 -c:a aac -b:a 256k "$output"
  • -i "$input": Specifies the input file, where $input is a variable representing the path to the source video.
  • -map_metadata 0: Maps all metadata from the input file to the output file, preserving information such as title, author, and other tags.
  • -crf 17: Sets the Constant Rate Factor (CRF) for the video encoding to 17. CRF controls the quality and size of the output video; lower values result in higher quality. A CRF of 17 typically produces visually lossless quality.
  • -c:v libx264: Specifies the video codec to be used for encoding as H.264 (libx264), which is a widely used video compression standard known for its balance of quality and file size.
  • -c:a aac: Specifies the audio codec to be used for encoding as Advanced Audio Coding (AAC), which is a standard for lossy audio compression.
  • -b:a 256k: Sets the audio bitrate to 256 kbps, which determines the quality and size of the audio stream. Higher bitrates provide better audio quality.
  • "$output": Specifies the output file name and path, where $output is a variable representing the destination for the converted video file.

More how to choose crf value:

  • The range of the CRF scale is 0–51, where 0 is lossless (for 8 bit only, for 10 bit use -qp 0), 23 is the default, and 51 is worst quality possible.
  • A lower value generally leads to higher quality, and a subjectively sane range is 17–28.
  • Consider 17 or 18 to be visually lossless or nearly so; it should look the same or nearly the same as the input but it isn’t technically lossless.

Trim a video to specific time range

The following command takes input.mp4, starts extracting at 5 minutes and 20 seconds, and continues for 10 minutes, copying both the video and audio streams without re-encoding, and saves the result as output.mp4:

ffmpeg -i input.mp4 -ss 00:05:20 -t 00:10:00 -c:v copy -c:a copy output.mp4
  • -i input.mp4: This specifies the input file, which in this case is input.mp4.
  • -ss 00:05:20: This sets the start time of the extraction. The video will start from 5 minutes and 20 seconds into the input.mp4 file.
  • -t 00:10:00: This specifies the duration of the extraction. The command will extract a segment that is 10 minutes long starting from the -ss time (5 minutes and 20 seconds).
  • -c:v copy: This tells ffmpeg to copy the video codec, meaning it will not re-encode the video stream but just copy it as is.
  • -c:a copy: This tells ffmpeg to copy the audio codec, meaning it will not re-encode the audio stream but just copy it as is.
  • output.mp4: This is the name of the output file that will contain the extracted video segment.

The -c:v copy -c:a copy commands copy the original video and audio streams without re-encoding.

To specify the time, you can use two different time unit formats: sexagesimal (HOURS:MM:SS.MILLISECONDS, e.g., 01:23:45.678) or in seconds. When using the former, you can omit the milliseconds and use HOURS:MM:SS, as shown in our example.

If you specify a duration that extends beyond the length of the input video, the output video will end when the input video ends.

Resize video retain aspect ratio

To resize a video using FFmpeg, you can use the following command:

ffmpeg -i input.ext -vf scale=width:height output.mp4

Replace input.ext with the name of your source video file, width and height with the desired dimensions, and output.mp4 with the desired name for the resized video file.

For example, to resize a video to 1280x720 resolution, you can use:

ffmpeg -i inputfile.ext -vf scale=1280:720 outputfile.mp4

If you want to maintain the aspect ratio while resizing, you can use:

ffmpeg -i inputfile.ext -vf scale=1280:-1 outputfile.mp4

Here, -1 automatically adjusts the height to maintain the aspect ratio based on the specified width.

However it may run into issue height not divisible by 2 like below:

libx264 @ 0x12a905e60] height not divisible by 2 (320x693)

To resize a video using FFmpeg and keep aspect ratio, you can use the following script to avoid height not divisible by 2 issue:

#!/bin/sh -x

# desired video width
WIDTH=480

INPUT=$1
BASENAME="${INPUT%.*}"   # without extension, e.g. "foo.mp4" -> "foo"
OUTPUT="$BASENAME-${WIDTH}p.mp4"    # output as .mp4

# not use`scale=width:-1` to avoid [libx264 @ 0x12a905e60] height not divisible by 2 (320x693)

ffmpeg -i "$INPUT" -vf "scale=$WIDTH:ceil(ih*$WIDTH/iw/2)*2" -y "$OUTPUT"

Explanation:

  • -vf "scale=$WIDTH:ceil(ih*$WIDTH/iw/2)*2": Applies a video filter (-vf) to resize the video. The scale filter resizes the video to a specified width and calculates the height to maintain the aspect ratio.
    • $WIDTH: The desired width of the output video.
    • ceil(ih*$WIDTH/iw/2)*2: Calculates the height while maintaining the aspect ratio. Here, ih is the input height, and iw is the input width.
      • ih*$WIDTH/iw computes the new height maintaining the aspect ratio.
      • /2)*2 ensures the height is an even number, which is required by many video codecs. The ceil function rounds up to the nearest integer.
  • -y: Overwrites the output file without asking for confirmation if it already exists.

Extract video cover image with exiftool

Use exiftool -json example.mp4 to get cover image tag name. The name may “CoverArt”, “Picture” etc. e.g.

$ exiftool -json example.mp4
  "CoverArt": "(Binary data 31650 bytes, use -b option to extract)",

Here the tag name is CoverArt, then extract with -b, by default it dump the image binary on screen, use > to redirect to a file:

exiftool -b -CoverArt example.mp4 > cover.jpg

Add covert image (thumbnail) to a video

To add an embedded cover/thumbnail:

ffmpeg -i example.mp4 -i cover.jpg -map 0 -map 1 -c copy -c:v:1 png -disposition:v:1 attached_pic out.mp4

Not all muxers support embedded thumbnails, and those who do, only support a few formats, like JPEG or PNG.

Note: Use png even your cover.jpg is jpg format, otherwise you may not able to see it in Finder Preview.

References

OmniLock - Block / Hide App on iOS

Block distractive apps from appearing on the Home Screen and App Library, enhance your focus and reduce screen time.

DNS Firewall for iOS and Mac OS

Encrypted your DNS to protect your privacy and firewall to block phishing, malicious domains, block ads in all browsers and apps

Ad