임의의 시간 범위 내의 비디오에서 썸네일 만들기

임의의 시간 범위 내의 비디오에서 썸네일 만들기

저는 이 bash 스크립트를 사용하여 비디오에서 썸네일을 생성하고 있습니다.

#!/bin/bash
source_dir="."
output_dir="/output"
input_file_types=(avi wmv flv mkv mpg mp4)
output_file_type="jpg"
r1=$(( ( RANDOM % 10 )  + 5 ))

convert() {
        echo "" | ffmpeg -ss 00:"r1":05 -y -i "$1" -an -f image2 -vframes 1 "$output_dir/$2"
}

for input_file_type in "${input_file_types[@]}"
do
        find "$source_dir" -name "*.$input_file_type" -print0 | while IFS= read -r -d $'\0' in_file
        do
                echo "Processing…"
                echo ">Input  $in_file"

                # Replace the file type
                out_file=$(echo "$in_file" | sed "s/\(.*\.\)$input_file_type/\1$output_file_type/g")
                # The above can be shortened to
                # out_file="${in_file%.$input_file_type}.$output_file_type"
                echo ">Output $out_file"

                # Convert the file
                convert "$in_file" "$out_file"

                if [ $? != 0 ]
                then
                    echo "$in_file had problems" >> handbrake-errors.log
                fi

                echo ">Finished $out_file\n\n"
        done
done
echo "DONE CONVERTING FILES"

내가 원하는 것은 총 비디오 시간을 계산하고 임의의 비디오 시간에서 썸네일을 생성하는 것입니다.

mediainfo myvideo.mp4 | grep Duration
Duration                                 : 5mn 7s
Duration                                 : 5mn 7s
Duration                                 : 5mn 7s

grep Duration총 비디오 시간을 기준으로 임의의 시간에 썸네일을 얻을 수 있도록 위의 bash 스크립트에 어떻게 통합할 수 있습니까 ?

답변1

시간을 초 단위로 구해 보세요. 이렇게 하면 모든 것이 더 쉬워집니다.

변환 함수는 다음과 같을 수 있습니다.

convert() {
    # Get duration in milliseconds, then convert to seconds
    duration=$(($(mediainfo --Inform="General;%Duration%" "${in_file}" ) / 1000 ))

    # Calculate random time
    random_time=$(date -u -d @$(shuf -i 0-${duration} -n 1) +"%T")

    # Take screenshot
    ffmpeg -ss ${random_time} -i "$in_file" -vframes 1 -q:v 2 "$output_dir/$output_file"
}

답변2

이 bash는 할 것입니다

#!/bin/bash
source_dir="."
output_dir="."
input_file_types=(avi wmv flv mkv mpg mp4)
output_file_type="jpg"

convert() {
        echo "" | ffmpeg -ss $ss -y -i "$in_file" -an -f image2 -vframes 1 "$output_dir/$out_file"
}

for input_file_types in "${input_file_types[@]}"
do

        find "$source_dir" -name "*.$input_file_types" -print0 | while IFS= read -r -d $'\0' in_file
        do
                echo "Processing…"
                echo ">Input  "$in_file
                # Replace the file type
                out_file=$(echo $in_file|sed "s/\(.*\.\)$input_file_types/\1$output_file_type/g")
                echo ">Output "$out_file

    # get video duration
    fulltime=`ffmpeg -i "$in_file" 2>&1 | grep 'Duration' | cut -d ' ' -f 4 | sed s/,//`;
    hour=`echo $fulltime | cut -d ':' -f 1`;
    minute=`echo $fulltime | cut -d ':' -f 2`;
    second=`echo $fulltime | cut -d ':' -f 3 | cut -d '.' -f 1`;

    seconds=`expr 3600 \* $hour + 60 \* $minute + $second`;
    ss=`expr $seconds / 2`; # from the middle of video

    # Convert the file
                convert "$in_file" "$out_file"

                if [ $? != 0 ]
                then
                    echo "$in_file had problems" >> ffmpeg-errors.log
                fi

                echo ">Finished "$out_file "\n\n"
        done
done

동영상 중간부터 썸네일을 만듭니다.

답변3

비디오 길이:

DURATION=$(ffmpeg -i "$4" 2>&1 | grep "Duration"| cut -d ' ' -f 4 | sed s/,// | sed 's@\..*@@g' | awk '{ split($1, A, ":"); split(A[3], B, "."); print 3600*A[1] + 60*A[2] + B[1] }')
RES=$(ffmpeg -i "$4" 2>&1 | grep -oP 'Stream .*, \K[0-9]+x[0-9]+')

완전한 썸네일 생성기: https://github.com/romanwarlock/thumbnails/blob/master/thumbgen.sh

관련 정보