![ffmpeg bash脚本段模板](https://linux22.com/image/8279/ffmpeg%20bash%E8%84%9A%E6%9C%AC%E6%AE%B5%E6%A8%A1%E6%9D%BF.png)
我试图通过 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
这实现了我需要它做的事情。