ffmpeg処理にネストされたwhileループを使用する

ffmpeg処理にネストされたwhileループを使用する

私が使用したい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

関連情報