story.sh
Код: Выделить всё
#!/bin/bash
# Проверка наличия аргументов
if [ -z "$1" ]; then
echo "Использование: $0 <видеофайл> [количество_кадров]"
exit 1
fi
INPUT_FILE="$1"
NUM_FRAMES="${2:-24}"
#OUTPUT_FILE="${INPUT_FILE%.*}_$(date +%Y.%m.%d_%H-%M-%S).jpg"
OUTPUT_FILE="${INPUT_FILE%.*}.jpg"
TEXT_PARAM="x=10:fontsize=16:fontcolor=white:boxcolor=black@0.6"
Y=10
Y_SMESHENIE=24 # Упростили расчет смещения
FILENAME=$(basename "$INPUT_FILE")
# 1. Получаем метаданные одним вызовом ffprobe (быстрее и надежнее)
metadata=$(ffprobe -v error -select_streams v:0 -show_entries stream=width,height,avg_frame_rate,duration,codec_name -show_entries format=size,bit_rate -of default=noprint_wrappers=1 "$INPUT_FILE")
width=$(echo "$metadata" | grep "^width=" | cut -d= -f2)
height=$(echo "$metadata" | grep "^height=" | cut -d= -f2)
fps_raw=$(echo "$metadata" | grep "^avg_frame_rate=" | cut -d= -f2)
duration=$(echo "$metadata" | grep "^duration=" | cut -d= -f2)
size=$(echo "$metadata" | grep "^size=" | cut -d= -f2)
#bit_rate=$(((echo "$metadata" | grep "^bit_rate=" | cut -d= -f2)/1024))
V_CODEC=$(echo "$metadata" | grep "^codec_name=" | cut -d= -f2)
#V_CODEC=$(ffprobe -v error -select_streams v:0 -show_entries stream=codec_name -of default=noprint_wrappers=1:nokey=1 "${INPUT_FILE}")
A_CODEC=$(ffprobe -v error -select_streams a:0 -show_entries stream=codec_name -of default=noprint_wrappers=1:nokey=1 "${INPUT_FILE}")
bit_v=$(($(ffprobe -v error -select_streams v:0 -show_entries stream=bit_rate -of default=noprint_wrappers=1:nokey=1 "${INPUT_FILE}")/1000))
bit_a=$(($(ffprobe -v error -select_streams a:0 -show_entries stream=bit_rate -of default=noprint_wrappers=1:nokey=1 "${INPUT_FILE}")/1000))
# 2. Математические расчеты
# Рассчитываем FPS для фильтра (равномерное распределение)
FPS_CALC=$(echo "scale=4; $NUM_FRAMES / $duration" | bc)
# Определяем сетку
COLUMNS=$(echo "sqrt($NUM_FRAMES)" | bc)
ROWS=$(echo "($NUM_FRAMES + $COLUMNS - 1) / $COLUMNS" | bc)
# Читаемый FPS (например, 24000/1001 -> 23.98)
if [[ "$fps_raw" == *"/"* ]]; then
FPS_VAL=$(echo "scale=2; ${fps_raw%/*} / ${fps_raw#*/}" | bc)
else
FPS_VAL=$fps_raw
fi
SIZE_MB=$(echo "scale=2; $size/1048576" | bc)
# Координаты строк текста (считаем в bash, чтобы не дергать bc лишний раз)
LINE1=$((Y + Y_SMESHENIE))
LINE2=$((Y + Y_SMESHENIE * 2))
LINE3=$((Y + Y_SMESHENIE * 3))
echo "Создание раскадровки для: $FILENAME"
echo "Длительность: $duration сек. Сетка: ${COLUMNS}x${ROWS}"
# 3. Запуск ffmpeg
# Важно: экранируем двоеточия в путях и именах файлов для drawtext
# Используем 'copy' для метаданных не нужно, рисуем фильтрами.
ffmpeg -v error -i "$INPUT_FILE" -frames:v 1 -vf \
"fps=$FPS_CALC,scale=320:-1,tile=${COLUMNS}x${ROWS}:padding=2,\
pad=iw:ih+80:0:80:color=gray,\
drawtext=text='File\: ${FILENAME//:/\\:}':y=${Y}:${TEXT_PARAM},\
drawtext=text='Res\: ${width}x${height}, fps\: $FPS_VAL, Size\: $SIZE_MB Mb':y=${LINE1}:${TEXT_PARAM},\
drawtext=text='Video\: ${V_CODEC}, ${bit_v} Kbp/s, Audio\: ${A_CODEC}, ${bit_a} Kbp/s':y=${LINE2}:${TEXT_PARAM}" \
-q:v 3 "$OUTPUT_FILE"
if [ $? -eq 0 ]; then
echo "Готово! Файл сохранен как: $OUTPUT_FILE"
else
echo "Произошла ошибка при обработке."
fi
Код: Выделить всё
./story.sh видеофайл