Skip to content

Instantly share code, notes, and snippets.

@alandbh
Last active August 25, 2025 18:45
Show Gist options
  • Save alandbh/e7894aaa9464980bb08dadecf3496048 to your computer and use it in GitHub Desktop.
Save alandbh/e7894aaa9464980bb08dadecf3496048 to your computer and use it in GitHub Desktop.
Bash Script For Compressing Videos
#!/bin/bash
# vcompress: comprime um vídeo encontrado por nome parcial.
# Uso:
# vcompress <nome-parcial> [--height <H>] [--crf <N>] [--noaudio]
#
# Padrões:
# --height <H> Altura do vídeo (padrão: 1440). Ex.: 720, 900, 1080, 1440
# --crf <N> Qualidade CRF (padrão: 20). 0–51 (menor = melhor)
# --noaudio Remove a trilha de áudio
#
# Saída: <nome-original>-comp.mp4
# ------------------------------------------
# Instalando como comando global vcompress
# ------------------------------------------
# Salve o script acima com o nome vcompress (sem .sh).
# Torne-o executável com o comando:
# chmod +x vcompress
# Mova para um diretório no seu PATH, por exemplo:
# sudo mv vcompress /usr/local/bin/
# Agora você pode usar de qualquer lugar:
# vcompress parte-do-nome
set -e
if [ -z "$1" ] || [[ "$1" == "--help" ]]; then
grep "^# " "$0" | sed 's/^# //'
exit 1
fi
pattern="$1"; shift
height=1440
crf=20
audio_opts="-c:a aac -b:a 128k" # padrão com áudio
# parse de flags simples
while [[ $# -gt 0 ]]; do
case "$1" in
--height)
height="$2"; shift 2 ;;
--crf)
crf="$2"; shift 2 ;;
--noaudio)
audio_opts="-an"; shift ;;
*)
echo "Opção desconhecida: $1"; exit 1 ;;
esac
done
# força altura par (múltiplo de 2) para evitar erros no x264
if [ $((height % 2)) -ne 0 ]; then
height=$((height + 1))
fi
# encontra o arquivo (respeita espaços no nome)
file=$(find . -maxdepth 1 -type f -iname "*$pattern*" | head -n 1 | sed 's|^\./||')
if [ -z "$file" ]; then
echo "Arquivo não encontrado com o padrão: $pattern"
exit 1
fi
base="${file%.*}"
output="${base}-comp.mp4"
# --- obtém FPS original com ffprobe (fração) ---
get_fps_fraction() {
local f="$1"
local fps
fps=$(ffprobe -v error -select_streams v:0 -show_entries stream=avg_frame_rate \
-of default=nokey=1:noprint_wrappers=1 "$f" || true)
if [ -z "$fps" ] || [ "$fps" = "0/0" ]; then
fps=$(ffprobe -v error -select_streams v:0 -show_entries stream=r_frame_rate \
-of default=nokey=1:noprint_wrappers=1 "$f" || true)
fi
if [ -z "$fps" ] || [ "$fps" = "0/0" ]; then
fps="30"
fi
echo "$fps"
}
fps_frac=$(get_fps_fraction "$file")
echo "▶️ Entrada : $file"
echo "🎯 Altura : ${height}px"
echo "🎞 FPS : $fps_frac (CFR)"
echo "🎚 CRF : $crf"
echo "🔈 Áudio : $([ "$audio_opts" = "-an" ] && echo "removido" || echo "AAC 128k")"
echo "💾 Saída : $output"
echo
# encode robusto (corrige PTS/DTS, preserva FPS em CFR, compatibilidade de pixel format)
ffmpeg -hide_banner -loglevel info -fflags +genpts \
-vsync cfr -r "$fps_frac" \
-i "$file" \
-vf "scale=-2:${height}" \
-c:v libx264 -crf "$crf" -preset slow -pix_fmt yuv420p \
$audio_opts \
-af $([ "$audio_opts" = "-an" ] && echo "anull" || echo "aresample=async=1") \
-movflags +faststart -avoid_negative_ts make_zero \
"$output"
echo "✅ Compressão finalizada: $output"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment