你如何用ffmpeg转换整个目录?

时间:2011-04-26 00:19:16

标签: ffmpeg batch-processing

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

27 个答案:

答案 0 :(得分:157)

对于 Linux macOS ,可以在一行中完成,使用parameter expansion更改输出文件的文件扩展名:

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

答案 1 :(得分:128)

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

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

答案 2 :(得分:50)

在Windows上:

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

答案 3 :(得分:23)

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

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

答案 4 :(得分:15)

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

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

答案 5 :(得分:9)

对于任何想要使用ffmpeg批量转换任何内容但希望拥有方便的Windows界面的人,我开发了这个前端:

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

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

答案 6 :(得分:5)

当然,现在PowerShell出现了,它经过专门设计以使完全类似于 的事情变得容易。

是的,PowerShell also available在Windows以外的其他操作系统上也可以使用,但是它已预先安装在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添加其他任何参数{1}}。

您可以更进一步,并在末尾添加ForEach,以自动删除旧文件。

如果Remove-Item不在您的路径中,并且实际上在您当前所在的目录中,请在其中写入ffmpeg,而不只是./ffmpeg

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

答案 7 :(得分:4)

如果你有GNU parallel,你可以将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。大多数Linux发行版都列出了GNU parallel'包中的存储库,通常称为parallel

答案 8 :(得分:3)

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

请注意,您无法将文件夹拖放到Quick Batcher上。因此,选择文件,然后通过Quick Batcher。

答案 9 :(得分: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]

批处理flac个文件到mp3(对于带空格的文件名是安全的)

答案 10 :(得分:2)

在这里有点像代码高尔夫,但是由于到目前为止几乎所有答案都是bash(除非有一个孤独的cmd),所以这是一个使用powershell的 windows cross-platform命令(因为很棒):

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

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

答案 11 :(得分:2)

windows:

@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

答案 12 :(得分:1)

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

只需在video和sub目录中创建“ 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"
    )

答案 13 :(得分:1)

以下脚本在Windows上的Bash中对我来说效果很好(因此在Linux和Mac上效果也一样)。它解决了我在其他解决方案中遇到的一些问题:

  • 处理子文件夹中的文件
  • 用目标扩展名替换源扩展名,而不只是附加目标扩展名
  • 使用名称中包含多个空格和多个点的文件 (有关详细信息,请参见this answer。)
  • 可以在目标文件存在时运行,在覆盖之前提示

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

答案 14 :(得分:1)

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

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

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

答案 15 :(得分:1)

只有这个对我有用,请注意,您必须手动在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

希望对您有帮助。

答案 16 :(得分:0)

对于傻笑,这是鱼壳中的解决方案:

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

答案 17 :(得分:0)

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

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

答案 18 :(得分:0)

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

答案 19 :(得分:0)

如果要在子文件夹中进行相同的转换,也可以。 这是递归代码。

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

答案 20 :(得分:0)

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

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

答案 21 :(得分: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"

答案 22 :(得分:0)

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

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

答案 23 :(得分:0)

这就是我用来将avi批量转换为1280x mp4的方式

  

FOR / F“ tokens = *” %% G IN('dir / b * .avi')DO“ D:\ Downloads \ ffmpeg.exe”   -hide_banner -i“ %% G”-线程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主-预设中片-电影-async 1 -vsync 1“ %%〜nG.mp4”

作为cmd文件运行良好,运行它,循环会在该文件夹中找到所有avi文件。

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

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

答案 24 :(得分:0)

对于Windows:

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

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

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

答案 25 :(得分:0)

尚未建议的另一种简单解决方案是使用Set @Ids = ''; select @Ids := concat_ws(',',@Ids,tbl.Id), tbl.Col1, ... from mytable tbl;

xargs

一个小缺陷是输出文件(例如ls *.avi | xargs -i -n1 ffmpeg -i {} "{}.mp4")的尴尬命名。可能的解决方法是:

input.avi.mp4

答案 26 :(得分:-2)

这个小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' ) );
}