Как конвертировать весь каталог с помощью ffmpeg?

191

Как конвертировать весь каталог / папку с помощью ffmpeg через командную строку или с помощью пакетного скрипта?

Евгений
источник

Ответы:

175

Предыдущий ответ создаст только 1 выходной файл с именем out.mov. Чтобы создать отдельный выходной файл для каждого старого фильма, попробуйте это.

for i in *.avi;
  do name=`echo "$i" | cut -d'.' -f1`
  echo "$name"
  ffmpeg -i "$i" "${name}.mov"
done
Исаак
источник
24
Если вы похожи на меня и в именах файлов есть много пробелов (и несколько других проблемных символов), я бы предложил добавить двойные кавычки: ffmpeg -i "$ i" "$ name.mov";
Пиф
7
Я получаю ошибкуi was unexpected at this time.
Keavon
5
do name=`echo "${i%.*}"`;будет работать с именами файлов с точками (и пробелами) в них.
Nepoxx
8
Вау, этот ответ невероятно сложен. Смотрите один из однострочных ответов.
foo barbecue
2
это поддержка .batв Windows?
Джазулы
294

Для Linux и macOS это можно сделать в одну строку, используя расширение параметра, чтобы изменить расширение имени файла выходного файла:

for i in *.avi; do ffmpeg -i "$i" "${i%.*}.mp4"; done
llogan
источник
2
Это прекрасно, спасибо! Вот полная команда, которая в итоге отлично работает для меня: для меня в * .avi; do ffmpeg -i "$ i" -c: aac -b: a 128k -c: v libx264 -crf 20 "$ {i% .avi} .mp4"; сделано
Фил Кулак
1
@Junaid 1) Убедитесь, что вы используете другое имя для выходного файла, чем для ввода, или выводите в другой каталог, потому что ffmpegне можете вводить и выводить в один и тот же файл. 2) Я не уверен, что команды Bash работают на Windows 10 изначально. Возможно, я должен добавить к ответу, что он нацелен на системы, которые могут использовать Bash, такие как Linux и macOS. LXS предоставил ответ Windows на этот вопрос.
Llogan
4
Потрясающий ответ. Работает с именами файлов с пробелами тоже!
wisbucky
1
Это должен быть главный ответ. По общему признанию, объяснение, почему {$ i%. *} Не простое, но если вы можете отложить это в сторону и просто «использовать», вы можете быстро изменить его в соответствии с требованиями. Например, я преобразовал сотни .mp4 (с именами файлов, имеющими пробелы и специальные символы) в меньший формат, используя: for i in .mp4; do ffmpeg -i "$ i" -s 512x288 -c: копия "$ {i%. } .m4v"; сделано
Тони М
1
Чтобы сделать еще один шаг вперед, вы можете использовать подстановку параметров Bash, если хотите заменить строку «x265» на «x264», если вы транскодируете с H.265 на H.264, что является распространенным случаем использования. for f in *.mkv; do ffmpeg -i "$f" -map 0 -movflags faststart -c:v libx264 -c:a copy -c:s copy "${f/x265/x264}"; done
Трэвис Runyard
70

И на Windows:

FOR /F "tokens=*" %G IN ('dir /b *.flac') DO ffmpeg -i "%G" -acodec mp3 "%~nG.mp3"
LXS
источник
19
если вы запускаете эту команду в пакетном (.bat) файле, вам нужно удвоить знак% => %%
hB0
Любая идея, как запустить эту команду, но скопировать в новый файл, который содержит метаданные исходного файла?
Barryman9000
@ Barryman9000 это было давным-давно, но я думаю, что есть опция выходного файла, которую вы могли бы передать
lxs
@lxs спасибо за продолжение. В итоге я сделал это с помощью Powershell, изменив имя нового файла на дату создания исходного файла stackoverflow.com/a/35671099/197472
Barryman9000
Использовал его для удаления метаданных. Но это дает мне доступ отказано в ошибке. Поэтому я изменил имя выходного файла с дополнительным пробелом, чтобы сделать его новым файлом. FOR /F "tokens=*" %G IN ('dir /b *.mp3') DO ffmpeg -i "%G" -map_metadata -1 -c:v copy -c:a copy "%~nG .mp3"
Джунаид
28

Легко сделать однострочный сценарий bash - замените его *.aviтипом файла:

for i in *.avi; do ffmpeg -i "$i" -qscale 0 "$(basename "$i" .avi)".mov  ; done
желток
источник
Кодировщик по умолчанию для .mov - libx264 (если доступен), но этот кодировщик игнорирует -qscale. Удалите его и используйте настройки по умолчанию или используйте -crfвместо него (по умолчанию это -crf 23).
Llogan
1
Если в имени файла есть пробелы, команда потерпит неудачу, поскольку basenameподоболочка с обратным символом не заключена в кавычки . Именно поэтому bash имеет расширение оболочки: для i в * .avi; do ffmpeg -i "$ i" -qscale 0 "$ (базовое имя" $ i ".avi)". mov; сделано
Calimo
спасибо @Calimo полностью согласен - я обновил свой ответ
желток
22

Для преобразования с подкаталогами используйте, например,

find . -exec ffmpeg -i {} {}.mp3 \;
user2707001
источник
Я использовал это, в сочетании с этим ответом, чтобы преобразовать VTT в SRT, чтобы получить отличный эффект. find -name "*.vtt" -exec ffmpeg -i {} {}.srt \;
Grooveplex
Я эту команду, с небольшим модификацией для преобразования всех mp4 в mp3:find *.mp4 -exec ffmpeg -i {} {}.mp3 \;
swdev
1
Или, если вы хотите конвертировать файлы нескольких типов:find . -name *.ogg -or -name *.wma -exec ffmpeg -i {} {}.mp3 \;
bonh
Конвертируйте все файлы wma в mp3 и после их удаления:find . -name *.wma -exec ffmpeg -i {} {}.mp3 \; -exec rm {} \;
Panagiotis
21

Для 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.

shubhamr238
источник
18

Для тех, кто хочет что-то пакетно конвертировать с помощью ffmpeg, но хотел бы иметь удобный интерфейс Windows, я разработал этот интерфейс:

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

Он добавляет в ffmpeg интерфейс моды окна, индикаторы выполнения и оставшееся время, функции, которые я всегда упускал при использовании ffmpeg.

Eibel
источник
Хорошо, это хороший проект! Я целый час гонялся за хвостом, пытаясь заставить ffmpeg принять относительный путь к файлу в Windows, и это похоже на обман. РЕДАКТИРОВАТЬ: я использовал это, чтобы конвертировать .xwm в
.flac
6

Если у вас есть GNU параллельно, вы можете конвертировать все файлы .avi ниже vid_dirв mp4 параллельно, используя все, кроме одного из ваших процессорных ядер с

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

Чтобы конвертировать из / в разные форматы, измените '*.avi'или по .mp4мере необходимости. Параллель GNU указана в большинстве репозиториев дистрибутивов Linux в пакете, который обычно называется parallel.

sebbit
источник
не могли бы вы сделать то же самое, добавив !в конец одну из строк строки bash?
19
3

Я знаю, что это может быть избыточно, но я использую этот скрипт для пакетного преобразования файлов.

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можете конвертировать его, вы можете указать любые два расширения.

Александр Луна
источник
Это лучшее 👍
Андреас Пранг
3

Это немного похоже на Code Golf, но так как почти все ответы пока что bash (за исключением одного одиночного cmd), вот кроссплатформенная команда windows, которая использует powershell (потому что это здорово):

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

Вы можете изменить * .avi на то, что соответствует исходному материалу.

STIB
источник
3

Конечно, в настоящее время PowerShell пришел вместе, специально разработан , чтобы сделать что - то точно , как это очень легко.

И да, PowerShell также доступен в других операционных системах, кроме Windows, но он предустановлен в Windows, так что это должно быть полезно для всех.

Сначала вы захотите перечислить все файлы в текущем каталоге, поэтому мы начнем с:

ls

Вы также можете использовать, ls -Recurseесли вы хотите рекурсивно конвертировать все файлы в подкаталогах тоже.

Затем мы отфильтруем их по типу файлов, которые мы хотим преобразовать, например, «avi».

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

После этого мы передадим эту информацию в FFmpeg через ForEach.

Для ввода FFmpeg мы будем использовать FullName- это полный путь к файлу. А для вывода FFmpeg'овской библиотеки мы будем использовать Name- но заменяя.avi на конце .mp3. Итак, это будет выглядеть примерно так:

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

Итак, давайте соберем все это вместе, и вот результат:

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

Это преобразует все файлы ".avi" в файлы ".mp3" через FFmpeg, просто замените три кавычки, чтобы решить, какой тип преобразования вы хотите, и не стесняйтесь добавлять любые другие аргументы в FFmpeg в ForEach.

Вы можете сделать еще один шаг и добавить Remove-Itemв конец, чтобы автоматически удалять старые файлы.

Если ffmpegего нет в вашем пути, и он на самом деле находится в каталоге, в котором вы сейчас находитесь, пишите ./ffmpegвместо простого ffmpeg.

Надеюсь, это кому-нибудь поможет.

ABPerson
источник
1
PowerShell великолепен, спасибо! Если у кого-то возникнут проблемы с запуском этого: поместите эту команду в .ps1файл, а не в .batфайл. Вам придется работать Set-ExecutionPolicy RemoteSignedот имени администратора, если вы никогда ранее не запускали сценарий PS.
звездная пауза
Ну, в общем, я просто думал о том, чтобы запустить его прямо в PowerShell, так что я на самом деле не думал об этом! Хороший совет, хотя!
ABPerson
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

Пакетная обработка flacфайлов в mp3(безопасно для имен файлов с пробелами) с использованием [1] [2]

Сезар Д. Веландия
источник
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, если хотите, но если у вас нет действительно хорошей акустической системы, это бесполезно

user151496
источник
1

Если вам нужен графический интерфейс для пакетной обработки с помощью ffmpegX, попробуйте Quick Batcher . Это бесплатно и примет ваши последние настройки ffmpegX, чтобы конвертировать файлы, которые вы вставили в него.

Обратите внимание, что вы не можете перетаскивать папки на Quick Batcher. Так что выберите файлы и затем поместите их через Quick Batcher.

Нирав Мехта
источник
2
Программное обеспечение «Quick Batcher» предназначено ТОЛЬКО для MAC OS
Мохаммад ЭльНеср
1

Только этот работал для меня, пожалуйста, обратите внимание, что вам нужно вручную создать папку «newfiles», где находится файл ffmpeg.exe.

Конвертировать . файлы в .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

надеюсь, это помогло 🙏.

Mehrdad995
источник
0

Это создаст MP4 видео из всех файлов JPG из текущего каталога.

echo exec("ffmpeg -framerate 1/5 -i photo%d.jpg -r 25 -pix_fmt yuv420p output.mp4");
thesachinparmar
источник
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"
Halligallator
источник
Это ответ или попытка опубликовать новый вопрос в качестве ответа? В последнем случае, пожалуйста, создайте совершенно новый вопрос, хотя, возможно, вернитесь сюда для справки.
tripleee
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-файлы в этой папке.

вызывает MY (смените на ваше) ffmpeg, передает имя ввода, настройки для изменения масштаба с резкостью. Мне не нужны CRF и " -b:v 1024k" ...

Выходной файл - это входной файл минус расширение, с mp4 в качестве нового ext.

Морфи
источник
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

Это преобразует во временный файл, а затем заменяет оригинальный, так что имена остаются неизменными после преобразования.

user1634000
источник
0

Также, если вы хотите такое же преобразование в подпапках. вот рекурсивный код

for /R "folder_path" %%f in (*.mov,*.mxf,*.mkv,*.webm) do (
    ffmpeg.exe -i "%%~f" "%%~f.mp4"
    )
Хасан Йилмаз
источник
-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' ) );
}
hanshenrik
источник
2
Ответ очень ограничен, поскольку пользователь должен установить PHP на своем компьютере. Ответы командной строки и командного файла намного проще и гораздо менее сложны.
ProfK
2
@ProfK PHP - один из самых популярных языков на SO - во-вторых, ответ Исаака на sh несколько ненадежен, так как он может переименовать ваши файлы во что-то, отличное от оригинала, например, он не сохраняет символы новой строки в имени файла. Сценарий летучей мыши lyx еще хуже, он полностью игнорирует любой файл с символами новой строки в имени. не уверен, почему, даже не синтаксическая ошибка или что-то, но это делает (проверено на win10). Мой PHP-скрипт не имеет проблем, спасибо escapeshellarg(), и работает как на Windows, так и на Linux. Я согласен, это крайний случай, хотя.
hanshenrik
-1

Другое простое решение, которое еще не было предложено, заключается в использовании xargs:

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

Одна небольшая ошибка - неудобное именование выходных файлов (например input.avi.mp4). Возможный обходной путь для этого может быть:

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

telenachos
источник
У shellcheck.net есть несколько предложений относительно ваших примеров.
Llogan
mywiki.wooledge.org/ParsingLs хотя вы можете просто заменить lsс printf '%s\n'здесь.
tripleee