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获得非视频媒体(如)。为避免这种情况,应在之前使用一些额外的测试,例如:.jpgfind-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*可能会触发 shell 通配符,应该是"*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 一起运行。

相关内容