ffmpeg

ffmpeg is the Swiss-army-knife command-line tool for recording, converting, and streaming audio and video. It handles essentially every codec and container format in common use, and its filtergraph system (-filter_complex) supports arbitrarily chained transformations. It’s the backend underneath yt-dlp, OBS, and countless media pipelines.

M4A → MP3

ffmpeg -i ${INPUT}.m4a -c:v copy -c:a libmp3lame \
       -q:a 0 ${OUTPUT}.mp3
  • -c:v copy passes album art through unchanged.
  • -c:a libmp3lame uses the LAME encoder.
  • -q:a maps to LAME’s -V (VBR quality) option: 0 is highest quality, 9 is lowest. Conventional wisdom says 34 is transparent enough, but in practice -q:a 0 often produces a smaller file than the source m4a anyway — despite mp3 nominally being less efficient than AAC.

MP4 → GIF

GIF only supports a 256-color palette, so a two-pass approach (generate an optimized palette, then apply it) gives dramatically better output than a naive one-liner:

# Generate an optimized palette.
ffmpeg -i $INPUT.mp4 \
       -filter_complex "[0:v] palettegen" $PALETTE.png
 
# Convert the MP4 to GIF using that palette.
ffmpeg -i $INPUT.mp4 -i $PALETTE.png \
       -filter_complex "[0:v][1:v] paletteuse" \
                        $OUTPUT.gif

MP4 → WebP

Animated WebP is much smaller than GIF for the same visual content and supports full color:

ffmpeg -i $INPUT.mp4 \
       -vf "fps=10,scale=720:-1:flags=lanczos" \
       -vcodec libwebp -lossless 0 -compression_level 6 \
       -q:v 50 -loop 0 -preset picture -an \
       -vsync 0 $OUTPUT.webp
  • fps=10,scale=720:-1:flags=lanczos — throttle to 10 fps and resize to 720px wide (height auto).
  • -loop 0 — loop forever.
  • -an — drop audio.
  • -q:v 50 — quality/Size tradeoff; lower is smaller and uglier.

Sources

Related: yt-dlp, fix-exif-data-google-photos-exports