Extract Creation date and time of multiple files at once [duplicate] - ffmpeg

How do you convert an entire directory/folder with ffmpeg via command line or with a batch script?

For Linux and macOS this can be done in one line, using parameter expansion to change the filename extension of the output file:
for i in *.avi; do ffmpeg -i "$i" "${i%.*}.mp4"; done

Previous answer will only create 1 output file called out.mov. To make a separate output file for each old movie, try this.
for i in *.avi;
do name=`echo "$i" | cut -d'.' -f1`
echo "$name"
ffmpeg -i "$i" "${name}.mov"
done

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

For Windows:
Here I'm Converting all the (.mp4) files to (.mp3) files.
Just open cmd, goto the desired folder and type the command.
Shortcut: (optional)
1. Goto the folder where your (.mp4) files are present
2. Press Shift and Left click and Choose "Open PowerShell Window Here"
or "Open Command Prompt Window Here"
3. Type "cmd" [NOTE: Skip this step if it directly opens cmd instead of PowerShell]
4. Run the command
for %i in (*.mp4) do ffmpeg -i "%i" "%~ni.mp3"
If you want to put this into a batch file on Windows 10, you need to use %%i.

A one-line bash script would be easy to do - replace *.avi with your filetype:
for i in *.avi; do ffmpeg -i "$i" -qscale 0 "$(basename "$i" .avi)".mov ; done

To convert with subdirectories use e.g.
find . -exec ffmpeg -i {} {}.mp3 \;

#Linux
To convert a bunch, my one liner is this, as example
(.avi to .mkv) in same directory:
for f in *.avi; do ffmpeg -i "${f}" "${f%%.*}.mkv"; done
please observe the double "%%" in the output statement. It gives you not only the first word or the input filename, but everything before the last dot.

For anyone who wants to batch convert anything with ffmpeg but would like to have a convenient Windows interface, I developed this front-end:
https://sourceforge.net/projects/ffmpeg-batch
It adds to ffmpeg a window fashion interface, progress bars and time remaining info, features I always missed when using ffmpeg.

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.

If you have GNU parallel you could convert all .avi files below vid_dir to mp4 in parallel, using all except one of your CPU cores with
find vid_dir -type f -name '*.avi' -not -empty -print0 |
parallel -0 -j -1 ffmpeg -loglevel fatal -i {} {.}.mp4
To convert from/to different formats, change '*.avi' or .mp4 as needed. GNU parallel is listed in most Linux distributions' repositories in a package which is usually called parallel.

Using multiple cores, this is the fastest way, (using parallel):
parallel "ffmpeg -i {1} {1.}.mp4" ::: *.avi

I know this might be redundant but I use this script to batch convert files.
old_extension=$1
new_extension=$2
for i in *."$old_extension";
do ffmpeg -i "$i" "${i%.*}.$new_extension";
done
It takes 2 arguments to make it more flexible :
the extension you want to convert from
the new extension you want to convert to
I create an alias for it but you can also use it manually like this:
sh batch_convert.sh mkv mp4
This would convert all the mkv files into mp4 files.
As you can see it slightly more versatile. As long as ffmpeg can convert it you can specify any two extensions.

The following script works well for me in a Bash on Windows (so it should work just as well on Linux and Mac). It addresses some problems I have had with some other solutions:
Processes files in subfolders
Replaces the source extension with the target extension instead of just appending it
Works with files with multiple spaces and multiple dots in the name
(See this answer for details.)
Can be run when the target file exists, prompting before overwriting
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
Example call:
$ sh ffmpeg-batch-convert.sh mp3 wav
As a bonus, if you want the source files deleted, you can modify the script like this:
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
Example call:
$ sh ffmpeg-batch-convert.sh mp3 wav delete

I use this for add subtitle for Tvshows or Movies on Windows.
Just create "subbed" folder and bat file in the video and sub directory.Put code in bat file and run.
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"
)

Getting a bit like code golf here, but since nearly all the answers so far are bash (barring one lonely cmd one), here's a windows cross-platform command that uses powershell (because awesome):
ls *.avi|%{ ffmpeg -i $_ <ffmpeg options here> $_.name.replace($_.extension, ".mp4")}
You can change *.avi to whatever matches your source footage.

Also if you want same convertion in subfolders.
here is the recursive code.
for /R "folder_path" %%f in (*.mov,*.mxf,*.mkv,*.webm) do (
ffmpeg.exe -i "%%~f" "%%~f.mp4"
)

for i in *.flac;
do name=`echo "${i%.*}"`;
echo $name;
ffmpeg -i "${i}" -ab 320k -map_metadata 0 -id3v2_version 3 "${name}".mp3;
done
Batch process flac files into mp3 (safe for file names with spaces) using [1] [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"
)
this is variable bitrate of quality 2, you can set it to 0 if you want but unless you have a really good speaker system it's worthless imo

Only this one Worked for me, pls notice that you have to create "newfiles" folder manually where the ffmpeg.exe file is located.
Convert . files to .wav audio
Code:
for %%a in ("*.*") do ffmpeg.exe -i "%%a" "newfiles\%%~na.wav"
pause
i.e if you want to convert all .mp3 files to .wav change ("*.*") to ("*.mp3").
The author of this script is :
https://forum.videohelp.com/threads/356314-How-to-batch-convert-multiplex-any-files-with-ffmpeg
hope it helped 🙏.

For giggles, here's solution in fish-shell:
for i in *.avi; ffmpeg -i "$i" (string split -r -m1 . $i)[1]".mp4"; end

Bash is terrible to me, so under Linux/Mac, I prefer Ruby script:
( find all the files in a folder and then convert it from rmvb/rm format to mp4 format )
# 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}`
}
and you can run it with: ruby run.rb

Alternative approach using fd command (repository):
cd directory
fd -d 1 mp3 -x ffmpeg -i {} {.}.wav
-d means depth
-x means execute
{.} path without file extension

I developed a python package for this case.
https://github.com/developer0hye/BatchedFFmpeg
You can easily install and use it.
pip install batchedffmpeg
batchedffmpeg * -i folder * output_file

This will create mp4 video from all the jpg files from current directory.
echo exec("ffmpeg -framerate 1/5 -i photo%d.jpg -r 25 -pix_fmt yuv420p output.mp4");

I'm using this one-liner in linux to convert files (usually H265) into something I can play on Kodi without issues:
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
This converts to a temporary file and then replaces the original so the names remain the same after conversion.

I needed all the videos to use the same codec for merging purposes
so this conversion is mp4 to mp4
it's in zsh but should easily be convertible to bash
for S (*.mp4) { ffmpeg -i $S -c:v libx264 -r 30 new$S }

If you want a graphical interface to batch process with ffmpegX, try Quick Batcher. It's free and will take your last ffmpegX settings to convert files you drop into it.
Note that you can't drag-drop folders onto Quick Batcher. So select files and then put them through Quick Batcher.

Another simple solution that hasn't been suggested yet would be to use xargs:
ls *.avi | xargs -i -n1 ffmpeg -i {} "{}.mp4"
One minor pitfall is the awkward naming of output files (e.g. input.avi.mp4). A possible workaround for this might be:
ls *.avi | xargs -i -n1 bash -c "i={}; ffmpeg -i {} "\${i%.*}.mp4""

And for Windows, this does not work
FOR /F "tokens=*" %G IN ('dir /b *.flac') DO ffmpeg -i "%G" -acodec mp3 "%~nG.mp3"
even if I do double those %.
I would even suggest:
-acodec ***libmp3lame***
also:
FOR /F "tokens=*" %G IN ('dir /b *.flac') DO ffmpeg -i "%G" -acodec libmp3lame "%~nG.mp3"

This is what I use to batch convert avi to 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"
Works well as a cmd file, run it, the loop finds all avi files in that folder.
calls MY (change for yours) ffmpeg, passes input name, the settings are for rescaling up with sharpening. I probs don't need CRF and "-b:v 1024k"...
Output file is input file minus the extension, with mp4 as new ext.

Related

How do I use ffmpeg on a directory of files and have the new files retain the same name, using Bash? [duplicate]

How do you convert an entire directory/folder with ffmpeg via command line or with a batch script?
For Linux and macOS this can be done in one line, using parameter expansion to change the filename extension of the output file:
for i in *.avi; do ffmpeg -i "$i" "${i%.*}.mp4"; done
Previous answer will only create 1 output file called out.mov. To make a separate output file for each old movie, try this.
for i in *.avi;
do name=`echo "$i" | cut -d'.' -f1`
echo "$name"
ffmpeg -i "$i" "${name}.mov"
done
And on Windows:
FOR /F "tokens=*" %G IN ('dir /b *.flac') DO ffmpeg -i "%G" -acodec mp3 "%~nG.mp3"
For Windows:
Here I'm Converting all the (.mp4) files to (.mp3) files.
Just open cmd, goto the desired folder and type the command.
Shortcut: (optional)
1. Goto the folder where your (.mp4) files are present
2. Press Shift and Left click and Choose "Open PowerShell Window Here"
or "Open Command Prompt Window Here"
3. Type "cmd" [NOTE: Skip this step if it directly opens cmd instead of PowerShell]
4. Run the command
for %i in (*.mp4) do ffmpeg -i "%i" "%~ni.mp3"
If you want to put this into a batch file on Windows 10, you need to use %%i.
A one-line bash script would be easy to do - replace *.avi with your filetype:
for i in *.avi; do ffmpeg -i "$i" -qscale 0 "$(basename "$i" .avi)".mov ; done
To convert with subdirectories use e.g.
find . -exec ffmpeg -i {} {}.mp3 \;
#Linux
To convert a bunch, my one liner is this, as example
(.avi to .mkv) in same directory:
for f in *.avi; do ffmpeg -i "${f}" "${f%%.*}.mkv"; done
please observe the double "%%" in the output statement. It gives you not only the first word or the input filename, but everything before the last dot.
For anyone who wants to batch convert anything with ffmpeg but would like to have a convenient Windows interface, I developed this front-end:
https://sourceforge.net/projects/ffmpeg-batch
It adds to ffmpeg a window fashion interface, progress bars and time remaining info, features I always missed when using ffmpeg.
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.
If you have GNU parallel you could convert all .avi files below vid_dir to mp4 in parallel, using all except one of your CPU cores with
find vid_dir -type f -name '*.avi' -not -empty -print0 |
parallel -0 -j -1 ffmpeg -loglevel fatal -i {} {.}.mp4
To convert from/to different formats, change '*.avi' or .mp4 as needed. GNU parallel is listed in most Linux distributions' repositories in a package which is usually called parallel.
Using multiple cores, this is the fastest way, (using parallel):
parallel "ffmpeg -i {1} {1.}.mp4" ::: *.avi
I know this might be redundant but I use this script to batch convert files.
old_extension=$1
new_extension=$2
for i in *."$old_extension";
do ffmpeg -i "$i" "${i%.*}.$new_extension";
done
It takes 2 arguments to make it more flexible :
the extension you want to convert from
the new extension you want to convert to
I create an alias for it but you can also use it manually like this:
sh batch_convert.sh mkv mp4
This would convert all the mkv files into mp4 files.
As you can see it slightly more versatile. As long as ffmpeg can convert it you can specify any two extensions.
The following script works well for me in a Bash on Windows (so it should work just as well on Linux and Mac). It addresses some problems I have had with some other solutions:
Processes files in subfolders
Replaces the source extension with the target extension instead of just appending it
Works with files with multiple spaces and multiple dots in the name
(See this answer for details.)
Can be run when the target file exists, prompting before overwriting
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
Example call:
$ sh ffmpeg-batch-convert.sh mp3 wav
As a bonus, if you want the source files deleted, you can modify the script like this:
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
Example call:
$ sh ffmpeg-batch-convert.sh mp3 wav delete
I use this for add subtitle for Tvshows or Movies on Windows.
Just create "subbed" folder and bat file in the video and sub directory.Put code in bat file and run.
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"
)
Getting a bit like code golf here, but since nearly all the answers so far are bash (barring one lonely cmd one), here's a windows cross-platform command that uses powershell (because awesome):
ls *.avi|%{ ffmpeg -i $_ <ffmpeg options here> $_.name.replace($_.extension, ".mp4")}
You can change *.avi to whatever matches your source footage.
Also if you want same convertion in subfolders.
here is the recursive code.
for /R "folder_path" %%f in (*.mov,*.mxf,*.mkv,*.webm) do (
ffmpeg.exe -i "%%~f" "%%~f.mp4"
)
for i in *.flac;
do name=`echo "${i%.*}"`;
echo $name;
ffmpeg -i "${i}" -ab 320k -map_metadata 0 -id3v2_version 3 "${name}".mp3;
done
Batch process flac files into mp3 (safe for file names with spaces) using [1] [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"
)
this is variable bitrate of quality 2, you can set it to 0 if you want but unless you have a really good speaker system it's worthless imo
Only this one Worked for me, pls notice that you have to create "newfiles" folder manually where the ffmpeg.exe file is located.
Convert . files to .wav audio
Code:
for %%a in ("*.*") do ffmpeg.exe -i "%%a" "newfiles\%%~na.wav"
pause
i.e if you want to convert all .mp3 files to .wav change ("*.*") to ("*.mp3").
The author of this script is :
https://forum.videohelp.com/threads/356314-How-to-batch-convert-multiplex-any-files-with-ffmpeg
hope it helped 🙏.
For giggles, here's solution in fish-shell:
for i in *.avi; ffmpeg -i "$i" (string split -r -m1 . $i)[1]".mp4"; end
Bash is terrible to me, so under Linux/Mac, I prefer Ruby script:
( find all the files in a folder and then convert it from rmvb/rm format to mp4 format )
# 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}`
}
and you can run it with: ruby run.rb
Alternative approach using fd command (repository):
cd directory
fd -d 1 mp3 -x ffmpeg -i {} {.}.wav
-d means depth
-x means execute
{.} path without file extension
I developed a python package for this case.
https://github.com/developer0hye/BatchedFFmpeg
You can easily install and use it.
pip install batchedffmpeg
batchedffmpeg * -i folder * output_file
This will create mp4 video from all the jpg files from current directory.
echo exec("ffmpeg -framerate 1/5 -i photo%d.jpg -r 25 -pix_fmt yuv420p output.mp4");
I'm using this one-liner in linux to convert files (usually H265) into something I can play on Kodi without issues:
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
This converts to a temporary file and then replaces the original so the names remain the same after conversion.
I needed all the videos to use the same codec for merging purposes
so this conversion is mp4 to mp4
it's in zsh but should easily be convertible to bash
for S (*.mp4) { ffmpeg -i $S -c:v libx264 -r 30 new$S }
If you want a graphical interface to batch process with ffmpegX, try Quick Batcher. It's free and will take your last ffmpegX settings to convert files you drop into it.
Note that you can't drag-drop folders onto Quick Batcher. So select files and then put them through Quick Batcher.
Another simple solution that hasn't been suggested yet would be to use xargs:
ls *.avi | xargs -i -n1 ffmpeg -i {} "{}.mp4"
One minor pitfall is the awkward naming of output files (e.g. input.avi.mp4). A possible workaround for this might be:
ls *.avi | xargs -i -n1 bash -c "i={}; ffmpeg -i {} "\${i%.*}.mp4""
And for Windows, this does not work
FOR /F "tokens=*" %G IN ('dir /b *.flac') DO ffmpeg -i "%G" -acodec mp3 "%~nG.mp3"
even if I do double those %.
I would even suggest:
-acodec ***libmp3lame***
also:
FOR /F "tokens=*" %G IN ('dir /b *.flac') DO ffmpeg -i "%G" -acodec libmp3lame "%~nG.mp3"
This is what I use to batch convert avi to 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"
Works well as a cmd file, run it, the loop finds all avi files in that folder.
calls MY (change for yours) ffmpeg, passes input name, the settings are for rescaling up with sharpening. I probs don't need CRF and "-b:v 1024k"...
Output file is input file minus the extension, with mp4 as new ext.

FFMPEG Multiple task for converting video to image sequence for MacOS [duplicate]

How do you convert an entire directory/folder with ffmpeg via command line or with a batch script?
For Linux and macOS this can be done in one line, using parameter expansion to change the filename extension of the output file:
for i in *.avi; do ffmpeg -i "$i" "${i%.*}.mp4"; done
Previous answer will only create 1 output file called out.mov. To make a separate output file for each old movie, try this.
for i in *.avi;
do name=`echo "$i" | cut -d'.' -f1`
echo "$name"
ffmpeg -i "$i" "${name}.mov"
done
And on Windows:
FOR /F "tokens=*" %G IN ('dir /b *.flac') DO ffmpeg -i "%G" -acodec mp3 "%~nG.mp3"
For Windows:
Here I'm Converting all the (.mp4) files to (.mp3) files.
Just open cmd, goto the desired folder and type the command.
Shortcut: (optional)
1. Goto the folder where your (.mp4) files are present
2. Press Shift and Left click and Choose "Open PowerShell Window Here"
or "Open Command Prompt Window Here"
3. Type "cmd" [NOTE: Skip this step if it directly opens cmd instead of PowerShell]
4. Run the command
for %i in (*.mp4) do ffmpeg -i "%i" "%~ni.mp3"
If you want to put this into a batch file on Windows 10, you need to use %%i.
A one-line bash script would be easy to do - replace *.avi with your filetype:
for i in *.avi; do ffmpeg -i "$i" -qscale 0 "$(basename "$i" .avi)".mov ; done
To convert with subdirectories use e.g.
find . -exec ffmpeg -i {} {}.mp3 \;
#Linux
To convert a bunch, my one liner is this, as example
(.avi to .mkv) in same directory:
for f in *.avi; do ffmpeg -i "${f}" "${f%%.*}.mkv"; done
please observe the double "%%" in the output statement. It gives you not only the first word or the input filename, but everything before the last dot.
For anyone who wants to batch convert anything with ffmpeg but would like to have a convenient Windows interface, I developed this front-end:
https://sourceforge.net/projects/ffmpeg-batch
It adds to ffmpeg a window fashion interface, progress bars and time remaining info, features I always missed when using ffmpeg.
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.
If you have GNU parallel you could convert all .avi files below vid_dir to mp4 in parallel, using all except one of your CPU cores with
find vid_dir -type f -name '*.avi' -not -empty -print0 |
parallel -0 -j -1 ffmpeg -loglevel fatal -i {} {.}.mp4
To convert from/to different formats, change '*.avi' or .mp4 as needed. GNU parallel is listed in most Linux distributions' repositories in a package which is usually called parallel.
Using multiple cores, this is the fastest way, (using parallel):
parallel "ffmpeg -i {1} {1.}.mp4" ::: *.avi
I know this might be redundant but I use this script to batch convert files.
old_extension=$1
new_extension=$2
for i in *."$old_extension";
do ffmpeg -i "$i" "${i%.*}.$new_extension";
done
It takes 2 arguments to make it more flexible :
the extension you want to convert from
the new extension you want to convert to
I create an alias for it but you can also use it manually like this:
sh batch_convert.sh mkv mp4
This would convert all the mkv files into mp4 files.
As you can see it slightly more versatile. As long as ffmpeg can convert it you can specify any two extensions.
The following script works well for me in a Bash on Windows (so it should work just as well on Linux and Mac). It addresses some problems I have had with some other solutions:
Processes files in subfolders
Replaces the source extension with the target extension instead of just appending it
Works with files with multiple spaces and multiple dots in the name
(See this answer for details.)
Can be run when the target file exists, prompting before overwriting
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
Example call:
$ sh ffmpeg-batch-convert.sh mp3 wav
As a bonus, if you want the source files deleted, you can modify the script like this:
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
Example call:
$ sh ffmpeg-batch-convert.sh mp3 wav delete
I use this for add subtitle for Tvshows or Movies on Windows.
Just create "subbed" folder and bat file in the video and sub directory.Put code in bat file and run.
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"
)
Getting a bit like code golf here, but since nearly all the answers so far are bash (barring one lonely cmd one), here's a windows cross-platform command that uses powershell (because awesome):
ls *.avi|%{ ffmpeg -i $_ <ffmpeg options here> $_.name.replace($_.extension, ".mp4")}
You can change *.avi to whatever matches your source footage.
Also if you want same convertion in subfolders.
here is the recursive code.
for /R "folder_path" %%f in (*.mov,*.mxf,*.mkv,*.webm) do (
ffmpeg.exe -i "%%~f" "%%~f.mp4"
)
for i in *.flac;
do name=`echo "${i%.*}"`;
echo $name;
ffmpeg -i "${i}" -ab 320k -map_metadata 0 -id3v2_version 3 "${name}".mp3;
done
Batch process flac files into mp3 (safe for file names with spaces) using [1] [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"
)
this is variable bitrate of quality 2, you can set it to 0 if you want but unless you have a really good speaker system it's worthless imo
Only this one Worked for me, pls notice that you have to create "newfiles" folder manually where the ffmpeg.exe file is located.
Convert . files to .wav audio
Code:
for %%a in ("*.*") do ffmpeg.exe -i "%%a" "newfiles\%%~na.wav"
pause
i.e if you want to convert all .mp3 files to .wav change ("*.*") to ("*.mp3").
The author of this script is :
https://forum.videohelp.com/threads/356314-How-to-batch-convert-multiplex-any-files-with-ffmpeg
hope it helped 🙏.
For giggles, here's solution in fish-shell:
for i in *.avi; ffmpeg -i "$i" (string split -r -m1 . $i)[1]".mp4"; end
Bash is terrible to me, so under Linux/Mac, I prefer Ruby script:
( find all the files in a folder and then convert it from rmvb/rm format to mp4 format )
# 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}`
}
and you can run it with: ruby run.rb
Alternative approach using fd command (repository):
cd directory
fd -d 1 mp3 -x ffmpeg -i {} {.}.wav
-d means depth
-x means execute
{.} path without file extension
I developed a python package for this case.
https://github.com/developer0hye/BatchedFFmpeg
You can easily install and use it.
pip install batchedffmpeg
batchedffmpeg * -i folder * output_file
This will create mp4 video from all the jpg files from current directory.
echo exec("ffmpeg -framerate 1/5 -i photo%d.jpg -r 25 -pix_fmt yuv420p output.mp4");
I'm using this one-liner in linux to convert files (usually H265) into something I can play on Kodi without issues:
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
This converts to a temporary file and then replaces the original so the names remain the same after conversion.
I needed all the videos to use the same codec for merging purposes
so this conversion is mp4 to mp4
it's in zsh but should easily be convertible to bash
for S (*.mp4) { ffmpeg -i $S -c:v libx264 -r 30 new$S }
If you want a graphical interface to batch process with ffmpegX, try Quick Batcher. It's free and will take your last ffmpegX settings to convert files you drop into it.
Note that you can't drag-drop folders onto Quick Batcher. So select files and then put them through Quick Batcher.
Another simple solution that hasn't been suggested yet would be to use xargs:
ls *.avi | xargs -i -n1 ffmpeg -i {} "{}.mp4"
One minor pitfall is the awkward naming of output files (e.g. input.avi.mp4). A possible workaround for this might be:
ls *.avi | xargs -i -n1 bash -c "i={}; ffmpeg -i {} "\${i%.*}.mp4""
And for Windows, this does not work
FOR /F "tokens=*" %G IN ('dir /b *.flac') DO ffmpeg -i "%G" -acodec mp3 "%~nG.mp3"
even if I do double those %.
I would even suggest:
-acodec ***libmp3lame***
also:
FOR /F "tokens=*" %G IN ('dir /b *.flac') DO ffmpeg -i "%G" -acodec libmp3lame "%~nG.mp3"
This is what I use to batch convert avi to 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"
Works well as a cmd file, run it, the loop finds all avi files in that folder.
calls MY (change for yours) ffmpeg, passes input name, the settings are for rescaling up with sharpening. I probs don't need CRF and "-b:v 1024k"...
Output file is input file minus the extension, with mp4 as new ext.

Convert all .wav files in all folders to .flac [duplicate]

How do you convert an entire directory/folder with ffmpeg via command line or with a batch script?
For Linux and macOS this can be done in one line, using parameter expansion to change the filename extension of the output file:
for i in *.avi; do ffmpeg -i "$i" "${i%.*}.mp4"; done
Previous answer will only create 1 output file called out.mov. To make a separate output file for each old movie, try this.
for i in *.avi;
do name=`echo "$i" | cut -d'.' -f1`
echo "$name"
ffmpeg -i "$i" "${name}.mov"
done
And on Windows:
FOR /F "tokens=*" %G IN ('dir /b *.flac') DO ffmpeg -i "%G" -acodec mp3 "%~nG.mp3"
For Windows:
Here I'm Converting all the (.mp4) files to (.mp3) files.
Just open cmd, goto the desired folder and type the command.
Shortcut: (optional)
1. Goto the folder where your (.mp4) files are present
2. Press Shift and Left click and Choose "Open PowerShell Window Here"
or "Open Command Prompt Window Here"
3. Type "cmd" [NOTE: Skip this step if it directly opens cmd instead of PowerShell]
4. Run the command
for %i in (*.mp4) do ffmpeg -i "%i" "%~ni.mp3"
If you want to put this into a batch file on Windows 10, you need to use %%i.
A one-line bash script would be easy to do - replace *.avi with your filetype:
for i in *.avi; do ffmpeg -i "$i" -qscale 0 "$(basename "$i" .avi)".mov ; done
To convert with subdirectories use e.g.
find . -exec ffmpeg -i {} {}.mp3 \;
#Linux
To convert a bunch, my one liner is this, as example
(.avi to .mkv) in same directory:
for f in *.avi; do ffmpeg -i "${f}" "${f%%.*}.mkv"; done
please observe the double "%%" in the output statement. It gives you not only the first word or the input filename, but everything before the last dot.
For anyone who wants to batch convert anything with ffmpeg but would like to have a convenient Windows interface, I developed this front-end:
https://sourceforge.net/projects/ffmpeg-batch
It adds to ffmpeg a window fashion interface, progress bars and time remaining info, features I always missed when using ffmpeg.
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.
If you have GNU parallel you could convert all .avi files below vid_dir to mp4 in parallel, using all except one of your CPU cores with
find vid_dir -type f -name '*.avi' -not -empty -print0 |
parallel -0 -j -1 ffmpeg -loglevel fatal -i {} {.}.mp4
To convert from/to different formats, change '*.avi' or .mp4 as needed. GNU parallel is listed in most Linux distributions' repositories in a package which is usually called parallel.
Using multiple cores, this is the fastest way, (using parallel):
parallel "ffmpeg -i {1} {1.}.mp4" ::: *.avi
I know this might be redundant but I use this script to batch convert files.
old_extension=$1
new_extension=$2
for i in *."$old_extension";
do ffmpeg -i "$i" "${i%.*}.$new_extension";
done
It takes 2 arguments to make it more flexible :
the extension you want to convert from
the new extension you want to convert to
I create an alias for it but you can also use it manually like this:
sh batch_convert.sh mkv mp4
This would convert all the mkv files into mp4 files.
As you can see it slightly more versatile. As long as ffmpeg can convert it you can specify any two extensions.
The following script works well for me in a Bash on Windows (so it should work just as well on Linux and Mac). It addresses some problems I have had with some other solutions:
Processes files in subfolders
Replaces the source extension with the target extension instead of just appending it
Works with files with multiple spaces and multiple dots in the name
(See this answer for details.)
Can be run when the target file exists, prompting before overwriting
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
Example call:
$ sh ffmpeg-batch-convert.sh mp3 wav
As a bonus, if you want the source files deleted, you can modify the script like this:
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
Example call:
$ sh ffmpeg-batch-convert.sh mp3 wav delete
I use this for add subtitle for Tvshows or Movies on Windows.
Just create "subbed" folder and bat file in the video and sub directory.Put code in bat file and run.
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"
)
Getting a bit like code golf here, but since nearly all the answers so far are bash (barring one lonely cmd one), here's a windows cross-platform command that uses powershell (because awesome):
ls *.avi|%{ ffmpeg -i $_ <ffmpeg options here> $_.name.replace($_.extension, ".mp4")}
You can change *.avi to whatever matches your source footage.
Also if you want same convertion in subfolders.
here is the recursive code.
for /R "folder_path" %%f in (*.mov,*.mxf,*.mkv,*.webm) do (
ffmpeg.exe -i "%%~f" "%%~f.mp4"
)
for i in *.flac;
do name=`echo "${i%.*}"`;
echo $name;
ffmpeg -i "${i}" -ab 320k -map_metadata 0 -id3v2_version 3 "${name}".mp3;
done
Batch process flac files into mp3 (safe for file names with spaces) using [1] [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"
)
this is variable bitrate of quality 2, you can set it to 0 if you want but unless you have a really good speaker system it's worthless imo
Only this one Worked for me, pls notice that you have to create "newfiles" folder manually where the ffmpeg.exe file is located.
Convert . files to .wav audio
Code:
for %%a in ("*.*") do ffmpeg.exe -i "%%a" "newfiles\%%~na.wav"
pause
i.e if you want to convert all .mp3 files to .wav change ("*.*") to ("*.mp3").
The author of this script is :
https://forum.videohelp.com/threads/356314-How-to-batch-convert-multiplex-any-files-with-ffmpeg
hope it helped 🙏.
For giggles, here's solution in fish-shell:
for i in *.avi; ffmpeg -i "$i" (string split -r -m1 . $i)[1]".mp4"; end
Bash is terrible to me, so under Linux/Mac, I prefer Ruby script:
( find all the files in a folder and then convert it from rmvb/rm format to mp4 format )
# 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}`
}
and you can run it with: ruby run.rb
Alternative approach using fd command (repository):
cd directory
fd -d 1 mp3 -x ffmpeg -i {} {.}.wav
-d means depth
-x means execute
{.} path without file extension
I developed a python package for this case.
https://github.com/developer0hye/BatchedFFmpeg
You can easily install and use it.
pip install batchedffmpeg
batchedffmpeg * -i folder * output_file
This will create mp4 video from all the jpg files from current directory.
echo exec("ffmpeg -framerate 1/5 -i photo%d.jpg -r 25 -pix_fmt yuv420p output.mp4");
I'm using this one-liner in linux to convert files (usually H265) into something I can play on Kodi without issues:
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
This converts to a temporary file and then replaces the original so the names remain the same after conversion.
I needed all the videos to use the same codec for merging purposes
so this conversion is mp4 to mp4
it's in zsh but should easily be convertible to bash
for S (*.mp4) { ffmpeg -i $S -c:v libx264 -r 30 new$S }
If you want a graphical interface to batch process with ffmpegX, try Quick Batcher. It's free and will take your last ffmpegX settings to convert files you drop into it.
Note that you can't drag-drop folders onto Quick Batcher. So select files and then put them through Quick Batcher.
Another simple solution that hasn't been suggested yet would be to use xargs:
ls *.avi | xargs -i -n1 ffmpeg -i {} "{}.mp4"
One minor pitfall is the awkward naming of output files (e.g. input.avi.mp4). A possible workaround for this might be:
ls *.avi | xargs -i -n1 bash -c "i={}; ffmpeg -i {} "\${i%.*}.mp4""
And for Windows, this does not work
FOR /F "tokens=*" %G IN ('dir /b *.flac') DO ffmpeg -i "%G" -acodec mp3 "%~nG.mp3"
even if I do double those %.
I would even suggest:
-acodec ***libmp3lame***
also:
FOR /F "tokens=*" %G IN ('dir /b *.flac') DO ffmpeg -i "%G" -acodec libmp3lame "%~nG.mp3"
This is what I use to batch convert avi to 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"
Works well as a cmd file, run it, the loop finds all avi files in that folder.
calls MY (change for yours) ffmpeg, passes input name, the settings are for rescaling up with sharpening. I probs don't need CRF and "-b:v 1024k"...
Output file is input file minus the extension, with mp4 as new ext.

Increase volume on multiple files

Let say I have a couple of hundreds mp3 files. How do I increase volume in all of them with ffmpeg?
This is for single file:
ffmpeg -i input.mp3 -filter:a "volume=1.5" output.mp3
And what about multiple files with one command?
Just write a loop in whatever scripting language your shell uses to call ffmpeg for each file.
e.g. for bash:
mkdir louder
for f in *.mp3
do
ffmpeg -i $f -filter:a "volume=1.5" louder/$f
done
or in Windows batch (untested):
FOR %%F IN (*.mp3) DO ffmpeg -i %%F -filter:a "volume=1.5" louder/%%F
And see https://ss64.com/nt/for2.html
For Windows users, type in command line interface:
for %i in (*.mp3) do ffmpeg -i "%i" -filter:a "volume=1.5" "%~ni-150percent.mp3"

How can I automatically convert all MP4 files to FLV with ffmpeg?

How can I automatically convert all MP4 files to FLV in a specific folder?
ffmpeg -i VID00002.MP4 -ar 44100 test.flv
Is there a way to queue these tasks, assuming that I don't know the file names?
If I need to run any scripts (I'm familiar with Python), how can I do that?
You can do this fairly easy within the terminal, given you have ffmpeg installed. In your terminal, enter the following:
$>cd /your/path/to/videos
$>for i in *.mp4; do ffmpeg -i $i -ar 44100 $i.flv; done
The second command simply iterates through each mp4 file and assigns the filename to '$i'. You then call ffmpeg using $i as the input and output filename. For the output, you simply add the extension, in this case $i.flv. So, if your filename is 'video.mp4', it will output as 'video.mp4.flv'.
Hope this helps.
This will convert and rename the new files using the find and ffmpeg functions and suppressing output questions:
find /mymediapath (\ -name '*.mp4' \) -exec bash -c 'ffmpeg -y -i "$0" -strict -2 "${0/mp4/flv}"' {} \;

Resources