2

Я использую ffmpeg, чтобы извлечь кадр и сохранить его в JPG-файлах следующим образом.

ffmpeg -i video.avi -r 1 -f image2 -q 1 %05d.jpg

Тем не менее, как я могу получить информацию о временных метках каждого извлеченного кадра. Например, я хотел бы сохранить файл jpg с именем файла как hh_mm_ss.jpg?

1 ответ1

1

Что ж, похоже, ffmpeg не может справиться с этим (как и другие популярные решения, такие как VLC media player). Обходное решение, которое я использовал, это получить длительность видео из ffmpeg -i video_file.mp4 и разделить ее на количество кадров.

Для справки и примера вот сценарий bash, который я написал: пакетная обработка обрабатывает набор видео, разбивает их на кадры (@ 30 кадров в секунду) и переименовывает файлы, чтобы у них была и метка времени видео (в миллисекундах от начала видео), и номер кадра первоначально.

Я уверен, что сценарий может быть более эффективным, но он работает достаточно хорошо для моих целей, поэтому, надеюсь, он найдет применение (так как этот вопрос возникает в поиске Google):

# Regular expression definitions to get frame number, and to get video duration from ffmpeg -i
FRAME_REGEX="frame-([0-9]*)\.jpeg"
LEN_REGEX="Duration: ([0-9]*):([0-9]*):([0-9]*)\.([0-9]*), start"

# Loops through the files passed in command line arguments, 
# example: videotoframes video-*.mp4
#      or: videotoframes file1.mp4 file2.mp4 file3.mp4
for vf in "$@"; do
    video_info=$(ffmpeg -i $vf 2>&1)                                                                                                                        # Get the video info as a string from ffmpeg -i
    [[ $video_info =~ $LEN_REGEX ]]                                                                                                                         # Extract length using reges; Groups 1=hr; 2=min; 3=sec; 4=sec(decimal fraction)
    LENGTH_MS=$(bc <<< "scale=2; ${BASH_REMATCH[1]} * 3600000 + ${BASH_REMATCH[2]} * 60000 + ${BASH_REMATCH[3]} * 1000 + ${BASH_REMATCH[4]} * 10")          # Calculate length of video in MS from above regex extraction

    mkdir frames-$vf                                                # Make a directory for the frames (same as the video file prefixed with "frames-"
    ffmpeg -i $vf -r 30 -f image2 frames-$vf/frame-%05d.jpeg        # Convert the video file to frames using ffmpeg, -r = 30 fps
    FRAMES=$(ls -1 frames-$vf | wc -l)                              # Get the total number of frames produced by the video (used to extrapolate the timestamp of the frame in a few lines)

    # Loop through the frames, generate a timestamp in milliseconds, and rename the files
    for f in frames-$vf/frame-*; do
        [[ $f =~ $FRAME_REGEX ]]                                                        # Regex to grab the frame number for each file
        timestamp=$(bc <<< "scale=0; $LENGTH_MS/$FRAMES*${BASH_REMATCH[1]}")            # Calculate the timestamp (length_of_video / total_frames_generated * files_frame_number)
        `printf "mv $f frames-$vf/time-%07d-%s" $timestamp $(basename $f)`              # Execute a mv (move) command, uses the `printf ...` (execute command returned by printf) syntax to zero-pad the timestamp in the file name
    done;
done;

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .