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

問題は、avconvtherein の呼び出しごとにエラーが発生することです。これを無視して、必要な情報を抽出します。これは少々見苦しい解決策です。あなたの方法が私の方法と同じかどうかはよくわかりません。他の正規表現に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: ファイル読み取りエラー」というメッセージのみが表示されます。

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

前述したように、「if」構文は機能します (実際のディレクトリに対して) が、find でも実行できるようにしてみます。

関連情報