300

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

4

31 回答 31

478

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

for i in *.avi; do ffmpeg -i "$i" "${i%.*}.mp4"; done
于 2015-11-17T20:15:16.817 回答
238

上一个答案只会创建 1 个名为 out.mov 的输出文件。要为每部旧电影制作单独的输出文件,请尝试此操作。

for i in *.avi;
  do name=`echo "$i" | cut -d'.' -f1`
  echo "$name"
  ffmpeg -i "$i" "${name}.mov"
done
于 2011-11-20T08:35:01.013 回答
104

在 Windows 上:

FOR /F "tokens=*" %G IN ('dir /b *.flac') DO ffmpeg -i "%G" -acodec mp3 "%~nG.mp3"
于 2014-06-17T21:34:17.813 回答
48

对于 Windows:

在这里,我将所有 (.mp4) 文件转换为 (.mp3) 文件。
只需打开 cmd,转到所需的文件夹并键入命令。

快捷方式:(可选)
1. 转到 (.mp4) 文件所在的文件夹
2. 按 Shift 并左键单击并选择“在此处打开 PowerShell 窗口”
或“在此处打开命令提示符窗口”
3. 键入“cmd” [注意:如果直接打开cmd而不是PowerShell,则跳过此步骤]
4.运行命令

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

如果要将其放入 Windows 10 上的批处理文件中,则需要使用 %%i。

于 2019-05-21T18:14:22.060 回答
35

单行 bash 脚本很容易实现 - 替换*.avi为您的文件类型:

for i in *.avi; do ffmpeg -i "$i" -qscale 0 "$(basename "$i" .avi)".mov  ; done
于 2011-07-02T22:29:07.357 回答
31

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

find . -exec ffmpeg -i {} {}.mp3 \;
于 2016-12-12T16:59:38.790 回答
25

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

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

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

于 2018-04-25T09:34:47.370 回答
22

@Linux 要转换一堆,我的一个衬里是这样的,例如(.avi 到 .mkv)在同一目录中:

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

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

于 2020-08-13T23:45:55.997 回答
8

当然,现在 PowerShell 已经出现,专门设计用于使类似这样的事情变得非常容易。

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

首先,您需要列出当前目录中的所有文件,因此,我们将从以下内容开始:

ls

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

然后,我们将这些过滤器过滤到我们想要转换的文件类型 - 例如“avi”。

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

之后,我们将通过一个ForEach.

对于 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”文件,只需替换引号中的三个内容以决定您想要的转换类型,并随时在ForEach.

您可以更进一步并添加Remove-Item到末尾以自动删除旧文件。

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

希望这对任何人都有帮助。

于 2020-04-03T13:24:37.817 回答
7

如果你有 GNU并行,你可以将下面的所有 .avi 文件并行转换vid_dir为 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.

于 2018-05-10T09:37:25.387 回答
6

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

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可以转换它就可以指定任意两个扩展名。

于 2018-09-14T20:17:03.807 回答
5

以下脚本在 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

于 2020-07-28T15:29:33.080 回答
4

我用它来为 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"
    )
于 2020-12-10T08:11:57.403 回答
3

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

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

您可以将 *.avi 更改为与您的源素材匹配的任何内容。

于 2019-01-22T07:45:01.660 回答
2
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]将文件批处理flacmp3(对带空格的文件名安全)

于 2016-05-13T02:15:44.357 回答
2

视窗:

@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,但除非您有一个非常好的扬声器系统,否则它毫无价值 imo

于 2019-01-29T21:07:11.933 回答
2

只有这个对我有用,请注意您必须手动创建 ffmpeg.exe 文件所在的“newfiles”文件夹。

转换. 文件到 .wav 音频代码:

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

希望它有所帮助。

于 2019-08-07T12:23:23.827 回答
2

此外,如果您想在子文件夹中进行相同的转换。这是递归代码。

for /R "folder_path" %%f in (*.mov,*.mxf,*.mkv,*.webm) do (
    ffmpeg.exe -i "%%~f" "%%~f.mp4"
    )
于 2020-06-12T05:14:08.770 回答
2

对于咯咯笑,这是fish-shell中的解决方案:

for i in *.avi; ffmpeg -i "$i" (string split -r -m1 . $i)[1]".mp4"; end
于 2020-10-27T12:21:57.773 回答
2

使用多核,这是最快的方式,(使用并行):

parallel "ffmpeg -i {1} {1.}.mp4" ::: *.avi 
于 2022-01-17T12:53:27.003 回答
1

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

echo exec("ffmpeg -framerate 1/5 -i photo%d.jpg -r 25 -pix_fmt yuv420p output.mp4");
于 2020-01-21T12:06:47.840 回答
1

我在 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

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

于 2020-04-24T21:57:05.333 回答
1

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

for S (*.mp4) { ffmpeg -i $S -c:v libx264 -r 30  new$S }
于 2020-11-02T17:19:51.717 回答
1

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

于 2021-07-25T00:03:57.530 回答
0

如果您想要使用 ffmpegX 进行批处理的图形界面,请尝试Quick Batcher。它是免费的,并且会使用您最后的 ffmpegX 设置来转换您放入其中的文件。

请注意,您不能将文件夹拖放到 Quick Batcher。因此,选择文件,然后将它们放入 Quick Batcher。

于 2014-04-05T08:58:23.927 回答
0

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

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

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

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

于 2018-11-27T17:01:41.273 回答
0

这就是我用来将 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 文件。

调用我的(为你的更改)ffmpeg,传递输入名称,设置用于通过锐化重新缩放。我可能不需要 CRF 和“ -b:v 1024k”...

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

于 2019-12-08T05:08:48.417 回答
0

对于 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"
于 2020-03-06T01:28:01.853 回答
0

我为此案例开发了python包。

https://github.com/developer0hye/BatchedFFmpeg

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

pip install batchedffmpeg
batchedffmpeg * -i folder * output_file

在此处输入图像描述

于 2021-12-11T17:16:29.557 回答
0

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

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

-d意味着深度

-x表示执行

{.}没有文件扩展名的路径

于 2022-02-17T08:29:38.063 回答
-1

执行此操作的小 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' ) );
}
于 2017-11-07T13:47:39.260 回答