私が使用したいffmpeg
機能は、signature
テキストファイルにリストされている何千ものビデオファイルに対して繰り返し分析を実行しますvids.list
。各ファイルを他のファイルと比較し、リスト内の対応する行を削除するには、このファイルが必要です。これまでに私が持っていたものは次のとおりです。
#!/bin/bash
home="/home/user/"
declare -i lineno=0
while IFS="" read -r i; do
/usr/bin/ffmpeg -hide_banner -nostats -i "${i}" -i "$(while IFS="" read -r f; do
echo "${f}"
done < ${home}/vids.list)" \
-filter_complex signature=detectmode=full:nb_inputs=2 -f null - < /dev/null
let ++lineno
sed -i "1 d" ${home}/vids.list
done < vids.list 2> ${home}/out.log
ffmpeg
内部whileループはすべてのファイル名を2番目のファイル名にダンプするため、出力は「引数が多すぎます」です。上のwhileループが完了している間にループを開いたままにするためにどこか(またはフォーマットオプション)が-i
必要かどうかはわかりません。wait
明確にするために、パスを含むテキストファイルの行1から始まり、そのファイルを行2、3、4...2000(または何でも)のファイルと比較し、行1を削除して続行するループが必要です。
答え1
正確なコマンドを避けながら、このようなことをしたいとします(明らかな4行の入力を含む)。
$ bash looploop.sh
run ffmpeg with arguments 'alpha' and 'beta'
run ffmpeg with arguments 'alpha' and 'charlie'
run ffmpeg with arguments 'alpha' and 'delta'
run ffmpeg with arguments 'beta' and 'charlie'
run ffmpeg with arguments 'beta' and 'delta'
run ffmpeg with arguments 'charlie' and 'delta'
私たちはすでにループを作成する方法を知っているので、最初のループ内に入れ子になった別のループを追加しましょう。独自にすべての入力行を自分とすべてのペアに対して2回一致させるので、行はすでに処理されているペアをスキップするように計算されます。
#!/bin/bash
i=0
while IFS= read a; do
i=$((i + 1))
j=0
while IFS= read b; do
j=$((j + 1))
if [ "$j" -le "$i" ]; then continue; fi
# insert the actual commands here
printf "run ffmpeg with arguments '%s' and '%s'\n" "$a" "$b"
done < vids.list
done < vids.list
または、前述したように、外部ループから処理された行を削除します。これは実際には短いです。
#!/bin/bash
cp vids.list vids.list.tmp
while IFS= read a; do
while IFS= read b; do
if [ "$a" = "$b" ]; then continue; fi
# insert the actual commands here
printf "run ffmpeg with arguments '%s' and '%s'\n" "$a" "$b"
done < vids.list.tmp
sed -i '1d' vids.list.tmp
done < vids.list.tmp
rm vids.list.tmp
スクリプト内の「パラメータが多すぎます」の原因が正確に何であるかはわかりませんが、パラメータは-i
内部にコマンド置換のみを含む二重引用符で囲まれた文字列なので、次のように渡されます。一つパラメータffmpeg
(改行文字を含むecho
)。あまりにも多くの議論につながるべきではありません。
答え2
これはどうですか?
readarray -t arr < file
counter=1
for i in "${arr[@]}"; do
for k in "${!arr[@]}"; do
if [[ ! -z "${arr[$k+$counter]}" ]]; then
f1="${i}"
f2="${arr[$k+$counter]}"
ffmpeg -hide_banner -nostats -i "${f1}" -i "${f2}" -filter_complex signature=detectmode=full:nb_inputs=2 -f null - < /dev/null
else
break
fi
done
(( counter++ ))
done