如何使用ffmpeg从文件夹中的所有视频提取帧

4

我目前能够使用以下代码从文件中提取图像:

ffmpeg -i inputfile.avi -r 1 image-%d.jpeg

然而,我想将其应用于文件夹中的所有文件,并将其放置在输出文件夹中。
假设我有当前包含所有视频的文件夹:
input-videos/
----subfolder1/
------video.avi
----subfolder2/
------video.avi
我希望将所有内容放在输出文件夹中:
output/
----subfolder1/
------video/
----------*.jpeg
----subfolder2/
------video/
----------*.jpeg
使用bash脚本(或其他更好的方法),最简单的方法是什么?

强烈建议修改此行代码:将 ffmpeg -i inputfile.avi -r 1 image-%d.jpeg 修改为 ffmpeg -i inputfile.avi -r 1 image-%05d.jpeg,这样图像名称就会进行零填充:例如,image-54.jpeg 将变成 image-00054.jpeg,这意味着按字母顺序排序也以时间顺序排序。这同样适用于此处给出的所有答案。 - Rodrigo Laguna
2个回答

7
如果文件夹的深度是常数,文件扩展名始终为avi,并且顶层文件夹称为“input-videos”和“output”:
#!/bin/bash
for file in input-videos/*/*.avi; do
    destination="output${file:12:${#file}-17}";
    mkdir -p "$destination";
    ffmpeg -i "$file" -r 1 "$destination/image-%d.jpeg";
done

如果最顶层文件夹的名称可以随意更改且可以位于任何位置,而且文件扩展名不同,那么有一个脚本可以使用,您可以像这样调用它:./script.sh <输入文件夹> <输出文件夹> <文件扩展名>:
#!/bin/bash
if [ "$1" == '' ] || [ "$2" == '' ] || [ "$3" == '' ]; then
    echo "Usage: $0 <input folder> <output folder> <file extension>";
    exit;
fi
for file in "$1"/*/*."$3"; do
    destination="$2${file:${#1}:${#file}-${#1}-${#3}-1}";
    mkdir -p "$destination";
    ffmpeg -i "$file" -r 1 "$destination/image-%d.jpeg";
done

0

将来自@Siguza的答案进行适应,以便直接执行:

INPUT_DIR="input-videos"
OUTPUT_DIR="output"
EXTENSION="avi"
for filepath in "$INPUT_DIR"*/*."$EXTENSION"; do
    filename="${filepath:${#INPUT_DIR}:${#filepath}-${#INPUT_DIR}-${#EXTENSION}-1}";
    destination="$OUTPUT_DIR$filename";
    mkdir -p "$destination";
    ffmpeg -i "$filepath" -r 1 "$destination/image-%d.jpeg";
done

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接