comment puis-je extraire de la vidéo en utilisant ffmpeg avec des informations d'horodatage


2

J'utilise ffmpeg pour extraire une image et l'enregistrer dans un fichier jpg comme suit.

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

Cependant, comment puis-je obtenir les informations d'horodatage de chaque image extraite. Par exemple, je voudrais enregistrer le fichier jpg avec le nom de fichier sous le nom hh_mm_ss.jpg?


Jetez un oeil à cette question posée sur Stack Overflow. La réponse acceptée fournit une solution de contournement à l'aide d'ImageMagick, car FFmpeg n'est pas capable de le faire lui-même.
— Nick van Tilborg

@NickvanTilborg Je pense que la question demande des horodatages pris dans la vidéo (PTS, Presentation Time Stamp) - de sorte qu'une image prise à une minute 30 secondes dans la vidéo aurait un nom de fichier comme 00_01_30.jpg- plutôt que l'horodatage de l'heure système à laquelle le fichier a été créé.
— Evilsoup

Ah oui, mais alors un simple script de changement de nom devrait faire l'affaire. @MinSun, pouvez-vous s'il vous plaît confirmer ce que vous voulez?
— Nick van Tilborg

J'ai la même question, précisément ce que je crois qu'il demande (comme je le suis) pour l'horodatage de la vidéo, c'est-à-dire qu'une image prise 20 secondes après dans la vidéo aurait un nom de fichier avec: image-00_20_00.jpg
— davidparks21

Réponses:


1

Eh bien, il semble que ffmpeg ne puisse pas gérer cela (pas plus que d’autres solutions populaires telles que VLC Media Player). Une solution de contournement que j'ai utilisée consiste à obtenir la durée de la vidéo ffmpeg -i video_file.mp4et à la diviser par le nombre d'images.

À titre d'exemple, voici un script bash que j'ai écrit: le traitement par lots traite un ensemble de vidéos, les divise en images (@ 30 ips) et renomme les fichiers afin qu'ils aient à la fois l'horodatage de la vidéo (en millisecondes à compter du début de la vidéo) et le numéro de l'image. à l'origine.

Je suis sûr que le script pourrait être plus efficace, mais il fonctionne assez bien pour mes besoins, donc j'espère qu'il trouvera une utilisation (puisque cette question est à venir dans les recherches sur 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;
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.