对多个目录中的视频文件进行递归编码

Recursively encode video files in many directories

提问人:menteith 提问时间:7/15/2023 更新时间:7/16/2023 访问量:52

问:

我想一次对多个目录中的视频文件进行编码。在每个目录中,当至少有一个文件时,应使用正确的参数运行应用程序。假设一个视频文件被命名为 。我希望输出文件与源位于同一目录中,名称后缀位于文件名末尾但在 extension01_file.mp401_file_processed.mp4' 之前。 我非常接近正确的解决方案。这是我的一句话:*.mp4ffmpeg01_file.mp4processed. So the source would be saved as

find -mindepth 2 -type f ! -path '*processed.mp4' -name '*.mp4' -exec bash -c 'ffmpeg -loglevel warning -i "$1" -vf fps=23.976025 "${1%/*}/${1##*/}_processed"' _ {} \;

由于输出文件不正确,因此我收到错误。以文件结尾的正确路径不是 .我相信错误在以下部分.如何解决此问题?ffmpeg01_file_processed.mp401_file.mp4_processed${1%/*}/output/${1##*/}"

bash 循环 文件 递归 ffmpeg

评论


答:

1赞 chrslg 7/15/2023 #1

你为什么要尝试将 dirname 与 basename 分开,如果你对这种拆分所做的唯一事情就是重新连接它?

我觉得你试图模仿另一个有另一个目标的代码。

就您而言,如果我理解正确,则无需提取 basename 或 dirname。但是您想删除扩展名以在其前面添加 a。_processed

以您的技术,这很容易做到,因为您知道扩展名是 .因此,只需删除尾随,就像删除尾随以提取 dirname 一样。然后用你想要的替换它,即,.mp4.mp4/*.mp4_processed.mp4

find -mindepth 2 -type f ! -path '*processed.mp4' -name '*.mp4' -exec bash -c 'ffmpeg -loglevel warning -i "$1" -vf fps=23.976025 "${1%.mp4}_processed.mp4"' _ {} \;
0赞 Ed Morton 7/16/2023 #2

未经测试,假设文件名不包含换行符:

sfx='mp4'
while IFS= read -r orig; do
    proc="${orig%%.$sfx}_processed.$sfx"
    ffmpeg ...whatever... "$orig" > "$proc"
done < <( find -mindepth 2 -type f ! -path "*processed.$sfx" -name "*.$sfx" {} + )
1赞 pjh 7/16/2023 #3

如果您有 Bash 版本 4.3 或更高版本,请尝试以下 Shellcheck-clean 代码:

#! /bin/bash -p

shopt -s dotglob extglob globstar nullglob
for mp4file in */**/!(*_processed).mp4; do
    echo ffmpeg -loglevel warning -i "$mp4file" -vf fps=23.976025 "${mp4file%.mp4}_processed.mp4"
done
  • shopt -s ...启用代码所需的某些 Bash 设置:
    • dotglob使 glob 能够匹配以 开头的文件和目录。 默认情况下处理此类文件。.find
    • extglob启用“扩展通配”(包括类似 的模式)。请参阅 glob - Greg's Wiki 中的 extglob 部分。!(*_processed).mp4
    • globstar允许使用 to 通过目录树以递归方式匹配路径。此选项是在 Bash 4.0(2009 年发布)中引入的,但在 4.3(2014 年发布)之前的版本中使用是危险的,因为它遵循符号链接。**
    • nullglob当没有匹配项时,使 glob 扩展为无(否则它们会扩展到 glob 模式本身,这在程序中几乎从来都没有用)。
  • 有关 的说明,请参阅删除字符串的一部分 (BashFAQ/100 (How do I do string manipulation in bash?))。${mp4file%.mp4}
  • 如果您对代码将执行您想要的操作感到满意,请删除。echo