ffmpeg bash 스크립트 스니펫 템플릿

ffmpeg bash 스크립트 스니펫 템플릿

큰 영화 파일을 작은 조각으로 자르기 위해 bash 스크립트를 통해 ffmpeg 파일 분할 기능을 제어하려고 합니다.

나는 살펴보았다여기 문서하지만 그것은 내가 하고 싶은 일을 실제로 다루지는 않습니다.

bash에서 세그먼트 기능을 내 자신의 일부 기능과 혼합하고 싶습니다. 이것은 스크립트의 예시 부분입니다.

#!/bin/bash
DIR="/../../*"
OUT_DIR="/../../"
file_extension=""
filename=""
input_file=""
input_file_dir=""
output_file=""
working_directory=""
output_file_dir=""
part_count=0
for f in $DIR
do
    filename=$(basename "$f")
    input_file="$filename"
    filename=${filename::-4}
    file_extension=${f: -3}
    input_file_dir=$(dirname "$f")"/"
    part_count="$(printf "%03d" "$counter")"
    output_file="$filename"_"$part_count"."$file_extension
    //my file name generation takes place here
    output_file_dir="$OUT_DIR$filename"_"$part_count".mkv"
    let part_count=$part_count+1

    ffmpeg -i "$f" -c:v libx264 -crf 22 -map 0 -strict -2 -segment_time 600 -g 9 -sc_threshold 0 -force_key_frames "expr:gte(t,n_forced*9)" -f segment "$OUT_DIR"
done

"$OUT_DIR" 위 줄은 작동하지 않으며 알 수 없는 오류가 발생합니다. "$OUT_DIR"을 제거하고 "test.mkv"와 같은 것을 넣으면 파일은 올바르게 기록되지만 잘못된 위치에 기록됩니다.

ffmpeg 준비 명령과 bash를 사용하여 이 작업을 수행할 수 있나요?

답변1

글쎄요, 저는 그것을 알아냈고 대본을 처음부터 다시 썼습니다.

#!/bin/bash
DIR="/../../../*" #directory where the movie files are located
OUT_DIR="/../../../../" #directory where the processed movie files will be exported
OUTPUT_FILE=""

file_duration_flat=0
file_duration_int=0
working_file_duration=0
default_chunk_size=600 #video length in seconds (10 minutes)
chunk_size=600 #video length in seconds (10 minutes)
video_pieces=0
video_pieces_hum_re=0
video_pieces_hum_re_cnt=0
counter=0
chunk_start_time=0
chunk_end_time=0
tt=10
end=10
iteration=0

#extract simple metadata from files
for f in $DIR
do
    echo $f
    file_duration_float=$(ffprobe -i "$f" -show_format -v quiet | sed -n 's/duration=//p')
    file_duration_int=$( echo "($file_duration_float+0.5)/1" | bc )
    working_file_duration_int=$file_duration_int
    working_file_duration=$(expr $file_duration_int - $chunk_size )
    echo $file_duration_int

    #---------------------------------------------
    # get the count of pieces to cut the file into
    #---------------------------------------------
    # echo $working_file_duration_int
    while [ "$working_file_duration_int" -ge "$chunk_size" ]
    do
        working_file_duration_int=$(($working_file_duration_int - chunk_size))
        video_pieces=$((video_pieces + 1 ))
        video_pieces_hum_re=$((video_pieces + 1 ))
        video_pieces_hum_re_cnt=$video_pieces_hum_re

        # echo "cut video into $video_pieces pieces"
        # echo "cut video into human readable $video_pieces_hum_re pieces"
        # echo "cut video human readable c $video_pieces_hum_re_cnt pieces"
    done
    #---------------------------------------------

    #---------------------------------------------
    # determine the start and end time of each clip
    #---------------------------------------------
    while [ $working_file_duration_int -gt -1 ]
    do
        filename=$(basename "$f")
        input_file="$filename"
        filename=${filename::-4}" "
        file_extension=${f: -3}
        input_file_dir=$(dirname "$f")"/"


        if [ $iteration -eq 0 ]
        then
            working_file_duration_int=$((file_duration_int - chunk_size))
            chunk_start_time=0
            chunk_end_time=$(($default_chunk_size))

            echo "iteration $iteration start: $chunk_start_time end: $chunk_end_time duration: $default_chunk_size video length left $working_file_duration_int"

            OUTPUT_FILE="$OUT_DIR$filename$iteration.mkv"
            $(ffmpeg -hide_banner -loglevel panic -i "$f" -ss $chunk_start_time -t $chunk_end_time [youre desired encoding] "$OUTPUT_FILE")
            iteration=$((iteration+1))
        fi
        if [ $working_file_duration_int -le $chunk_size ]
        then
            # echo "break early because time is $working_file_duration_int"
            chunk_size=$working_file_duration_int
            working_file_duration_int=$((working_file_duration_int - chunk_size))
            chunk_start_time=$(($chunk_start_time+$chunk_end_time))
            chunk_end_time=$(($chunk_size))

            # echo "early chunk size: $chunk_size iteration $iteration video length left $working_file_duration_int start: $chunk_start_time end: $chunk_end_time"
            echo "early chunk size: $chunk_size iteration $iteration start: $chunk_start_time end: $((chunk_start_time+chunk_end_time)) duration: $chunk_end_time video length left $working_file_duration_int "

            OUTPUT_FILE="$OUT_DIR$filename$iteration.mkv"
            $(ffmpeg -hide_banner -loglevel panic -i "$f" -ss $chunk_start_time -t $chunk_end_time [youre desired encoding] "$OUTPUT_FILE")
            iteration=0
            chunk_size=$default_chunk_size
            break
        else
            chunk_start_time=$(($chunk_start_time+$chunk_end_time))
            chunk_end_time=$(($chunk_size))
            working_file_duration_int=$((working_file_duration_int - chunk_size))
            echo "iteration $iteration start: $chunk_start_time end: $((chunk_start_time+chunk_end_time)) duration: $chunk_end_time video length left $working_file_duration_int "

            OUTPUT_FILE="$OUT_DIR$filename$iteration.mkv"
            $(ffmpeg -hide_banner -loglevel panic -i "$f" -ss $chunk_start_time -t $chunk_end_time [youre desired encoding] "$OUTPUT_FILE")
            iteration=$((iteration+1))
        fi
    done
done

이것은 내가 해야 할 일을 성취합니다.

관련 정보