bash - 将 3 个单独的命令合并为一个,用于重新编码视频、提取缩略图、删除原始视频并在子目录中重命名新视频

标签 bash ffmpeg find command-line-interface

我正在尝试执行 find bash 命令来处理数百个名为 video-original.mp4 的视频文件但在父目录的子目录中。

这是目录结构的示例:

videos
├── 01a
│   └── video-original.mp4
├── 01b
│   └── video-original.mp4
├── 02a
│   └── video-original.mp4
├── 02b
│   └── video-original.mp4
├── 03a
│   └── video-original.mp4
└── 03b
    └── video-original.mp4

我正在使用以下命令:
find ./ -name 'video-original.mp4' -exec bash -c 'ffmpeg -i "$0" -f mp4 -vcodec libx264 -preset veryslow -profile:v high -acodec aac -movflags faststart video.mp4 -hide_banner' {} \;

我遇到的问题是它正在保存文件 video.mp4在父 videos目录,而不是在原始 video-original.mp4 旁边的子目录中

之后,我想删除文件video-original.mp4 .目前,我的过程需要等待所有视频重新编码,然后在完成后发出单独的命令来删除文件 video-original.mp4 :
find ./ -name 'video-original.mp4' -exec bash -c 'rm -rf "$0"' {} \;

我的最后一步是提取新 video.mp4 的屏幕截图。 10 秒后保存为 thumbnail.jpg .同样,我目前正在将其作为一个单独的步骤执行,在前两个步骤完成后执行。
find ./ -name 'video.mp4' -exec bash -c 'ffmpeg -i "$0" -ss 00:00:10 -vframes 1 thumbnail.jpg' {} \;

我想做的是将这三个步骤组合成一个命令,因此最终结果将是:
videos
├── 01a
│   ├── thumbnail.jpg
│   └── video.mp4
├── 01b
│   ├── thumbnail.jpg
│   └── video.mp4
├── 02a
│   ├── thumbnail.jpg
│   └── video.mp4
├── 02b
│   ├── thumbnail.jpg
│   └── video.mp4
├── 03a
│   ├── thumbnail.jpg
│   └── video.mp4
└── 03b
    ├── thumbnail.jpg
    └── video.mp4

最后,最好将其保存为 bash 脚本并将其包含在我的路径中的 /usr/local/bin 中。或 ~/bin作为一个可执行文件,所以我可以发出命令 reencode它会运行。如果输入文件可以有任何视频文件会更好,例如,random_name.mp4random_name.movrandom_name.webm ,基本上是任何视频文件(但在编码步骤跳过video.mp4)。

最佳答案

我相信可能有两个问题,一个是路径 ./ - 所以也许尝试使用:

find . -name ...

否则路径被翻译为.//file ,这似乎不正确。

下一个问题是,由于您正在运行 find来自父目录的命令 任何用 -exec 调用的东西将在那里输出。相反,我们将要使用 -execdir因为这将处理它找到的文件目录中的所有内容。既然你想从中创建一个命令,我们将把它变成一个 bash 函数,然后你可以将你添加到 ~/.bash_profile或您喜欢设置环境的任何地方。
encode () { export target=$2 ; find . -name "*$1*" \
! -name "$target" -execdir bash -c 'ffmpeg -i "$0" -f mp4 -vcodec libx264 \
-preset veryslow -profile:v high -acodec aac -movflags faststart "$target" \
-hide_banner -ss 00:00:10 -vframes 1 thumbnail.jpg' {} \; \
-execdir bash -c 'rm -f "$0"' {} \; ; }

基本上它的作用是包装整个 find您可以从命令行调用的 bash 函数中的命令(一旦添加到您的配置文件等):
$ encode mp4 video.mp4
          |      |
          |      |___ target file (encode will also skip this file)
          |
          |___ recursively encode files matching this extension

总而言之,encode函数包装 find命令,它依次递归搜索与您选择作为参数一的扩展名匹配的任何文件。 target (arg 2) 是要保存的文件名或输出文件。编码完成后的原始文件target被编码从被删除。如果文件与您选择的扩展名匹配并且与 target 位于同一目录中那么匹配的文件将被编码为 target文件(覆盖它);不管怎样 target文件总是被跳过并且从不编码。

关于bash - 将 3 个单独的命令合并为一个,用于重新编码视频、提取缩略图、删除原始视频并在子目录中重命名新视频,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41657024/

相关文章:

linux - 如何更改多个文件的编码?

linux - 查找具有可变字符数的文件名

bash - 使用 find 命令重复结果条目

loops - Solidworks 宏在每个工程图上查找和替换

linux - Bash while 在两次之间循环

Linux 命令输出未被重定向

python - 进程完成后如何杀死终端

ffmpeg - 在 ffmpeg 或 avconv 中明确加入 MP3 - 什么是神奇的代码行?

ffmpeg - 管道管道线到 ffmpeg 标准输入

video - FFmpeg -ss 奇怪的行为