dotfiles

My personal shell configs and stuff
git clone git://git.alex.balgavy.eu/dotfiles.git
Log | Files | Refs | Submodules | README | LICENSE

ffmpres (6073B)


      1 #!/usr/bin/env bash
      2 # ffmpeg wrapper with various presets.
      3 
      4 if ! command -v ffmpeg &> /dev/null; then echo "ffmpeg not found" && exit 1; fi
      5 main() {
      6   case "$1" in
      7     *.gif)
      8       if ! [ -f "$1" ] ; then echo "$1 not found." && exit 1; fi
      9       echo "GIF: $1"
     10       process_gif "$1"
     11       ;;
     12     *.mp4|*.mov|*.webm|*.m4v|*.mkv)
     13       if ! [ -f "$1" ] ; then echo "$1 not found." && exit 1; fi
     14       echo "VIDEO: $1"
     15       process_video "$@"
     16       ;;
     17     *.mp3|*.wav|*.ogg|*.flac|*.m4a)
     18       if ! [ -f "$1" ] ; then echo "$1 not found." && exit 1; fi
     19       echo "AUDIO: $1"
     20       process_audio "$@"
     21       ;;
     22     "")
     23       process_misc
     24       ;;
     25     *)
     26       echo "File type not supported."
     27       ;;
     28   esac
     29 }
     30 
     31 process_misc() {
     32   echo "For other functionality, please add the filename as the first argument."
     33   select operation in "Record audio" "List devices"; do
     34     case "$operation" in
     35       "Record audio")
     36         echo -n "Devices to record (format n:n): ";
     37         read -r record_src;
     38         echo -n "Output filename: ";
     39         read -r out_name;
     40         ffmpeg -f avfoundation -i "$record_src" "${out_name:-output.mkv}"
     41         break;;
     42       "List devices")
     43         ffmpeg -f avfoundation -list_devices true -i "";
     44         break;;
     45       *)
     46         break;;
     47     esac
     48   done
     49 }
     50 
     51 process_gif() {
     52   select to_fmt in "MP4"; do
     53     case "$to_fmt" in
     54       "MP4")
     55         ffmpeg -i "$1" -r 30 -movflags faststart -pix_fmt yuv420p -vf "scale=trunc(iw/2)*2:trunc(ih/2)*2" "${1%%.gif}.mp4"
     56         break;;
     57       *)
     58         break;;
     59     esac
     60   done
     61 }
     62 
     63 process_audio() {
     64   select operation in "VOLUME" "CLIP"; do
     65     case "$operation" in
     66       "VOLUME")
     67         read -rp "Amount or percent: " vol;
     68         read -rp "Enter output filename: " outfile
     69         ffmpeg -i "$1" -filter:a "volume=$vol" "${outfile:-out-$1}"
     70         break;;
     71       "CLIP")
     72         read -rp "From time (blank if from start): " starttime
     73         read -rp "To time (blank if till end): " endtime
     74         read -rp "Save as: " outfile
     75         if [ -z "$endtime" ]; then
     76           ffmpeg -i "$1" -ss "$starttime" "$outfile"
     77         elif [ -z "$starttime" ]; then
     78           ffmpeg -i "$1" -to "$endtime" "$outfile"
     79         else
     80           ffmpeg -i "$1" -ss "$starttime" -to "$endtime" "$outfile"
     81         fi
     82         break;;
     83       *)
     84         break;;
     85     esac
     86   done
     87 }
     88 
     89 process_video() {
     90   select to_fmt in "MP4" "MP3" "GIF" "NO AUDIO" "CONCAT" "CLIP" "VOLUME" "FAST" "SLOW" "SCREENSHOT" "OPTIMISE"; do
     91     case "$to_fmt" in
     92       "MP4")
     93         ffmpeg -i "$1" -vcodec copy -qscale 0 -c:s mov_text "${1%%.*}.mp4"
     94         break;;
     95       "MP3")
     96         ffmpeg -i "$1" "${1%%.*}.mp3"
     97         break;;
     98       "GIF")
     99         printf "FPS (default 24): "
    100         read -r fps
    101         printf "Scale (default unchanged): "
    102         read -r scale
    103         if [ -n "$scale" ]; then
    104           local filters="fps=${fps:-24},scale=$scale:flags=lanczos"
    105         else
    106           local filters="fps=${fps:-24},scale=0:-1:flags=lanczos"
    107         fi
    108         echo "Creating gif"
    109         local palette="/tmp/palette.png"
    110         ffmpeg -v warning -i "$1" -vf "$filters,palettegen" -y "$palette"
    111         ffmpeg -v warning -i "$1" -i "$palette" -lavfi "$filters [x]; [x][1:v] paletteuse" -y "${1%%.*}.gif"
    112         break;;
    113       "NO AUDIO")
    114         ffmpeg -i "$1" -an "silent-$1"
    115         break;;
    116       "CONCAT")
    117         if [ $# -le 1 ]; then echo "Only one file supplied, need at least two." && exit 1; fi
    118         read -rp "Enter output filename: " outfile
    119         set -x
    120         tempfile="./ffmpeg-list-$RANDOM"
    121         for f in "$@"; do echo "file '$f'" >> "$tempfile"; done
    122         ffmpeg -f concat -safe 0 -i "$tempfile" -c copy "$outfile"
    123         rm "$tempfile"
    124         break;;
    125       "CLIP")
    126         read -rp "From time: " starttime
    127         read -rp "To time: " endtime
    128         read -rp "Save as: " outfile
    129         if [ -z "$outfile" ]; then
    130           if [ -z "$endtime" ]; then
    131             ffmpeg -i "$1" -ss "$starttime" -acodec copy -vcodec copy "out-$1"
    132           elif [ -z "$starttime" ]; then
    133             ffmpeg -i "$1" -to "$endtime" -acodec copy -vcodec copy "out-$1"
    134           else
    135             ffmpeg -i "$1" -ss "$starttime" -to "$endtime" -acodec copy -vcodec copy "out-$1"
    136           fi
    137         else
    138           if [ -z "$endtime" ]; then
    139             ffmpeg -i "$1" -ss "$starttime" "$outfile"
    140           elif [ -z "$starttime" ]; then
    141             ffmpeg -i "$1" -to "$endtime" "$outfile"
    142           else
    143             ffmpeg -i "$1" -ss "$starttime" -to "$endtime" "$outfile"
    144           fi
    145         fi
    146         break;;
    147       "VOLUME")
    148         read -rp "Amount or percent: " vol;
    149         read -rp "Enter output filename: " outfile
    150         ffmpeg -i "$1" -filter:a "volume=$vol" "${outfile:-out-$1}"
    151         break;;
    152       "FAST")
    153         read -rp "Enter output filename: " outfile
    154         ffmpeg -i "$1" -filter_complex "[0:v]setpts=0.5*PTS[v];[0:a]atempo=2.0[a]" -map "[v]" -map "[a]" "${outfile:-out-$1}"
    155         break;;
    156       "SLOW")
    157         read -rp "Enter output filename: " outfile
    158         ffmpeg -i "$1" -filter_complex "[0:v]setpts=1.5*PTS[v];[0:a]atempo=0.67[a]" -map "[v]" -map "[a]" "${outfile:-out-$1}"
    159         break;;
    160       "SCREENSHOT")
    161         read -rp "Timestamp to extract: " ts
    162         ffmpeg -ss "$ts" -i "$1" -frames:v 1 -q:v 2 "$1.jpg"
    163         break;;
    164       "OPTIMISE")
    165         codec="$(ffprobe -v error -select_streams v:0 -show_entries stream=codec_name -of default=noprint_wrappers=1:nokey=1 "$1")"
    166         read -rp "Enter output filename: " outfile
    167         if [ "$codec" = "h264" ]; then
    168           read -rp "Use h265? [Y/n] " -n 1 conf
    169           echo
    170           if [ "$conf" = "Y" ] || [ "$conf" = "y" ]; then
    171             read -rp "CRF value (24..30, lower == higher bitrate): " crf
    172             ffmpeg -i "$1" -vcodec libx265 -crf "$crf" "${outfile:-optimised-$1}"
    173             return
    174           fi
    175         fi
    176         read -rp "CRF value (18..24, lower == higher bitrate): " crf
    177         ffmpeg -i "$1" -vcodec libx264 -crf "$crf" "${outfile:-optimised-$1}"
    178         break;;
    179       *)
    180         ;;
    181     esac
    182   done
    183 }
    184 main "$@"