Linux: 정확히 720p 해상도의 모든 비디오 파일을 나열하는 방법은 무엇입니까?

Linux: 정확히 720p 해상도의 모든 비디오 파일을 나열하는 방법은 무엇입니까?

해상도가 다른 여러 개의 비디오 파일이 있습니다. 이제 예를 들어 720p 해상도의 비디오 파일 이름만 나열하고 싶습니다. 나는 bash 명령줄에서 하나의 라이너를 선호하며 다음을 실행할 때 해상도를 포함한 유용한 비디오 정보를 받을 수 있습니다.

avconv -i video.mp4

하지만 이 조합은:

find -exec sh -c 'if [[ "$(avconv -i {}") == *720* ]] ; then echo 720 found; fi;'

오류가 발생합니다: exec - 인수가 누락되었습니다.

솔직히 말해서 나는 bash 명령 구조, 특히 결합 명령과 거의 싸우지 않습니다. 그렇다면 결합된 명령 문자열에 어떤 문제가 있습니까?

감사합니다.

답변1

어쩌면 이 명령이 당신이 찾고 있는 것을 성취할 수도 있습니다:

for i in *.mp4; do if [[ $(avconv -i $i) =~ .*720.* ]]; then echo $i; fi; done

답변2

놀랄 수도 있지만 호출 -exec시 테스트로 사용할 수 있습니다 .find

find -type f -exec sh -c 'ffprobe -show_streams 2>/dev/null "$1" | grep -q coded_height=720' sh {} \; -print

위 명령은 하위 디렉터리로 내려갑니다. 현재 디렉토리에서만 검색하려면 -maxdepth 1다음과 같이 사용하십시오.

find -maxdepth 1 -type f -exec …

모든 파일을 테스트 합니다 ffprobe. 미디어가 아닌 파일의 경우 분명히 실패하지만 .jpg최종 출력에는 비디오가 아닌 미디어(예: )가 나타날 수 있습니다. 이를 방지하려면 의 몇 가지 추가 테스트를 find전에 사용해야 합니다 -exec. 예:

find -maxdepth 1 -type f \( -iname "*.avi" -o -iname "*.mp4" -o -iname "*.mkv" \) -exec sh -c 'ffprobe -show_streams 2>/dev/null "$1" | grep -q coded_height=720' sh {} \; -print

또는 다음을 사용하여 MIME 유형을 테스트하는 것이 더 좋습니다 file.

find -maxdepth 1 -exec sh -c 'file --mime-type "$1" | grep -q "video/"' sh {} \; -exec sh -c 'ffprobe -show_streams 2>/dev/null "$1" | grep -q coded_height=720' sh {} \; -print

man find자세히 알아보려면 읽어보세요 .


편집하다:

이 명령은 avconv요청한 대로 를 (잘못) 사용합니다.

find -exec sh -c 'file --mime-type "$1" | grep -q "video/"' sh {} \; -exec sh -c 'avconv 2>&1 -i "$1" | grep -q "Stream.*x720"' sh {} \; -print

문제는 호출할 때마다 avconv오류가 발생한다는 것입니다. 우리는 그것을 무시하고 필요한 정보를 추출합니다. 이것은 다소 추악한 해결책입니다. 나는 당신이 내 것처럼 행동하는지 완전히 확신하지 못합니다 . 다른 정규식으로 avconv바꿔야 할 수도 있습니다 .Stream.*x720


내 결합된 명령 문자열에 무슨 문제가 있나요?

  • find -exec\;또는 로 닫아야 합니다 +.
  • $()질문을 편집한 후에 는 "" 인터리브(중첩되지 않음) 되어 있습니다$() .
  • *720*쉘 글로빙을 유발할 수 있습니다. ( 외부 쉘이 아니라 "*720*"에 대해 이야기하고 있습니다 .)sh
  • avconv구문 분석을 시도한 결과는 다음과 같습니다 stderr. 구문 분석하기 전에 리디렉션해야 한다고 생각합니다.
  • 그리고 아마도 다른 것일 수도 있습니다.

답변3

나는 avconv를 모르고 보통 ffmpeg를 사용합니다. 설치하면 이 스크립트를 사용할 수 있습니다

#!/bin/bash
OIFS="$IFS"
IFS=$'\n'

files=$(find ./ -type f -exec ls {} + | grep ".*\.mpg$\|.*\.avi$\|.*\.mkv$\|.*\.mp4$"| cut -c3-)

for f in ${files}
do
resolution=$(ffprobe -v error -select_streams v:0 -show_entries 
stream=height -of csv=s=x:p=0 ${f})
printf "%-100s %-10s\n" $f $resolution
done

답변4

지금은 유용한 솔루션을 찾았습니다.

 for i in ls *.m??; do sm=$(mediainfo $i | grep Height | sed 's/  //g');if [[ "$sm" == *720* ]]; then printf "Video: %-s $i %-s $sm \n"; fi; done

여기에서 모든 m을 반복할 수 있나요?? 비디오 파일을 선택하고 "720" 조건을 포함하여 이름을 인쇄합니다. if 부분이 없으면 모든 비디오와 해당 해상도를 표시할 수 있습니다.

나는 여기의 다른 답변의 도움으로 이것을 해결했습니다.

위 솔루션의 find, exec 및 do 부분을 결합하려고 하면 각 주제에 대한 mediainfo의 결과로 "E: File read error" 메시지만 수신됩니다.

 find -exec mediainfo "{}" \; -exec bash -c 'sm=$(mediainfo ${} | grep 720) : ; echo $sm' \;

내가 말했듯이 'if' 구성은 (실제 디렉토리에 대해) 작동하지만 find로도 실행되도록 노력할 것입니다.

관련 정보