this post was submitted on 24 Aug 2026
10 points (100.0% liked)

ffmpeg - the media conversion toolbox

42 readers
3 users here now

Everything about the powerful open source media recording, conversion and streaming tool!

Scripting, encoding, remuxing, filters, choosing the right parameters...

Be civil and on-topic

founded 3 days ago
MODERATORS
 
remove_extension() {
  sed -E 's/^(.+)\.[^.]+$/\1/'
}

get_extension() {
  sed -E '/^\.?[^.]+$/d; s/^.+\.([^.]*)$/\1/'
}

ffmpeg_av1_opus() {
  if [ "$#" -lt 4 ]; then
    return
  fi
  ffmpeg -i "$4" -c:v libsvtav1 -preset "$1" -crf "$2" -c:a libopus -vbr:a 1 -b:a "$3" "${5:-"$(echo "$4" | remove_extension)_ffmpeg_av1_$1_$2_opus_$3.mkv"}"
}

ffmpeg_av1_lossless_flac() {
  if [ "$#" -eq 0 ]; then
    return
  fi
  ffmpeg -i "$1" -c:v libsvtav1 -svtav1-params lossless=1 -preset -2 -c:a flac "${2:-"$(echo "$1" | remove_extension)_ffmpeg_av1_lossless_flac.mkv"}"
}

ffmpeg_opus() {
  if [ "$#" -lt 2 ]; then
    return
  fi
  ffmpeg -i "$2" -c:a libopus -vbr:a 1 -b:a "$1" "${3:-"$(echo "$2" | remove_extension)_ffmpeg_opus_$1.opus"}"
}

ffmpeg_flac() {
  if [ "$#" -eq 0 ]; then
    return
  fi
  ffmpeg -i "$1" -c:a flac "${2:-"$(echo "$1" | remove_extension)_ffmpeg_flac.flac"}"
}

ffmpeg_segment() {
  if [ "$#" -lt 2 ]; then
    return
  fi
  ffmpeg -i "$2" -c copy -map 0 -segment_time "$1" -f segment -reset_timestamps 1 "${3:-"$(echo "$2" | remove_extension)_ffmpeg_%04d.$(echo "$2" | get_extension)"}"
}

ffmpeg_concat_auto() {
  local files=()
  if [ "$#" -eq 0 ]; then
    for f in *; do
      test -f "$f" && files+=("$f")
    done
  else
    files=("$@")
  fi
  ffmpeg -f concat -safe 0 -i <(printf "file '$PWD/%s'\n" "${files[@]}") -c copy "$(echo "${files[0]}" | remove_extension | sed -E 's/_ffmpeg_[0-9]+$//').$(echo "${files[0]}" | get_extension)"
}

ffmpeg_concat() {
  if [ "$#" -lt 2 ]; then
    return
  fi
  ffmpeg -f concat -safe 0 -i <(printf "file '$PWD/%s'\n" "${@:2}") -c copy "$1"
}

echo_non_ffmpeg() {
  while IFS= read -r -d '' f; do
    case "$f" in
      *ffmpeg_*) ;;
      *)
        echo "$f"
        ;;
    esac
  done < <(find . -type f -print0)
}

remove_non_ffmpeg() {
  while IFS= read -r -d '' f; do
    case "$f" in
      *ffmpeg_*) ;;
      *)
        rm -f "$f"
        ;;
    esac
  done < <(find . -type f -print0)
}

echo_ffmpeg() {
  while IFS= read -r -d '' f; do
    case "$f" in
      *ffmpeg_*)
        echo "$f"
        ;;
      *) ;;
    esac
  done < <(find . -type f -print0)
}

remove_ffmpeg() {
  while IFS= read -r -d '' f; do
    case "$f" in
      *ffmpeg_*)
        rm -f "$f"
        ;;
      *) ;;
    esac
  done < <(find . -type f -print0)
}

mv_space_underscore() {
  while IFS= read -r -d '' f; do
    new="${f// /_}"
    [[ -e "$new" ]] && {
      echo "skipping '$f', '$new' exists"
      continue
    }
    mv -- "$f" "$new"
  done < <(find . -depth -name '* *' -print0)
}

mv_space_hyphen() {
  while IFS= read -r -d '' f; do
    new="${f// /-}"
    [[ -e "$new" ]] && {
      echo "skipping '$f', '$new' exists"
      continue
    }
    mv -- "$f" "$new"
  done < <(find . -depth -name '* *' -print0)
}

Edit: Add -vbr:a 1 to opus, thanks to exdor.

you are viewing a single comment's thread
view the rest of the comments
[–] exdor@programming.dev 2 points 2 days ago* (last edited 2 days ago) (2 children)

Very nice! Will see what I can adapt

I would recommend to always use vbr for opus

-c:a libopus -vbr:a 1 -ac 2

There are 2 modes 1 and 2, not sure why, but 1 resulted in smaller files while taking a bit longer so I use that.

How big are these lossless encodes? I expect HUGE? flac is smaller than some weird dolby formats though.

I really like your shell magic for the concatenation, way more efficient than building a filelist.txt

Also really nice way you handle the extension

[–] Willie169@infosec.pub 1 points 2 days ago (1 children)

-vbr 0 means CBR (constant bitrate), 1 means normal VBR (variable bitrate), 2 means constrained VBR, and 1 is the default for most build I think.

-ac is audio channel. 1 is mono, 2 is stereo, 6/8 are 5.1/7.1 surround, so I think I'll keep it unspecified since some movies or Dolby Atmos things use >2 channels.

[–] exdor@programming.dev 2 points 6 hours ago

Interesting! Yeah I use ffmpegs default matrix to downmix to stereo to save a lot of data as I dont have a surround system and never will. I prefer to watch movies with good open back headphones and doubt that a surround system will come close.

[–] Willie169@infosec.pub 1 points 2 days ago (1 children)

Thanks for your recommendation.

Regarding lossless encoding, I find flac much smaller than wav, another lossless format, while lossless AV1 is quite huge in size when converting from H264/H265.

~/a $ du -sh *
10308   file_example_WAV_10MG.wav
2924    file_example_WAV_10MG_ffmpeg_flac.flac
2016    file_example_WAV_10MG_ffmpeg_opus_256k.opus
~/a $ declare -f ffmpeg_flac ffmpeg_opus
ffmpeg_flac ()
{
    if [ "$#" -eq 0 ]; then
        return;
    fi;
    ffmpeg -i "$1" -c:a flac "${2:-"$(echo "$1" | remove_extension)_ffmpeg_flac.flac"}"
}
ffmpeg_opus ()
{
    if [ "$#" -lt 2 ]; then
        return;
    fi;
    ffmpeg -i "$2" -c:a libopus -vbr:a 1 -ac 2 -b:a "$1" "${3:-"$(echo "$2" | remove_extension)_ffmpeg_opus_$1.opus"}"
}
[–] exdor@programming.dev 2 points 6 hours ago

Yes wav is uncompressed and flac is lossless compressed. For example an empty wav should be the same size than one with content, while an empty flac would be very small.

Some people in the forums etc convert audio to wav which is really stupid...