【问题标题】:Quickly check the integrity of video files inside a directory with ffmpeg [closed]使用ffmpeg快速检查目录内视频文件的完整性[关闭]
【发布时间】:2022-01-09 19:21:28
【问题描述】:

我正在拼命寻找一种方便的方法来检查包含文件夹的特定目录中 .mp4 文件的完整性。 .mp4 文件和文件夹的名称都包含空格、特殊字符和数字。

我已经找到了一个合适的 ffmpeg 命令来快速识别损坏的 .mp4 文件,取自 hereffmpeg -v error -i filename.mp4 -map 0:1 -f null - 2>error.log

如果创建的 error.log 包含一些条目,则该文件显然已损坏。反之则为空的 error.log。

下一步是将此命令应用于文件夹及其子文件夹中的每个 .mp4 文件。一些指南,如herehere,确实描述了如何递归应用 ffmpeg 命令,但我的编码能力有限,因此我无法找到组合这些命令以获得以下结果的方法:

一种使用上述 ffmpeg 命令(递归)测试文件夹内所有 .mp4 文件的方法,该命令应该创建 .log 文件,前提是视频文件确实包含错误(读取的内容有一些)并且它应该继承名称损坏的文件,以了解哪个文件已损坏。

使用 Ubuntu Gnome 15.10。

【问题讨论】:

  • 您需要批处理脚本 (Windows) 还是 shell 脚本 (Unix)?
  • 一个 shell 脚本,因为我使用的是 Ubuntu Gnome 15.10。非常感谢。

标签: video ffmpeg


【解决方案1】:

试试这个命令:

find . -name "*.mp4" -exec ffmpeg -v error -i "{}" -map 0:1 -f null - 2>error.log \;

find 命令递归查找当前目录中与给定模式相对应的所有文件:"*.mp4"。在-exec 之后是您要为所有文件运行的命令。 "{}" 替换当前文件的名称,其中引号允许文件名中有空格。该命令必须以\; 结尾。

编辑:

上面的代码只生成一个日志文件,因此无法知道是哪个文件损坏了。要改为为每个 .mp4 文件创建单独的 .log 文件,您可以再使用一次 {} 符号:

find . -name "*.mp4" -exec sh -c "ffmpeg -v error -i '{}' -map 0:1 -f null - 2>'{}.log'" \;

【讨论】:

  • 安德里亚,感谢您的快速回复!您的命令仅部分起作用:虽然它考虑了文件夹内的所有文件及其子文件夹,但只为所有文件创建了一个 error.log。不好的是,我无法仅从这个 .log 文件的内容中识别损坏的视频文件,因为它只显示文件的损坏字节,而不是文件名本身。因此,我正在寻找一个命令,该命令将为每个损坏的视频文件创建一个单独的 .log 文件,该文件与损坏的视频文件具有相同的名称。
  • 这次您更新的命令创建了一个名为 {}.log 的单个 .log 文件。出了点问题。
  • @dmt 我更新了第二条命令,试试看!如果这仍然不起作用,我的最后一个想法是使用具有更详细日志记录级别的第一个版本:-v verbose 而不是-v error。这样一来,您将拥有一个日志文件,但包含更多信息,因此您有望看到哪个文件包含损坏的字节。
  • 您更新后的命令再次无法正常工作,但第一个带有-v verbose 的命令终于足以找到损坏的视频文件。非常感谢!
  • 如果文件名中有空格find -name "*.mp4" -exec sh -c "ffmpeg -v error -i '{}' -map 0:1 -f null - 2>'{}.log'" \;
【解决方案2】:

我最近遇到了同样的问题,但我认为有一个简单的技巧可以找出哪些文件损坏了:

find -name "*.mp4" -exec sh -c "echo '{}' >> errors.log; ffmpeg -v error -i '{}' -map 0:1 -f null - 2>> errors.log" \;

这样错误会跟随文件名(和路径)。

【讨论】:

  • 为了更好地格式化源代码find . -name "*.mp4" -exec sh -c "echo '{}\t\c' >> errors.log; ffmpeg -v error -i '{}' -map 0:1 -f null - 2>> errors.log;echo ''>>errors.log" \;
【解决方案3】:

使用ffmpeg 重新编码为null 格式的其他答案的问题是它们需要很长时间。一种快速的方法是为所有视频生成缩略图,并查看缩略图生成失败的位置。

find . -iname "*.mp4" | while read -r line; do 
  line=`echo "$line" | sed -r 's/^\W+//g'`; 
  echo 'HERE IT IS ==>' "$line"; 
  if ffmpeg -i "$line" -t 2 -r 0.5 %d.jpg; 
    then echo "DONE for" "$line"; 
  else echo "FAILED for" "$line" >>error.log; 
  fi; 
done;

事实证明,这种方法比其他方法快得多。

但是,有一个警告。此方法可能会产生错误的结果,因为有时甚至可以为损坏的文件生成缩略图。例如。如果视频文件仅在最后损坏,此方法将失败。

【讨论】:

  • @llogan 此答案仅使用缩略图生成作为空编码器的替代方案。目标仍然是查找损坏的视频文件,尽管它比其他解决方案提供的信息要少得多。
【解决方案4】:

我将把它留在这里,主要是为了我,也许还有其他人想要使用 ffmpeg 在多个文件夹中批量查找有错误或损坏文件的视频,创建一个子文件夹并移动该子文件夹中的文件。

这是我的 bash 脚本,用于递归查找有错误的 mp4 文件并将它们移动到 00errors 文件夹中。

#!/bin/bash

ROOTPATH="/mnt/f/00test/" # manually define root  path to your folder that has subfolders
for subdir in *; do
  cd ${ROOTPATH}${subdir} 
  mkdir 00errors
  
  for path in *.mp4; do

    ffmpeg error -i "${path}"
    RC=$?

    if [ "${RC}" -ne "0" ]; then
        # Do something to handle the error.
        mv ${path} ./00errors
    fi

  done
  cd ../
done

编辑:

与此同时,我发现了这款适用于 HandBrake 和 FFmpeg/FFprobe(Windows、macOS、Linux 和 Docker)的 HBBatchBeast 应用

https://github.com/HaveAGitGat/HBBatchBeast

【讨论】:

  • 您的脚本将每个视频从文件夹移动到子文件夹,无论视频是否损坏?
【解决方案5】:

Windows 系统的批处理文件,假设 ffmpeg 在您的路径中:

@echo off
for /r %%f in (*.mp4) do (
    ffmpeg -hide_banner -v error -i "%%f" -map 0:1 -f null - 2>out.txt
    if errorlevel 1 (
        type out.txt
        echo   %%f
    )
)
if exist out.txt del out.txt 1>nul 2>nul
pause

这将列出错误,后跟缩进的文件名,仅为那些出错的文件。

【讨论】:

    【解决方案6】:
    find /dir/subdir -iname "*.mp4" -print0 | while read -d $'\0' file; do ERR=`ffprobe -v error "$file" 2>&1`; if [ "$ERR" != "" ]; then echo "$file"; fi; done
    

    【讨论】:

      猜你喜欢
      • 2019-07-05
      • 1970-01-01
      • 1970-01-01
      • 2021-09-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-12
      相关资源
      最近更新 更多