86 lines
2.7 KiB
Bash
86 lines
2.7 KiB
Bash
#!/usr/bin/env bash
|
|
|
|
declare -rA presets=(
|
|
[davinci-resolve]="-c:v dnxhd -profile:v dnxhr_hq -pix_fmt yuv422p -c:a pcm_s16le"
|
|
[instagram]="-vf scale='if(gte(iw/ih,1),1920,-1)':'if(gte(iw/ih,1),-1,1920)' -pix_fmt yuv420p -c:v h264_nvenc -b:v 3500k -b:a 128k -c:a aac -movflags +faststart"
|
|
[web-generic]="-vf scale='if(gte(iw/ih,1),1920,-1)':'if(gte(iw/ih,1),-1,1920)' -pix_fmt yuv420p -c:v h264_nvenc -crf 23 -preset medium -c:a aac -b:a 128k -movflags +faststart"
|
|
[storage]="-c:v hevc_nvenc -preset p7 -b:v 0 -spatial-aq 1 -rc vbr_hq -c:a copy"
|
|
[whatsapp]="-vf scale='if(gte(iw/ih,1),1920,-1)':'if(gte(iw/ih,1),-1,1920)' -c:v h264_nvenc -preset slow -crf 30 -profile:v baseline -level 3.0 -pix_fmt yuv420p -r 25 -g 50 -c:a aac -b:a 160k -r:a 44100"
|
|
)
|
|
declare -rA containers=(
|
|
[davinci-resolve]="mov"
|
|
[instagram]="mp4"
|
|
[web-generic]="mp4"
|
|
[storage]="mp4"
|
|
[whatsapp]="mp4"
|
|
)
|
|
|
|
where="${1:-.}"
|
|
dest="${2:-$where}"
|
|
|
|
selection=$(find "$where" -type f | fzf --multi --preview 'ffprobe -v error -show_format -show_streams {}' --preview-window=up:wrap)
|
|
|
|
preset=$(
|
|
printf '%s\n' "${!presets[@]}" | \
|
|
fzf --multi --prompt "Select a preset"
|
|
)
|
|
flags="${presets[$preset]}"
|
|
container="${containers[$preset]}"
|
|
|
|
output_dir=$(find "$dest" -type d ! -name '.*' ! -path '*/.*/*' | fzf --preview 'tree -C {}' --preview-window=up:wrap --prompt "Select output directory: ")
|
|
|
|
if gum confirm "Flatten the directory structure?";
|
|
then
|
|
flatten=true
|
|
else
|
|
flatten=false
|
|
fi
|
|
|
|
|
|
function transcode_job {
|
|
local ifile="$1"
|
|
local output_dir="$2"
|
|
local flatten="$3"
|
|
local where="$4"
|
|
local flags="$5"
|
|
local container="$6"
|
|
local fname=$(basename "$ifile")
|
|
local segment=$(realpath --relative-to="$where" "$ifile")
|
|
|
|
|
|
if [ "$flatten" = true ]; then
|
|
output_file="$output_dir/$fname.$container"
|
|
else
|
|
output_file="$output_dir/$segment.$container"
|
|
fi
|
|
|
|
tmp_file=$(mktemp)
|
|
|
|
echo "Running Command: ffmpeg -y -i $ifile $flags $output_file" >> "$tmp_file"
|
|
|
|
mkdir -p "$(dirname "$output_file")"
|
|
|
|
if ffmpeg -y -i "$ifile" $(echo -n "$flags") "$output_file" 2>> "$tmp_file";
|
|
then
|
|
rm -f "$tmp_file"
|
|
else
|
|
# gum log "Failed to transcode $ifile. Check ./error.log for details."
|
|
cat "$tmp_file" >> error.log
|
|
rm -f "$tmp_file"
|
|
|
|
fi
|
|
}
|
|
export -f transcode_job
|
|
|
|
mapfile -t files <<< "$selection"
|
|
len=${#files[@]}
|
|
i=1
|
|
for file in "${files[@]}"; do
|
|
if [[ -f "$file" ]]; then
|
|
gum spin --spinner dot --title "[$i/$len] Transcoding $file" -- bash -c "source <(declare -f transcode_job); transcode_job \"$file\" \"$output_dir\" \"$flatten\" \"$where\" \"$flags\" \"$container\""
|
|
else
|
|
echo "Skipping invalid file: $file" >&2
|
|
fi
|
|
((i++))
|
|
done
|