如何用ffmpeg转换整个目录?

如何通过命令行或批处理脚本与ffmpeg转换整个目录/文件夹?

413128 次浏览

一行bash脚本很容易做到-用你的文件类型替换*.avi:

for i in *.avi; do ffmpeg -i "$i" -qscale 0 "$(basename "$i" .avi)".mov  ; done

前面的答案只会创建一个名为out.mov的输出文件。要为每一部老电影创建一个单独的输出文件,可以试试这个方法。

for i in *.avi;
do name=`echo "$i" | cut -d'.' -f1`
echo "$name"
ffmpeg -i "$i" "${name}.mov"
done

如果你想要一个使用ffmpegX进行批处理,尝试快速批处理。它是免费的,并将使用您最后的ffmpegX设置来转换您放入其中的文件。

注意,不能将文件夹拖放到Quick Batcher上。所以选择文件,然后把他们通过快速批处理。

在Windows上:

FOR /F "tokens=*" %G IN ('dir /b *.flac') DO ffmpeg -i "%G" -acodec mp3 "%~nG.mp3"

对于LinuxmacOS,这可以在一行中完成,使用参数扩展更改输出文件的文件名扩展名:

for i in *.avi; do ffmpeg -i "$i" "${i%.*}.mp4"; done
for i in *.flac;
do name=`echo "${i%.*}"`;
echo $name;
ffmpeg -i "${i}" -ab 320k -map_metadata 0 -id3v2_version 3 "${name}".mp3;
done

使用[1] [2]flac文件批处理为mp3(对于带有空格的文件名安全)

要转换子目录,请使用例如。

find . -exec ffmpeg -i {} {}.mp3 \;

小PHP脚本来做它:

#!/usr/bin/env php
<?php
declare(strict_types = 1);
if ($argc !== 2) {
fprintf ( STDERR, "usage: %s dir\n", $argv [0] );
die ( 1 );
}
$dir = rtrim ( $argv [1], DIRECTORY_SEPARATOR );
if (! is_readable ( $dir )) {
fprintf ( STDERR, "supplied path is not readable! (try running as an administrator?)" );
die(1);
}
if (! is_dir ( $dir )) {
fprintf ( STDERR, "supplied path is not a directory!" );
die(1);
}
$files = glob ( $dir . DIRECTORY_SEPARATOR . '*.avi' );
foreach ( $files as $file ) {
system ( "ffmpeg -i " . escapeshellarg ( $file ) . ' ' . escapeshellarg ( $file . '.mp4' ) );
}

对于任何想要用ffmpeg批量转换任何东西,但想要有一个方便的Windows界面的人,我开发了这个前端:

https://sourceforge.net/projects/ffmpeg-batch

它为ffmpeg添加了一个窗口时尚界面,进度条和时间剩余信息,这些功能是我在使用ffmpeg时经常错过的。

如果你有GNU 平行,你可以将vid_dir以下的所有。avi文件并行转换为mp4,使用你的CPU内核,除了一个

find vid_dir -type f -name '*.avi' -not -empty -print0 |
parallel -0 -j -1 ffmpeg -loglevel fatal -i {} {.}.mp4

要从/转换为不同的格式,可以根据需要更改'*.avi'.mp4。GNU并行在大多数Linux发行版的存储库中被列在一个通常被称为parallel的包中。

我知道这可能是多余的,但我使用这个脚本批量转换文件。

old_extension=$1
new_extension=$2


for i in *."$old_extension";
do ffmpeg -i "$i" "${i%.*}.$new_extension";
done

它需要2个参数使其更灵活:

  1. 要转换的扩展名
  2. 要转换的新扩展名

我为它创建了一个别名,但你也可以手动使用它,像这样:

sh batch_convert.sh mkv mp4

这将把所有的mkv文件转换为mp4文件。

正如你所看到的,它更多功能。只要ffmpeg可以转换它,你就可以指定任何两个扩展名。

另一个尚未被建议的简单解决方案是使用xargs:

ls *.avi | xargs -i -n1 ffmpeg -i {} "{}.mp4"

一个小缺陷是输出文件的尴尬命名(例如input.avi.mp4)。一个可能的解决方法是:

ls *.avi | xargs -i -n1 bash -c "i={}; ffmpeg -i {} "\${i%.*}.mp4"

这里有点像代码高尔夫,但由于到目前为止几乎所有的答案都是bash(除了一个单独的cmd),这里有一个窗户 跨平台的命令,它使用powershell(因为很棒):

ls *.avi|%{ ffmpeg -i $_ <ffmpeg options here> $_.name.replace($_.extension, ".mp4")}

你可以改变*。Avi到与源视频相匹配的地方。

窗口:

@echo off
for /r %%d in (*.wav) do (
ffmpeg -i "%%~nd%%~xd" -codec:a libmp3lame -c:v copy -qscale:a 2 "%


%~nd.2.mp3"
)

这是质量2的可变比特率,如果你想,你可以把它设置为0,但除非你有一个非常好的扬声器系统,否则在我看来这是毫无价值的

Windows: < br >

这里我正在将所有(.mp4)文件转换为(.mp3)文件 只需打开cmd,进入所需的文件夹并键入命令
快捷方式:(可选) < br > 1. 转到(.mp4)文件所在的文件夹
2. 按Shift键,点击左键,选择“打开PowerShell窗口此处”
或“此处打开命令提示窗口”
3.输入“cmd”[注意:如果它直接打开cmd而不是PowerShell,则跳过此步骤]
4. 执行命令

for %i in (*.mp4) do ffmpeg -i "%i" "%~ni.mp3"

如果你想把它放到Windows 10的批处理文件中,你需要使用%%i。

只有这一个为我工作,请注意,你必须手动创建“newfiles”文件夹,ffmpeg.exe文件所在的位置。

转换文件为.wav音频 代码:< / p >

for %%a in ("*.*") do ffmpeg.exe -i "%%a" "newfiles\%%~na.wav"
pause

例如,如果你想将所有的。mp3文件转换为。wav,将("*.*")转换为("*.mp3")

这个剧本的作者是:

https://forum.videohelp.com/threads/356314-How-to-batch-convert-multiplex-any-files-with-ffmpeg

希望这对你有帮助🙏。

这是我用来批量转换avi到1280x mp4

FOR /F "tokens=*" %%G IN ('dir /b *.avi') DO "D:\Downloads\ffmpeg.exe" -hide_banner -i "%%G" -threads 8 -acodec mp3 -b:a 128k -ac 2 -strict -2 -c:v libx264 -crf 23 -filter:v "scale=1280:-2,unsharp=5:5:1.0:5:5:0.0" -sws_flags lanczos -b:v 1024k -profile:v main -preset medium -tune film -async 1 -vsync 1 "%%~nG.mp4"

作为一个cmd文件,运行它,循环找到该文件夹中的所有avi文件。

调用MY(更改为您的)ffmpeg,传递输入名称,设置为缩放锐化。我可能不需要CRF和“-b:v 1024k”…

输出文件是减去扩展名的输入文件,mp4作为新的ext。

这将从当前目录中的所有jpg文件创建mp4视频。

echo exec("ffmpeg -framerate 1/5 -i photo%d.jpg -r 25 -pix_fmt yuv420p output.mp4");

对于Windows,这是行不通的

FOR /F "tokens=*" %G IN ('dir /b *.flac') DO ffmpeg -i "%G" -acodec mp3 "%~nG.mp3"

即使我将%加倍。

我甚至建议:

-acodec ***libmp3lame***

另外:

FOR /F "tokens=*" %G IN ('dir /b *.flac') DO ffmpeg -i "%G" -acodec libmp3lame "%~nG.mp3"

当然,现在PowerShell出现了,专门设计来使类似的事情变得容易。

而且,是的,除了Windows, PowerShell在其他操作系统上是也可用,但它是预装在Windows上的,所以这应该对每个人都有用。

首先,你想要列出当前目录中的所有文件,所以,我们将从:

ls

如果你想递归地转换子目录中的所有文件,也可以使用ls -Recurse

然后,我们将这些文件过滤下来,只有我们想转换的文件类型-例如。“avi”。

ls | Where { $_.Extension -eq ".avi" }

之后,我们将通过ForEach将该信息传递给FFmpeg。

对于FFmpeg的输入,我们将使用FullName——这是文件的整个路径。对于FFmpeg的输出,我们将使用Name -但替换.avi.mp3结尾。所以,它看起来是这样的:

$_.Name.Replace(".avi", ".mp3")

所以,让我们把所有这些放在一起,这是结果:

ls | Where { $_.Extension -eq ".avi" } | ForEach { ffmpeg -i $_.FullName $_.Name.Replace(".avi", ".mp3") }

这将改变所有人。”通过FFmpeg将avi"文件转换为".mp3"文件,只需替换引号中的三个内容来决定您想要的转换类型,并随时向FFmpeg中ForEach. xml文件中添加任何其他参数。

你可以更进一步,在末尾添加Remove-Item来自动删除旧文件。

如果ffmpeg不在你的路径中,它实际上在你当前所在的目录中,在那里写./ffmpeg而不是ffmpeg

希望这对大家有所帮助。

我在linux中使用这一行程序将文件(通常是H265)转换为我可以在Kodi上毫无问题地播放的东西:

for f in *.mkv; do ffmpeg -i "$f" -c:v libx264 -crf 28 -c:a aac -b:a 128k output.mkv; mv -f output.mkv "$f"; done

这将转换为临时文件,然后替换原始文件,以便转换后名称保持不变。

同样如果你想在子文件夹中进行相同的转换。 这是递归代码。

for /R "folder_path" %%f in (*.mov,*.mxf,*.mkv,*.webm) do (
ffmpeg.exe -i "%%~f" "%%~f.mp4"
)

下面的脚本在Windows上的Bash中工作得很好(所以它在Linux和Mac上也应该工作得很好)。它解决了我在其他解决方案中遇到的一些问题:

  • 处理子文件夹中的文件
  • 用目标扩展替换源扩展,而不仅仅是附加它
  • 适用于名称中有多个空格和多个点的文件 (详见这个答案)
  • 可以运行时,目标文件存在,提示之前覆盖

ffmpeg-batch-convert.sh:

sourceExtension=$1 # e.g. "mp3"
targetExtension=$2 # e.g. "wav"
IFS=$'\n'; set -f
for sourceFile in $(find . -iname "*.$sourceExtension")
do
targetFile="${sourceFile%.*}.$targetExtension"
ffmpeg -i "$sourceFile" "$targetFile"
done
unset IFS; set +f

示例调用:

$ sh ffmpeg-batch-convert.sh mp3 wav

作为奖励,如果你想删除源文件,你可以像这样修改脚本:

sourceExtension=$1 # e.g. "mp3"
targetExtension=$2 # e.g. "wav"
deleteSourceFile=$3 # "delete" or omitted
IFS=$'\n'; set -f
for sourceFile in $(find . -iname "*.$sourceExtension")
do
targetFile="${sourceFile%.*}.$targetExtension"
ffmpeg -i "$sourceFile" "$targetFile"
if [ "$deleteSourceFile" == "delete" ]; then
if [ -f "$targetFile" ]; then
rm "$sourceFile"
fi
fi
done
unset IFS; set +f

示例调用:

$ sh ffmpeg-batch-convert.sh mp3 wav delete

< p > @Linux 为了转换一堆,我的一行代码是这样的 (.Avi到。mkv)在相同的目录:

for f in *.avi; do ffmpeg -i "${f}" "${f%%.*}.mkv"; done

请注意两个“%%"在输出语句中。它不仅提供了第一个单词或输入文件名,还提供了最后一个点之前的所有内容。

下面是fish-shell中的解决方案:

for i in *.avi; ffmpeg -i "$i" (string split -r -m1 . $i)[1]".mp4"; end

我需要所有的视频使用相同的编解码器来合并 所以这个转换是mp4到mp4
它在ZSH中,但应该很容易转换为bash

for S (*.mp4) { ffmpeg -i $S -c:v libx264 -r 30  new$S }

我用这个为Windows上的电视节目或电影添加字幕。

只需创建“subbed”;文件夹和bat文件在视频和子目录。将代码放入bat文件并运行。

for /R  %%f in (*.mov,*.mxf,*.mkv,*.webm) do (
ffmpeg.exe  -i "%%~f" -i "%%~nf.srt" -map 0:v -map 0:a -map 1:s -metadata:s:a language=eng -metadata:s:s:1 language=tur -c copy ./subbed/"%%~nf.mkv"
)

Bash对我来说很糟糕,所以在Linux/Mac下,我更喜欢Ruby脚本:

(找到一个文件夹中的所有文件,然后将其从rmvb/rm格式转换为mp4格式)

# filename: run.rb
Dir['*'].each{ |rm_file|
next if rm_file.split('.').last == 'rb'
command = "ffmpeg -i '#{rm_file}' -c:v h264 -c:a aac '#{rm_file.split('.')[0]}.mp4'"
puts "== command: #{command}"
`#{command}`
}


你可以用:ruby run.rb运行它

我为此开发了一个python包。

https://github.com/developer0hye/BatchedFFmpeg

您可以轻松地安装和使用它。

pip install batchedffmpeg
batchedffmpeg * -i folder * output_file

enter image description here

使用多核时,这是最快的方法(使用平行):

parallel "ffmpeg -i {1} {1.}.mp4" ::: *.avi

使用fd命令(存储库)的替代方法:

cd directory
fd -d 1 mp3 -x ffmpeg -i {} {.}.wav

-d表示深度

-x表示执行

不带文件扩展名的{.}路径

如果你不想转换文件,只是复制编解码器使用下面的代码

for %i in (*.mkv) do ffmpeg -i "%i" -codec copy "%~ni.mp4"

这样可以减少转换时间。

复制@HiDd3n,你也可以这样做,如果你想递归搜索文件目录,以防你有很多文件夹:

for /r %i in (*.webm) do "C:\Program Files\ffmpeg\bin\ffmpeg.exe" -i "%i" "%~ni.mp3"

在Windows上,用于子目录中的文件

FOR /F "tokens=*" %G IN ('dir /s /b /o:gn *.mp4') DO ffmpeg -i "%G" -c copy "%~pG%~nG.mkv"

这将所有mp4文件转换为mkvs,包括子目录中的文件,并将mkv文件放在mp4文件所在的位置,即文件C:\temp\test.mp4将在C:\temp\test.mkv中有对应的mkv文件