如何用FFmpeg递归扫描文件夹检测视频是否含软嵌字幕?
解决树莓派递归检测视频软嵌字幕的问题
核心解决方案(一行命令)
直接运行以下命令,替换/path/to/your/video/library为你的视频库根目录:
find /path/to/your/video/library -type f \( -iname "*.mp4" -o -iname "*.mkv" -o -iname "*.avi" \) -print0 | xargs -0 sh -c ' for file do # 用ffprobe检测是否存在字幕流(比ffmpeg更轻量) has_sub=$(ffprobe -v error -select_streams s -show_entries stream=codec_type -of default=noprint_wrappers=1:nokey=1 "$file") if [ -n "$has_sub" ]; then echo "0 $file" else echo "1 $file" fi done' sh
分步解释
处理带空格的文件名
find ... -print0:递归查找指定格式的视频文件,用null字符分隔文件名,彻底避免空格、特殊字符导致的文件名拆分问题xargs -0:读取null分隔的输入,确保每个文件名被完整传递给后续命令
字幕检测逻辑
ffprobe -v error:仅输出错误信息,屏蔽冗余日志-select_streams s:筛选所有字幕流(如果只检测第一个字幕流,用s:0)-show_entries stream=codec_type:仅提取流类型信息-of default=noprint_wrappers=1:nokey=1:简化输出格式,有字幕时返回subtitle,无字幕时返回空字符串- 通过判断返回值是否非空,输出
0(有字幕)或1(无字幕)+完整文件名
可选:封装为脚本
如果需要重复使用,可创建脚本文件check_subtitles.sh:
#!/bin/bash if [ $# -eq 0 ]; then echo "用法: $0 <视频库目录>" exit 1 fi find "$1" -type f \( -iname "*.mp4" -o -iname "*.mkv" -o -iname "*.avi" \) -print0 | xargs -0 sh -c ' for file do has_sub=$(ffprobe -v error -select_streams s -show_entries stream=codec_type -of default=noprint_wrappers=1:nokey=1 "$file") [ -n "$has_sub" ] && echo "0 $file" || echo "1 $file" done' sh
赋予执行权限并运行:
chmod +x check_subtitles.sh ./check_subtitles.sh /your/video/library
为什么之前的方案失败?
你之前的find方案大概率是直接用了-exec sh -c 'ffmpeg ... {}'这种写法,当文件名含空格时,会被拆分成多个参数传递给FFmpeg,导致FFmpeg找不到文件,最终统一返回1。而-print0 + xargs -0的组合能确保文件名被完整识别。
内容的提问来源于stack exchange,提问作者frosty
相关产品推荐
相关产品推荐

