Back to TIL
macOS

Transcoding Video with FFmpeg and Apple VideoToolbox

Started experimenting with FFmpeg for HEVC encoding using Apple’s VideoToolbox (GPU acceleration), aiming for 4K video with 10-bit color and 5.1 audio. They have to be playable by my old LG OLED TV from 2018, the LG C9.

Ran into compatibility issues but finally got it. Here’s a sample command if you’re in a similar situation:

$ ffmpeg -i input.mkv \
    -c:v hevc_videotoolbox \
    -pix_fmt p010le \
    -b:v 20M \
    -c:a aac -b:a 384k -ac 6 \
    -c:s copy \
    -map 0:v -map 0:a:0 -map 0:s:0 \
    -metadata:s:s:0 language=eng \
    -movflags +faststart \
    output_optimised.mkv

Each parameter in detail:

  • -i is the input file
  • -c:v specifies the video encoder to use. In my case I want to use my MacBook’s Apple Silicon GPUs for faster transcoding. Works beautifully with speeds from 1.4x to 2.7x, while only consuming 18w of power. That is incredibly low power draw.
  • -pix_fmt p010le sets the pixel format to something 10bit that VideoToolbox can do hardware accelerated encoding with
  • -b:v 20M limits the video bandwidth 20mbps. The higher you go, the bigger the file. The lower you go, the smaller the file but also artifacts will be more visible. In my case, I found a good sweet spot here.
  • -c:a aac ... specifies we want AAC audio with 384kbps bandwidth and 6 channels (5.1 surround sound). It sounded good on my Sonos system.
  • -c:s copy copy the subtitles
  • -map ... tells ffmpeg to keep the first video stream, the first audio stream and the first subtitles. I don’t need multi languages.
  • -metadata:s:s:0 language=eng sets the metadata for the subtitles. In my case here the language is English.
  • -movflags +faststart not really necessary, but should optimize the contained MP4 for streaming over a network by placing metadata at the beginning.