Of course, now PowerShell has come along, specifically designed to make something exactly like this extremely easy.
And, yes, PowerShell is also available on other operating systems other than just Windows, but it comes pre-installed on Windows, so this should be useful to everyone.
First, you’ll want to list all of the files within the current directory, so, we’ll start off with:
ls
You can also use ls -Recurse
if you want to recursively convert all files in subdirectories too.
Then, we’ll filter those down to only the type of file we want to convert — e.g. «avi».
ls | Where { $_.Extension -eq ".avi" }
After that, we’ll pass that information to FFmpeg through a ForEach
.
For FFmpeg’s input, we will use the FullName
— that’s the entire path to the file. And for FFmpeg’s output we will use the Name
— but replacing the .avi
at the end with .mp3
. So, it will look something like this:
$_.Name.Replace(".avi", ".mp3")
So, let’s put all of that together and this is the result:
ls | Where { $_.Extension -eq ".avi" } | ForEach { ffmpeg -i $_.FullName $_.Name.Replace(".avi", ".mp3") }
That will convert all «.avi» files into «.mp3» files through FFmpeg, just replace the three things in quotes to decide what type of conversion you want, and feel free to add any other arguments to FFmpeg within the ForEach
.
You could take this a step further and add Remove-Item
to the end to automatically delete the old files.
If ffmpeg
isn’t in your path, and it’s actually in the directory you’re currently in, write ./ffmpeg
there instead of just ffmpeg
.
Hope this helps anyone.
У меня есть код для одного файла.
ffmpeg -i "sample.webm" -vn -ab 320k -ar 44100 "sample.mp3"
Но файлов много, а времени мало. Есть ли возможность сконвертировать все файлы из папки одной командой командной строки? Спасибо за ответ!
-
Вопрос заданболее трёх лет назад
-
2026 просмотров
В cmd, перейдите в каталог с файлами и выдайте эту команду и будет вам счастье:
for %a in (*.webm) do ffmpeg -i «%a» -vn -ab 320k -ar 44100 «%~dpna.mp3»
Пригласить эксперта
-
Показать ещё
Загружается…
04 февр. 2023, в 15:56
2500 руб./за проект
04 февр. 2023, в 15:46
200 руб./за проект
04 февр. 2023, в 15:45
200000 руб./за проект
Минуточку внимания
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
for i in *.mkv; do ffmpeg -i «$i» … ;done | |
for i in *.avi; do ffmpeg -i «$i» -qscale 0 «$(basename «$i» .avi)».mov ; done | |
for i in *.mkv; | |
do ffmpeg -i «$i» -c:v copy -c:a aac «${i%.*}.mp4»; | |
done; | |
//////////////////////////////////////// | |
///////////########## https://trac.ffmpeg.org/wiki/AudioChannelManipulation | |
####CONVERT WITH MONO AUDIO FROM LEFT CHANNEL#### | |
ffmpeg -i video-inform.mp4 -c:v copy -c:a aac -map_channel 0.1.0 video-inform-ff2.mp4 | |
ffmpeg -i video-inform.mp4 -c:v copy -c:a aac -map_channel 0.1.0 -map_channel 0.1.0 video-inform-ff2.mp4 | |
// ffmpeg -i video-inform.mp4 -c:v copy -c:a aac -map_channel 0.1.0 -map_channel 0.1.1 video-inform-ff2.mp4 | |
ffmpeg -i video-inform.mp4 -c:v copy -c:a aac -af «pan=stereo|c0=c0|c1=c0» video-inform-ff2.mp4 | |
//////////////////////////////// | |
ffmpeg -i input.mkv -c:a copy -s hd720 output.mkv | |
#### CONVERT 360 ####### | |
#!/bin/bash | |
DIR=»SRC/2″ | |
cd «$DIR» | |
for vid in *.*; | |
do ffmpeg -i «$vid» -map 0:0 -map 0:1 -map 0:2 -map 0:3 -map 0:4 -c:v libx264 -preset fast -vf scale=640:360 -c:a aac «../../CONV/360/${vid%.MOV}-360.mp4»; | |
# mv SRC/2/*-360.mp4 CONV/360/ | |
done; | |
#### CONVERT 1080 ####### | |
for vid in SRC/2/*.MOV; | |
do ffmpeg -i «$vid» -map 0:0 -map 0:1 -map 0:2 -map 0:3 -map 0:4 -c:v libx264 -preset fast -vf scale=1920:1080 -c:a aac «${vid%.MOV}-1080.mp4»; | |
mv SRC/2/*-1080.mp4 CONV/1080/ | |
done; | |
Скрипт для FFMpeg, конвертация всех файлов в одном каталоге (папке)
Script for FFMpeg, convert all the files in one directory (folder)
С помощью ffmpeg вы можете конвертировать почти все видео файлы. И поскольку это конвертер командной строки, вы можете конвертировать ваши файлы сразу с помощью базового сценария windows из командной строки. Подобно преобразованию всех видео файлов из одного каталога / директории в формат avi, вы сможете конвертировать и в другие форматы, без рутины переписывания командной строки.
Приведу пару примеров, для начинающего пользователя FFmpeg, которыми разумеется не ограничиваются возможности и мощь данного конвертера.
Если вы еще не скачали конвертер, то это можно сделать ТУТ
Пример 1. Настройка ffmpeg и его проверка
1. Для того чтобы не писать полный путь к конвертеру, укажем его в переменных средах. Где пропишем путь до файла запуска
2. Запускаем командную строку и проверяем на работоспособность, введя команду
ffmpeg -version
Пример 2. Конвертация нескольких файлов из одного каталога / директории
1. Создаем *.bat файл со следующим содержанием:
for %%a in («*.*») do ffmpeg -i «%%a» -map 0:0 -map 0:1 -f avi -s 1280×720 -vcodec libx264 -vb 1648k -ac 2 -ar 44100 -acodec libmp3lame -ab 128k -sn -y «newfiles%%~na.avi»
pause
Где первая строка отвечает за конвертацию всех файлов с желаемыми параметрами и дальнейшим помещением их в каталог newfolder.
Pause — на случай ошибки и непредвиденного закрытия окна командной строки
2. Помещаем наш *.bat файл в каталог с видео файлами и там же создаем каталог new_folder
3. После запуска *.bat файла начнется конвертация, а файлы с результатом будут помещаться в новый каталог.
I have a ffmpeg command that will happily process all video files in a folder one by one, but how can i make it process them simultaneously?
here’s my current command:
for i in *.mov; do name=``echo $i | cut -d'.' -f1``; echo $name; TIMECODE=$(ffprobe "$i" -v error -show_entries stream_tags=timecode -of default=noprint_wrappers=1:nokey=1 | awk -F: '{ print $1 "\:" $2 "\:" $3 "\:" $4 }') ; ffmpeg -i "$i" -vf "trim=start_frame=192,setpts=PTS-STARTPTS,scale=1280:-1:force_original_aspect_ratio=decrease,drawtext=fontfile=/usr/share/fonts/truetype/droid/DroidSansMono.ttf: fontsize=28: timecode='00:00:00:00': r=24: x=(w-tw)/2: y=25: fontcolor=white: box=1: boxcolor=0x00000099" -threads 4 -c:v mpeg1video -b:v 5000k -af "atrim=start=8,asetpts=PTS-STARTPTS" -c:a libmp3lame -b:a 192k "${name}_mpeg1.mpeg"
stib
13.5k1 gold badge31 silver badges53 bronze badges
asked May 22, 2017 at 9:26
All that you need is to put an & at the end of the ffmpeg command line. This will make the ffmpeg process to run in background, allowing it to be executed simultaneously with other processes.
#!/bin bash
# add this code to a file called encode or whatever you want
# make it executable: chmod ugo+x encode
# and you are ready to run: ./encode
for i in *.mov; do
name=``echo $i | cut -d'.' -f1``;
echo $name;
TIMECODE=$(ffprobe "$i" -v error -show_entries stream_tags=timecode -of default=noprint_wrappers=1:nokey=1 | awk -F: '{ print $1 "\:" $2 "\:" $3 "\:" $4 }') ;
ffmpeg -i "$i" -vf "trim=start_frame=192,setpts=PTS-STARTPTS,scale=1280:-1:force_original_aspect_ratio=decrease,drawtext=fontfile=/usr/share/fonts/truetype/droid/DroidSansMono.ttf: fontsize=28: timecode='00:00:00:00': r=24: x=(w-tw)/2: y=25: fontcolor=white: box=1: boxcolor=0x00000099" -threads 4 -c:v mpeg1video -b:v 5000k -af "atrim=start=8,asetpts=PTS-STARTPTS" -c:a libmp3lame -b:a 192k "${name}_mpeg1.mpeg" &;
# limit ffmpeg processes to 5
while [$(ps | grep ffmpeg | wc -l) -eq 5]; do
echo "ffmpeg queue is full, waiting...";
# amount of seconds to wait till we check again
sleep 10;
done
done;
answered May 22, 2017 at 13:08
2
Put it into a flexible wrapper script
There’s a few benefits to doing it this way, for example, the provided script;
- Uses
find
and array variables to handle complex and crazy filenames, and the process management - Records the process ID’s as it spawns
ffmpeg
and then periodically checks them if they are active - If a file already exists in it’s desired output form (i.e. file_mpeg1.mpeg), that file is skipped; this prevents saying running a loop of 100 files, failing for some reason after 90 files, and then re-running the whole thing from the start. (there is however no check at this stage to see if the existing file was complete or not. This goes a bit deeper into error checking / maybe a length compare based on original / an ffprobe, etc… )
- The flexible template allows you easily manipulate the flow.
I tested it to process 4 random files downloaded off youtube:
As you can see it handles silly filenames quite well.
Here is the wrapper script based on your commands:
The syntax is: ./scriptname.sh [ext] [maxprocesses]
- So, to look to look for *.mov files and run 5 processes:
- If the script name was
script.sh
, then you’d run./script.sh mov 5
- If the script name was
Wrapper Script:
#!/usr/bin/env bash
ffprocess () {
file="$1"
output="$2"
TIMECODE=$(ffprobe "$file" -v error -show_entries stream_tags=timecode -of default=noprint_wrappers=1:nokey=1 | awk -F: '{ print $1 "\:" $2 "\:" $3 "\:" $4 }')
ffmpeg -i "$file"
-vf "trim=start_frame=192,setpts=PTS-STARTPTS,scale=1280:-1:force_original_aspect_ratio=decrease,drawtext=fontfile=/usr/share/fonts/truetype/droid/DroidSansMono.ttf: fontsize=28: timecode='00:00:00:00': r=24: x=(w-tw)/2: y=25: fontcolor=white: box=1: boxcolor=0x00000099"
-threads 4
-c:v mpeg1video
-b:v 5000k
-af "atrim=start=8,asetpts=PTS-STARTPTS"
-c:a libmp3lame -b:a 192k
"${output}"
}
#This function gets called when a process is no longer valid and needs removing from the array
removeps () {
trtmp=()
for tmpps in "${ffpsid[@]}"
do
[[ $tmpps != "$1" ]] && trtmp+=($tmpps)
done
ffpsid=("${trtmp[@]}")
unset trtmp
return
}
#Checks to see if each process is still active
checkffpsid () {
for ffps in "${ffpsid[@]}"
do
ps -p $ffps > /dev/null || removeps "$ffps"
done
}
if [[ "$#" -lt 2 ]]; then echo -e "Usage: $0 [ext] [maxproc]ni.e. $0 .mov 5" ; exit ; fi
ext="$1"
maxproc="$2"
find . -maxdepth 1 -iname "*.$ext" > inputlist.txt # Find files with ext specified
IFS=$'n' read -rd '' -a filelist <<<"$(cat inputlist.txt)"
for file in "${filelist[@]}"
do
name=$(basename "$file")
name="${name%.*}" # remove ext for name var
outname="${name}_mpeg1.mpeg" # Set output name
checkffpsid
if [ -f "$outname" ]
then
echo "$outname" already exists, skipping ...
else
until [[ "${#ffpsid[@]}" -le "$maxproc" ]]
do
checkffpsid
sleep 5
done
ffprocess "$file" "$outname" & ffpsid+=("$!")
fi
done
Just a couple notes
- Your «$TIMECODE» variable never gets used … This is as per your original script.
- You’re better off letting
ffmpeg
manage its own threads by passing-threads 0
instead of 4
answered May 23, 2017 at 1:41
I have a ffmpeg command that will happily process all video files in a folder one by one, but how can i make it process them simultaneously?
here’s my current command:
for i in *.mov; do name=``echo $i | cut -d'.' -f1``; echo $name; TIMECODE=$(ffprobe "$i" -v error -show_entries stream_tags=timecode -of default=noprint_wrappers=1:nokey=1 | awk -F: '{ print $1 "\:" $2 "\:" $3 "\:" $4 }') ; ffmpeg -i "$i" -vf "trim=start_frame=192,setpts=PTS-STARTPTS,scale=1280:-1:force_original_aspect_ratio=decrease,drawtext=fontfile=/usr/share/fonts/truetype/droid/DroidSansMono.ttf: fontsize=28: timecode='00:00:00:00': r=24: x=(w-tw)/2: y=25: fontcolor=white: box=1: boxcolor=0x00000099" -threads 4 -c:v mpeg1video -b:v 5000k -af "atrim=start=8,asetpts=PTS-STARTPTS" -c:a libmp3lame -b:a 192k "${name}_mpeg1.mpeg"
stib
13.5k1 gold badge31 silver badges53 bronze badges
asked May 22, 2017 at 9:26
All that you need is to put an & at the end of the ffmpeg command line. This will make the ffmpeg process to run in background, allowing it to be executed simultaneously with other processes.
#!/bin bash
# add this code to a file called encode or whatever you want
# make it executable: chmod ugo+x encode
# and you are ready to run: ./encode
for i in *.mov; do
name=``echo $i | cut -d'.' -f1``;
echo $name;
TIMECODE=$(ffprobe "$i" -v error -show_entries stream_tags=timecode -of default=noprint_wrappers=1:nokey=1 | awk -F: '{ print $1 "\:" $2 "\:" $3 "\:" $4 }') ;
ffmpeg -i "$i" -vf "trim=start_frame=192,setpts=PTS-STARTPTS,scale=1280:-1:force_original_aspect_ratio=decrease,drawtext=fontfile=/usr/share/fonts/truetype/droid/DroidSansMono.ttf: fontsize=28: timecode='00:00:00:00': r=24: x=(w-tw)/2: y=25: fontcolor=white: box=1: boxcolor=0x00000099" -threads 4 -c:v mpeg1video -b:v 5000k -af "atrim=start=8,asetpts=PTS-STARTPTS" -c:a libmp3lame -b:a 192k "${name}_mpeg1.mpeg" &;
# limit ffmpeg processes to 5
while [$(ps | grep ffmpeg | wc -l) -eq 5]; do
echo "ffmpeg queue is full, waiting...";
# amount of seconds to wait till we check again
sleep 10;
done
done;
answered May 22, 2017 at 13:08
2
Put it into a flexible wrapper script
There’s a few benefits to doing it this way, for example, the provided script;
- Uses
find
and array variables to handle complex and crazy filenames, and the process management - Records the process ID’s as it spawns
ffmpeg
and then periodically checks them if they are active - If a file already exists in it’s desired output form (i.e. file_mpeg1.mpeg), that file is skipped; this prevents saying running a loop of 100 files, failing for some reason after 90 files, and then re-running the whole thing from the start. (there is however no check at this stage to see if the existing file was complete or not. This goes a bit deeper into error checking / maybe a length compare based on original / an ffprobe, etc… )
- The flexible template allows you easily manipulate the flow.
I tested it to process 4 random files downloaded off youtube:
As you can see it handles silly filenames quite well.
Here is the wrapper script based on your commands:
The syntax is: ./scriptname.sh [ext] [maxprocesses]
- So, to look to look for *.mov files and run 5 processes:
- If the script name was
script.sh
, then you’d run./script.sh mov 5
- If the script name was
Wrapper Script:
#!/usr/bin/env bash
ffprocess () {
file="$1"
output="$2"
TIMECODE=$(ffprobe "$file" -v error -show_entries stream_tags=timecode -of default=noprint_wrappers=1:nokey=1 | awk -F: '{ print $1 "\:" $2 "\:" $3 "\:" $4 }')
ffmpeg -i "$file"
-vf "trim=start_frame=192,setpts=PTS-STARTPTS,scale=1280:-1:force_original_aspect_ratio=decrease,drawtext=fontfile=/usr/share/fonts/truetype/droid/DroidSansMono.ttf: fontsize=28: timecode='00:00:00:00': r=24: x=(w-tw)/2: y=25: fontcolor=white: box=1: boxcolor=0x00000099"
-threads 4
-c:v mpeg1video
-b:v 5000k
-af "atrim=start=8,asetpts=PTS-STARTPTS"
-c:a libmp3lame -b:a 192k
"${output}"
}
#This function gets called when a process is no longer valid and needs removing from the array
removeps () {
trtmp=()
for tmpps in "${ffpsid[@]}"
do
[[ $tmpps != "$1" ]] && trtmp+=($tmpps)
done
ffpsid=("${trtmp[@]}")
unset trtmp
return
}
#Checks to see if each process is still active
checkffpsid () {
for ffps in "${ffpsid[@]}"
do
ps -p $ffps > /dev/null || removeps "$ffps"
done
}
if [[ "$#" -lt 2 ]]; then echo -e "Usage: $0 [ext] [maxproc]ni.e. $0 .mov 5" ; exit ; fi
ext="$1"
maxproc="$2"
find . -maxdepth 1 -iname "*.$ext" > inputlist.txt # Find files with ext specified
IFS=$'n' read -rd '' -a filelist <<<"$(cat inputlist.txt)"
for file in "${filelist[@]}"
do
name=$(basename "$file")
name="${name%.*}" # remove ext for name var
outname="${name}_mpeg1.mpeg" # Set output name
checkffpsid
if [ -f "$outname" ]
then
echo "$outname" already exists, skipping ...
else
until [[ "${#ffpsid[@]}" -le "$maxproc" ]]
do
checkffpsid
sleep 5
done
ffprocess "$file" "$outname" & ffpsid+=("$!")
fi
done
Just a couple notes
- Your «$TIMECODE» variable never gets used … This is as per your original script.
- You’re better off letting
ffmpeg
manage its own threads by passing-threads 0
instead of 4
answered May 23, 2017 at 1:41
I’m trying to batch encode 45 video files, and copy the encoded files into an existing subfolder called «encode»
I’ve used the suggested code from this question (https://stackoverflow.com/questions/5784661/how-do-you-convert-an-entire-directory-with-ffmpeg) But, I don’t know how to capture the original file names (with spaces and punctuation) and use that as the new file name in the new directory.
Here’s the code I’m using so far:
for i in *.mp4;
do name=`echo "${i%.*}"`;
echo $name;
ffmpeg -i “$i” -vf "scale='if(gt(a*sar,16/9),640,-1)':'if(gt(a*sar,16/9),-1,360)',pad=640:360:(ow-iw)/2:(oh-ih)/2,setsar=1" -vcodec libx264 -b:v 1600k -bufsize:v 1600k -r 30000/1001 “encoded/$name.mp4”
done
It’s giving me an «invalid argument» error message when I run it — probably because I haven’t specified the names correctly(?)
The ffmpeg code that I’m using does work (I can encode individual file) but I haven’t figured out how to batch encode the entire directory.
If anyone can let me know what I’m doing wrong, I would love to know!
Thank you!
-
FFMPEG — мощная, кроссплатформенная утилита с открытым исходным кодом, для конвертирования видео и аудио файлов из одного формата в другой.
FFMPEG может собирать из набора изображений видео или GIF анимацию.
А также может конвертировать видео в GIF.
Чтобы скачать данную утилиту для Windows, нужно зайти на сайт: https://ffmpeg.org/download.html
Далее выбираем «Windows builds by BtbN».
В списке релизов ищем win64-gpl.zip или win64-lgpl.zip и скачиваем архив.
Распаковываем архив в удобное место, например в папку D:ffmpeg
Из архива нужны только файлы ffmpeg.exe, ffplay.exe, ffprobe.exe их можно найти в папке bin.
Для работы с программой используется командная строка Windows или BAT файлы.
В папке с файлами создаём cropvideo.bat файл с следующим кодом:
ffmpeg -i input.mp4 -b:v 4M -filter:v "crop=in_w-140:in_h-140" -c:a copy out.mp4
Пути к файлам для конвертации, нужно указывать через обратные слеши «».
Данный скрипт обрежет(сделает Crop) видео по краям на 140px со всех сторон.
Параметр -b:v отвечает за битрейт входного видео.
Запускаем батник и через несколько секунд вы получите кропнутое видео.
Конвертирование WAV в MP3 при помощи FFMPEG
BAT файл:
ffmpeg -i input-file.wav -vn -ar 44100 -ac 2 -b:a 256k output-file.mp3
Параметр -ar задаёт частоту дискретизации, -b:a задаёт битрейт аудио файла.
Конвертирование AVI в mp4
ffmpeg -i input_file.avi output_file.mp4
Пакетное конвертирование MP4 в GIF | FFMPEG(Windows)
for %%a in ("D:video*.mp4") do ffmpeg -i "%%a" -vf "fps=25" -s 1280x720 "D:videogif%%~na.gif"
Данный BATCH(bat) скрипт конвертирует все файлы формата .mp4 из папки D:video в GIF анимацию.
GIF файлы будут лежать в папке D:videogif
Название будет как у .mp4 файлов, а расширение .gif
Параметр fps отвечает за количество кадров.
Чем больше FPS — тем плавнее анимация, но больше размер файла.
Параметр -s, это разрешение.
Если нужно обрезать изображение перед конвертацией в GIF:
for %%a in ("D:video*.mp4") do ffmpeg -i "%%a" -vf "fps=25,crop=in_w-200:in_h-200" -s 1280x720 "D:videogif%%~na.gif"
in_w-по ширине
in_h-по высоте
BAT скрипты нужно запускать из папки с программой FFMPEG.