for f in *.mp4 *.mkv *.MP4; do ffmpeg -n -i "$f" -c:v libx264 -preset ultrafast -crf 30 -vf "scale=-2:480,fps=25" -c:a copy -threads 0 -vsync cfr "${f%.*}_proxy.mp4"; done
Jeśli ktoś ma kartę NVIDII, może użyć -c:v h264_nvenc
albo w przypadku kart AMD – -c:v h264_amf
i użyć mocy obliczeniowej karty graficznej zamiast katować CPU
Tylko wtedy trzeba wywalić -crf 30
które jest specyficzne dla libx264
Nie wiem, jak to wygląda w przypadku AMD, ale w przypadku NVIDIA z pewnością potrzebujemy ffmpeg-full
, zamiast ffmpeg-free
, bo ich encoder jest zamknięty.
Akurat ten one-liner jest odpalany na montażu odcinków ICD, gdzie proxy muszą być generowane przez CPU, bo dostępna jest tylko integra Intela 620, ale tak zgadzam się z Tobą
W przypadku macOSa można jeszcze
-hwaccel videotoolbox -c:v h264_videotoolbox
a w przypadku intela
-hwaccel vaapi -hwaccel_output_format vaapi -vaapi_device /dev/dri/renderD128 -c:v h264_vaapi
Poprawiony one-liner z użyciem vaapi i generowaniem CFR 480p dla Kdenlive. Na intelu czas speed skoczył dla referencyjnego pliku (1080p 25 fps 8 Mbit/s nagranego OBSem) z 3-4x na 17.5x
for f in *.mp4 *.mkv; do \
fps=$(ffprobe -v 0 -of csv=p=0 -select_streams v:0 -show_entries stream=r_frame_rate "$f" | awk -F'/' '{print $1/$2}'); \
ffmpeg -n -hwaccel vaapi -hwaccel_output_format vaapi -vaapi_device /dev/dri/renderD128 \
-i "$f" -vf "scale_vaapi=w=-2:h=480,fps=$fps" -c:v h264_vaapi -b:v 2M -c:a copy -vsync cfr "${f%.*}_proxy.mp4"; \
done
config:
Tutaj mam skrypt do skalowania, który automatycznie wykrywa dostępne przyspieszanie sprzętowe i skaluje film:
#!/usr/bin/env bash
set -x
set -euo pipefail
if [[ $# -lt 1 ]]; then
echo "Usage: $0 <video_file> [vertical_resolution]"
exit 1
fi
INPUT="$1"
RESOLUTION="${2:-720}"
BASENAME="${INPUT%.*}"
EXT="${INPUT##*.}"
OUTPUT="${BASENAME}.${RESOLUTION}p.${EXT}"
# Candidate encoders in priority order
CANDIDATES=(h264_nvenc hevc_nvenc h264_vaapi h264_qsv libx264)
# Function: test if encoder works
encoder_works() {
local enc="$1"
# VAAPI needs special handling
if [[ "$enc" == "h264_vaapi" ]]; then
ffmpeg -hide_banner -loglevel error -vaapi_device /dev/dri/renderD128 \
-f lavfi -i testsrc2=size=128x128:rate=1 -t 1 \
-vf 'format=nv12,hwupload' -c:v "$enc" -f null - >/dev/null 2>&1
else
ffmpeg -hide_banner -loglevel error \
-f lavfi -i testsrc2=size=128x128:rate=1 -t 1 \
-c:v "$enc" -f null - >/dev/null 2>&1
fi
}
VIDEO_CODEC="libx264"
for enc in "${CANDIDATES[@]}"; do
if encoder_works "$enc"; then
VIDEO_CODEC="$enc"
break
fi
done
echo "Using encoder: $VIDEO_CODEC"
# Filters / opts
EXTRA_OPTS=()
if [[ "$VIDEO_CODEC" == "h264_vaapi" ]]; then
EXTRA_OPTS=(-vaapi_device /dev/dri/renderD128 -vf "format=nv12,hwupload,scale_vaapi=-2:${RESOLUTION}")
else
EXTRA_OPTS=(-vf "scale=-2:${RESOLUTION}")
fi
ffmpeg -y -i "$INPUT" "${EXTRA_OPTS[@]}" -c:v "$VIDEO_CODEC" -c:a copy "$OUTPUT"
jeszcze możnaby wzbogacić o przyspieszenie sprzętowe videotoolbox