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


190

Як перетворити весь каталог / папку з ffmpeg за допомогою командного рядка або за допомогою пакетного сценарію?

Відповіді:


174

Попередня відповідь створить лише 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
Вау, ця відповідь неймовірно складна. Дивіться одну з однорядних відповідей.
foobarbecue

2
це підтримка .batв Windows?
Jazuly

294

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

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

2
Це ідеально, дякую! Ось повна команда, яка в мене вийшла чудово: for i in * .avi; виконайте 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; зробіть 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
Travis Runyard

70

А в Windows:

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

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 має розширення оболонки замість: for i in * .avi; do ffmpeg -i "$ i" -qscale 0 "$ (базове ім'я" $ i ".avi)". mov; виконано
Калімо

дякую @Calimo повністю згоден - я оновив свою відповідь
жовток

22

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

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

Я використовував це в поєднанні з цією відповіддю для перетворення ВТТ в 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

20

Для Windows:

Тут я конвертую всі (.mp4) файли в (.mp3) файли.
Просто відкрийте cmd, перейдіть до потрібної папки та введіть команду.

Ярлик: (необов’язково)
1. Перейдіть у папку, де є ваші (.mp4) файли
2. Натисніть клавішу Shift та клацніть лівою кнопкою миші та виберіть "Відкрити вікно PowerShell Here"
або "Open Open Command Window Here"
3. Введіть "cmd" [ПРИМІТКА : Пропустіть цей крок, якщо він безпосередньо відкриє cmd замість PowerShell]
4. Запустіть команду

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

Якщо ви хочете помістити це в пакетний файл в Windows 10, вам потрібно використовувати %% i.


18

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

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

Це додає ffmpeg інтерфейс віконної моди, панелі прогресу та інформацію про час, що залишився, функції, які я завжди пропускав під час використання ffmpeg.


Добре, це приємний проект! Я протягом години переслідував свій хвіст, намагаючись змусити ffmpeg прийняти відносний шлях до виходу в Windows, і це відчуває себе як обман. EDIT: я використав це для перетворення .xwm в .flac
semtex41

6

Якщо у вас 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.


ти не міг би зробити те ж саме, додавши !до кінця будь-яку з однотонних лайнерів?
стиб

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

Тут трохи схожий на кодовий гольф, але оскільки майже всі відповіді на сьогоднішній день є баш (забороняючи один самотній cmd один), ось команда Windows для крос-платформи, яка використовує powerhell (бо приголомшливо):

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

Ви можете змінити * .avi на те, що відповідає вашим вихідним відео.


3

Звичайно, зараз з'явився PowerShell, спеціально розроблений, щоб зробити щось саме подібне надзвичайно просто.

І так, PowerShell також доступний в інших операційних системах, окрім Windows, але він попередньо встановлений у Windows, тому це повинно бути корисним для всіх.

По-перше, ви захочете перерахувати всі файли в поточному каталозі, тому ми почнемо з:

ls

Ви також можете використовувати, ls -Recurseякщо ви хочете рекурсивно конвертувати всі файли і в підкаталогах.

Потім ми відфільтруємо їх лише до того типу файлу, який ми хочемо конвертувати - наприклад, "avi".

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

Після цього ми передамо цю інформацію FFmpeg через a 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 .

Сподіваюсь, це допомагає комусь.


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, якщо хочете, але якщо у вас є справді хороша акустична система, це нічого не варто


1

Якщо ви хочете, щоб графічний інтерфейс здійснював пакетний процес із ffmpegX, спробуйте Quick Batcher . Це безкоштовно і забирає ваші останні налаштування ffmpegX для перетворення файлів, які ви впадаєте в нього.

Зауважте, що ви не можете перетягувати папки на Quick Batcher. Отже, виберіть файли та перенесіть їх через Швидкий Batcher.


2
Програмне забезпечення "Швидкий дозатор" ТІЛЬКИ для ОС MAC
Mohammad ElNesr

1

Лише цей працював для мене, pls зауважте, що вам потрібно створити папку "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

сподіваюся, що це допомогло 🙏.


0

Це створить mp4 відео з усіх файлів jpg з поточного каталогу.

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

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"

Це відповідь чи спроба поставити нове запитання як відповідь? В останньому випадку, будь ласка, створіть зовсім нове запитання замість цього, хоча можливо, посилаючись тут на задній план.
трійка

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

Це перетворюється у тимчасовий файл, а потім замінює оригінал, тому імена залишаються однаковими після перетворення.


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

2
Відповідь щодо обмеженого діапазону, оскільки користувач повинен мати PHP, встановлений на своїй машині. Відповіді командного рядка та пакетного файлу набагато простіші та набагато менш складні.
ПрофК

2
@ProfK PHP - одна з найпопулярніших мов на SO - по-друге, відповідь Ісаака для sh є дещо недостовірною, оскільки він може перейменувати ваші файли на щось інше, ніж оригінал, наприклад, він не зберігає нові рядки у назві файлу. Скрипт bat- файлу 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""


shellcheck.net має кілька пропозицій щодо ваших прикладів.
llogan

mywiki.wooledge.org/ParsingLs, хоча ви можете просто замінити lsїх printf '%s\n'тут.
трійка
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.