Skip to content

Using ffmpeg

Combine Video Files

First make a video stream file. All this is a text file with the file names in listed by file 'filename.mkv' for each file. Here is a quick and easy way to generate that file:

Example

printf "file '%s'\n" *.mkv > mylist.txt

Next you need to tell ffmpeg that you're going to combine the file with the concat format. In this example I was converting a DVD I dumped with makemkv. Since they're all using the same formats and resolutions I didn't have to worry about adding a bunch of stuff. I also had it write it to mp4 and made me easier for Plex to stream it with the movflags.

Example

ffmpeg -fflags +genpts -f concat -safe 0 -i mylist.txt -c copy -movflags +faststart -movflags use_metadata_tags Your.File.Name.mp4

Removing Tracks from a File

First find all the mappings in the file by doing ffmpeg -i video.file.here.mp4

You should see a few things that start with Stream #0:0 or Stream #0:1 and so on. Those are the various audio and video streams, yes things like mkv can have many different streams, codecs, etc. mp4, m4v, webm, etc are limited though. So lets' say I have a file that has both English and Spanish audio and I only want to keep the 2nd audio stream and drop the first. Looking at the mappings I can see that 0:0 is the video stream, so I want to keep that. I also see that I want to keep 0:2 and drop 0:1 so I will tell ffmpeg that I want to copy everything in the file, but I want to drop the 0:1 stream. In this example you can see that I also included flag to make it load faster and use metadata too.

Example

ffmpeg -i video.file.here.m4v -map 0:0 -map 0:2 -c copy -movflags faststart -movflags use_metadata_tags video.output.here.mp4

Setting New Default Audio Track

Let's remap some audio streams and set the 0:2 to the default

Example

ffmpeg -c copy -map 0:0 -map 0:2 -map 0:1 -map 0:7 -disposition:a:0 default -disposition:a:1 none

Looking at the command above we're saying that in the output file audio a:0 will be the default and a:1 will not be anything. This sets whatever was the default to none and promotes the stream we want as the default. You'll see that we're also moving stream 0:2 head of stream 0:1. So in the output file stream 0:2 will in the a:0 place.

Change the Language Tag of a Stream

Lets say we have some tracks that are not tagged as the language we want. We'll add the metadata tags BEFORE the mapping. The metadata tags are going to corrospond to the output streams in their order, so taking the command above we would do

Example

ffmpeg -i video.mp4 -c copy -metadata:s:0 language=eng -metadata:s:1 language=eng -metadata:s:2 language=eng -metadata:s:3 language=eng -map 0:0 -map 0:2 -map 0:1 -map 0:7 -disposition:a:0 default -disposition:a:1 none remapped_video.mp4

This command says that stream 0,1,2,3 are going to have the tag eng and we're mapping streams 0,2,1,7 from the input to and they will become streams 0,1,2,3 on the output with the default audio stream being the 0:2 on the input or 0:1 on the output.

Let's say we want to add other information such as title information, we would add another -metadata:s:0 title="TITLE HERE" for each stream. here's an example of remapping, dropping, and adding metadata

Example

ffmpeg -i Highlander\ \(1986\)\ Remux-1080p\ AV1\ DTS-HD\ MA\ \[EN+DE\]\ 4K4U\ tt0091203.m4v -y -c copy -metadata:s:0 title="Highlander (1986) Remux-1080p x265 DTS-HD MA [E tt0091203" -metadata:s:1 title="DTS-HD MA 5.1" -metadata:s:1 language=eng -metadata:s:2 title="DTS-MA 2.0" -metadata:s:2 language=eng -metadata:s:3 title="DTS 2.0" -metadata:s:3 language=eng -map 0:0 -map 0:2 -map 0:1 -map 0:7 -disposition:a:0 default -disposition:a:1 none Highlander\ \(1986\)\ Remux-1080p\ AV1\ DTS-HD\ MA\ \[EN\]\ tt0091203.mp4

Success

Output #0, mp4, to 'Highlander (1986) Remux-1080p AV1 DTS-HD MA [E tt0091203.mp4':
 Metadata:
   major_brand     : mp42
   minor_version   : 512
   compatible_brands: mp42av01iso2mp41
   title           : Highlander (1986) Remux-1080p x265 DTS-HD MA [EN+D 4K4U tt0091203
   encoder         : Lavf58.29.100
   Stream #0:0(und): Video: av1 (Main) (av01 / 0x31307661), yuv420p10le(tv, bt709), 1920x1080 [SAR 1:1 DAR 16:9], q=2-31, 7534 kb/s, 24 fps, 24 tbr, 90k tbn, 90k tbc (default)
   Metadata:
     creation_time   : 2023-02-28T21:31:32.000000Z
     handler_name    : VideoHandler
     title           : Highlander (1986) Remux-1080p x265 DTS-HD MA [E tt0091203
   Stream #0:1(eng): Audio: dts (DTS-HD MA) (mp4a / 0x6134706D), 48000 Hz, 5.1(side), s32p (24 bit) (default)
   Metadata:
     creation_time   : 2023-02-28T21:31:32.000000Z
     title           : DTS-HD MA 5.1
     handler_name    : Surround
   Stream #0:2(eng): Audio: dts (DTS-HD MA) (mp4a / 0x6134706D), 48000 Hz, stereo, s16p
   Metadata:
     creation_time   : 2023-02-28T21:31:32.000000Z
     title           : DTS-MA 2.0
     handler_name    : Stereo
   Stream #0:3(eng): Audio: dts (DTS) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 768 kb/s
   Metadata:
     creation_time   : 2023-02-28T21:31:32.000000Z
     title           : DTS 2.0
     handler_name    : Stereo
Stream mapping:
 Stream #0:0 -> #0:0 (copy)
 Stream #0:2 -> #0:1 (copy)
 Stream #0:1 -> #0:2 (copy)
 Stream #0:7 -> #0:3 (copy)
Press [q] to stop, [?] for help

M1 Hardware Acceleration

Apple silicon uses videotoolbox for it's HW Acceleration. If you need to control the quality add -q:v 50 to after _videotoolbox with the number being 0-100 where 100 is lossless.

The M1 supports the following encode / decode codes:

  • mpeg1_videotoolbox
  • mpeg2_videotoolbox
  • mpeg4_videotoolbox
  • h263_videotoolbox
  • h264_videotoolbox
  • prores_videotoolbox
  • vp9_videotoolbox
  • hevc_videotoolbox

Example

ffmpeg -i video_file.mp4 -c:v h264_videotoolbox -c:a copy -vf subtitles=subititles.vtt -movflags faststart -movflags use_metadata_tags video_burnin_subtitles.mp4

This example shows how to burn in subtitles to a video using hardware acceleration on Apple silicon, e.g. M1, while placing the ATOM upfront to easy decode / streaming.

See Also:
This Stack Exchange post
Documentation on the -map flag