Smaller mkv with ffmpeg

When you run a Plex Media Server you know that family and friends ask for specific content to be placed on it so they can watch it. It comes down that a “popular” series just finished up all 9 of their episodes and the wanted it to exist on our Plex. I was able to find the asked content, but was a bit surprised when the video content was a spectacular 1080p but the audio content defaulted to Brazilian Portuguese.

Lucky for me there was an English audio stream as well, but I felt it annoying that if I wanted to start watching this and have to swap to the secondary audio track every time. With the power of ffmpeg[static] and a couple smart command-line parameters I was able to re-make my videos with English as the default language and cut out all the unnecessary data.

First thing was to run ffprobe on the file and see the output:

$ ffprobe Filename.mkv
ffprobe version 4.2.1-static https://johnvansickle.com/ffmpeg/  Copyright (c) 2007-2019 the FFmpeg developers
  built with gcc 6.3.0 (Debian 6.3.0-18+deb9u1) 20170516
  configuration: --enable-gpl --enable-version3 --enable-static --disable-debug --disable-ffplay --disable-indev=sndio --disable-outdev=sndio --cc=gcc-6 --enable-fontconfig --enable-frei0r --enable-gnutls --enable-gmp --enable-libgme --enable-gray --enable-libaom --enable-libfribidi --enable-libass --enable-libvmaf --enable-libfreetype --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-librubberband --enable-libsoxr --enable-libspeex --enable-libsrt --enable-libvorbis --enable-libopus --enable-libtheora --enable-libvidstab --enable-libvo-amrwbenc --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libdav1d --enable-libxvid --enable-libzvbi --enable-libzimg
  libavutil      56. 31.100 / 56. 31.100
  libavcodec     58. 54.100 / 58. 54.100
  libavformat    58. 29.100 / 58. 29.100
  libavdevice    58.  8.100 / 58.  8.100
  libavfilter     7. 57.100 /  7. 57.100
  libswscale      5.  5.100 /  5.  5.100
  libswresample   3.  5.100 /  3.  5.100
  libpostproc    55.  5.100 / 55.  5.100
Input #0, matroska,webm, from 'Filename.mkv':
  Metadata:
    title           : Filename
    creation_time   : 2021-01-15T09:31:57.000000Z
    ENCODER         : Lavf58.29.100
  Duration: 00:26:33.02, start: 0.000000, bitrate: 2591 kb/s
    Stream #0:0: Video: h264 (Main), yuv420p(tv, bt709, progressive), 1920x1080 [SAR 1:1 DAR 16:9], 23.98 fps, 23.98 tbr, 1k tbn, 180k tbc (default)
    Metadata:
      DURATION        : 00:26:33.013000000
    Stream #0:1(por): Audio: ac3, 48000 Hz, stereo, fltp, 192 kb/s (default)
    Metadata:
      title           :
      DURATION        : 00:26:33.024000000
    Stream #0:2(eng): Audio: ac3, 48000 Hz, stereo, fltp, 192 kb/s
    Metadata:
      title           :
      DURATION        : 00:26:33.024000000
    Stream #0:3(por): Subtitle: ass
    Metadata:
      title           : Brazilian Portuguese
      DURATION        : 00:26:30.679000000

The output shows me 4 streams: 1 video stream, 2 audio streams, and 1 subtitle stream.

ffmpeg allows us to be able to “map” specific streams between input and output, and with this we’ll tell ffmpeg to use stream 0 for our “video”, steam 2 (index 1) as our audio stream, and that we do not want the Portuguese subtitles.

ffmpeg -i Filename.mkv -vcodec copy -acodec copy -map 0:v:0 -map 0:a:1 -sn new-Filename.mkv

This happens very fast since the data is already there and we’re telling ffmpeg not to transcode it in any way.

$ ffprobe new-Filename.mkv
ffprobe version 4.2.1-static https://johnvansickle.com/ffmpeg/  Copyright (c) 2007-2019 the FFmpeg developers
  built with gcc 6.3.0 (Debian 6.3.0-18+deb9u1) 20170516
  configuration: --enable-gpl --enable-version3 --enable-static --disable-debug --disable-ffplay --disable-indev=sndio --disable-outdev=sndio --cc=gcc-6 --enable-fontconfig --enable-frei0r --enable-gnutls --enable-gmp --enable-libgme --enable-gray --enable-libaom --enable-libfribidi --enable-libass --enable-libvmaf --enable-libfreetype --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-librubberband --enable-libsoxr --enable-libspeex --enable-libsrt --enable-libvorbis --enable-libopus --enable-libtheora --enable-libvidstab --enable-libvo-amrwbenc --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libdav1d --enable-libxvid --enable-libzvbi --enable-libzimg
  libavutil      56. 31.100 / 56. 31.100
  libavcodec     58. 54.100 / 58. 54.100
  libavformat    58. 29.100 / 58. 29.100
  libavdevice    58.  8.100 / 58.  8.100
  libavfilter     7. 57.100 /  7. 57.100
  libswscale      5.  5.100 /  5.  5.100
  libswresample   3.  5.100 /  3.  5.100
  libpostproc    55.  5.100 / 55.  5.100
Input #0, matroska,webm, from 'new-Filename.mkv':
  Metadata:
    title           : COMANDO.TO
    ENCODER         : Lavf58.29.100
  Duration: 00:26:33.02, start: 0.000000, bitrate: 2397 kb/s
    Stream #0:0: Video: h264 (Main), yuv420p(tv, bt709, progressive), 1920x1080 [SAR 1:1 DAR 16:9], 23.98 fps, 23.98 tbr, 1k tbn, 180k tbc (default)
    Metadata:
      DURATION        : 00:26:33.012000000
    Stream #0:1(eng): Audio: ac3, 48000 Hz, stereo, fltp, 192 kb/s
    Metadata:
      title           :
      DURATION        : 00:26:33.024000000

In regards to saving space with removing all the junk data I had to do the same conversion over 9 files. The smallest and largest file before/after was the following:

Smallest before: 516,127,446, after: 477,507,693, savings of 38,619,753 or 7.4%

Largest before: 2,806,175,671, after: 2,716,594,097, savings of 89,581,574 or 3.1%

Any space saved is a blessing!

Leave a Reply