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 루프가 모든 파일 이름을 두 번째 파일 이름으로 덤프하기 때문에 출력은 "인수가 너무 많습니다"입니다 . 위쪽 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'

우리는 루프를 만드는 방법을 이미 알고 있으므로 첫 번째 루프 내에 중첩된 다른 루프를 추가해 보겠습니다. 자체적으로 모든 입력 행을 자신과 모든 쌍에 대해 두 번 일치시키므로 행은 이미 처리된 쌍을 건너뛰도록 계산됩니다.

#!/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

관련 정보