Last active
August 25, 2025 18:45
-
-
Save alandbh/e7894aaa9464980bb08dadecf3496048 to your computer and use it in GitHub Desktop.
Bash Script For Compressing Videos
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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