Раскадровка видео в jpg (скринлист)

Ответить
ya
^-^
Сообщения: 3102
Зарегистрирован: 16 дек 2021, 19:56

Раскадровка видео в jpg (скринлист)

Сообщение ya »

Раскадровка видео в jpg (скринлист)

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 видеофайл
ya
^-^
Сообщения: 3102
Зарегистрирован: 16 дек 2021, 19:56

Re: Раскадровка видео в jpg (скринлист)

Сообщение ya »

Раскадровка с превью-изображениями в отдельном каталоге

story2.sh

Код: Выделить всё

#!/bin/bash

if [ -z "$1" ]; then
    echo "Использование: $0 <видеофайл> [количество_кадров_сетки]"
    exit 1
fi

INPUT_FILE="$1"
NUM_FRAMES="${2:-24}"
# Основной файл раскадровки
OUTPUT_FILE="${INPUT_FILE%.*}.jpg"
# Папка для больших кадров
BIG_FRAMES_DIR="${INPUT_FILE%.*}"

TEXT_PARAM="x=10:fontsize=18:fontcolor=white:boxcolor=black@0.6"
Y=10
Y_SMESHENIE=24
FILENAME=$(basename "$INPUT_FILE")

# 1. Получаем метаданные
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)
V_CODEC=$(echo "$metadata" | grep "^codec_name=" | cut -d= -f2)

A_CODEC=$(ffprobe -v error -select_streams a:0 -show_entries stream=codec_name -of default=noprint_wrappers=1:nokey=1 "${INPUT_FILE}" 2>/dev/null || echo "none")
bit_v=$(($(ffprobe -v error -select_streams v:0 -show_entries stream=bit_rate -of default=noprint_wrappers=1:nokey=1 "${INPUT_FILE}" 2>/dev/null || echo 0)/1000))
bit_a=$(($(ffprobe -v error -select_streams a:0 -show_entries stream=bit_rate -of default=noprint_wrappers=1:nokey=1 "${INPUT_FILE}" 2>/dev/null || echo 0)/1000))

# Расчеты для текста
LINE1=$((Y + Y_SMESHENIE))
LINE2=$((Y + Y_SMESHENIE * 2))
SIZE_MB=$(echo "scale=2; $size/1048576" | bc)
FPS_VAL=$(echo "scale=2; ${fps_raw%/*} / ${fps_raw#*/}" | bc)

# Общая строка фильтра для текста (чтобы не дублировать)
DRAW_TEXT="pad=iw:ih+80:0:80:color=darkgray, \
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}"

# --- 1. Создание основной сетки (Storylink) ---
COLUMNS=$(echo "sqrt($NUM_FRAMES)" | bc)
ROWS=$(echo "($NUM_FRAMES + $COLUMNS - 1) / $COLUMNS" | bc)
FPS_CALC=$(echo "scale=4; $NUM_FRAMES / $duration" | bc)

echo "Создание раскадровки (сетка $COLUMNS x $ROWS)..."
ffmpeg -v error -i "$INPUT_FILE" -frames:v 1 -vf \
    "fps=$FPS_CALC,scale=320:-1,tile=${COLUMNS}x${ROWS}:padding=2,$DRAW_TEXT" \
    -q:v 3 "$OUTPUT_FILE"

# --- 2. Создание больших кадров (Big Frames) ---
echo "Создание больших кадров..."
mkdir -p "$BIG_FRAMES_DIR"

# Выбираем 20 временных меток (на 10%, 30%, 50%, 70%, 90% длительности)
for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20; do
    TIMESTAMP=$(echo "scale=2; $duration * $i / 20" | bc)
    OUT_BIG="$BIG_FRAMES_DIR/${i}.jpg"
    TIME1=$(date -u -d @"$TIMESTAMP" +%H\:%M\:%S)

    # Извлекаем конкретный кадр с той же плашкой
    #ffmpeg -v error -ss "${TIMESTAMP}" -i "${INPUT_FILE}" -frames:v 1 -vf "${DRAW_TEXT}" -q:v 2 "{$OUT_BIG}"
    ffmpeg -y -v error -ss "$TIMESTAMP" -i "$INPUT_FILE" -frames:v 1 -vf "$DRAW_TEXT,drawtext=text=\'$TIME1\':fontcolor=black:box=1:boxcolor=white@1:boxborderw=2:fontsize=16:x=(w-tw)-(lh):y=h-(2*lh)" -q:v 2 "$OUT_BIG"
done

#,drawtext=font='Courier New':text='${TIMESTAMP}':fontcolor=black:shadowcolor=white:shadowx=1:shadowy=1:fontsize=16:x=w-tw-10:y=h-th-10

echo "Готово!"
echo "Сетка: $OUTPUT_FILE"
echo "Большие кадры в папке: $BIG_FRAMES_DIR"

Ответить