436

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

2
  • Run from batch file. I found a solution that was close on reddit and then used chatGTB to clean it up and make it work. It converts mp4 to WebP. I made this a comment as I could not find a way to answer. Start code: @echo off REM Loop through each MP4 file in the current directory for %%a in (*.mp4) do ffmpeg -i "%%~a" -vcodec libwebp -filter:v fps=fps=20 -lossless 1 -loop 0 -preset default -an -vsync 0 "%%~na.webp" Commented Jun 12, 2023 at 20:08
  • Looking for a Windows batch script solution to extract audio from all video files in bulk and in the quickest way possible? go to this post: superuser.com/a/1876199 Commented Feb 3, 2025 at 7:02

40 Answers 40

755

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
Sign up to request clarification or add additional context in comments.

9 Comments

This is perfect, thank you! Here's full command that ended up working great for me: for i in *.avi; do ffmpeg -i "$i" -c:a aac -b:a 128k -c:v libx264 -crf 20 "${i%.avi}.mp4"; done
I am getting i was unexpected at this time. error in cmd, windows 10. I used following line: for i in *.mp3; do ffmpeg -i "$i" -map_metadata -1 -c:v copy -c:a copy "${i%.mp3}.mp3"; done
@Junaid 1) Make sure to use a different name for the output file than the input, or output to another directory, because ffmpeg can't input and output to the same file. 2) I'm not sure if Bash commands work on Windows 10 natively. Maybe I should add to the answer that it is targeted towards systems that can natively use Bash such as Linux and macOS. lxs provided an Windows answer for this question.
This should be the top answer. Admittedly, the explanation for why {$i%.*} is not simple, but if you can put that aside and just "use it" you can quickly modify to suit. For example, I converted hundreds of .mp4's (with filenames having spaces and special characters) to a smaller format using: for i in .mp4; do ffmpeg -i "$i" -s 512x288 -c:a copy "${i%.}.m4v"; done
To take it one step further, you could use Bash parameter substitution if you would like to replace the string "x265" with "x264" if you're transcoding from H.265 to H.264 which is a common use case. 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
|
278

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

10 Comments

If you're like me and have lots of spaces (and a few other problematic characters) in your file names, I'd suggest addding double quotes : ffmpeg -i "$i" "$name.mov";
I'm getting the error i was unexpected at this time.
is this support for .bat in windows?
@Jazuly No, this is sh syntax. You can install Bash on Windows if you aren't yet prepared to ditch Windows entirely.
This seems to be trimming up to the first full stop and not last for me. So the filenames aren't the same but with .mov on the end.
|
139

And on Windows:

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

8 Comments

if you run this command in a batch (.bat) file you need to double the % signs => %%
Any idea how to run this command but copy to a new file that includes the original file's metadata?
@Barryman9000 this was a long time ago but I think there's an output file option you could pass
@lxs thanks for the follow up. I ended up doing it with Powershell by changing the new file's name to be the original file's date created stackoverflow.com/a/35671099/197472
For PowerShell: Get-ChildItem *.ogg -recurse | % { ffmpeg.exe -i $_.FullName -map_metadata -1 -c:v copy -c:a copy ("NewPath" + "\" +$_.Name) } Where NewPath = new directory path.
|
94

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 Right 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.

6 Comments

This works on command prompt for me, but not for powershell Missing opening '(' after keyword 'for'. + CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException + FullyQualifiedErrorId : MissingOpenParenthesisAfterKeyword
Indeed this command did work, but don't use powershell.
powershell has a completely different syntax that's more like an actual programming language. I'm sure it'd be possible to do this in powershell but it'd be different
Worked for me on Win11 in Command Prompt - not in Powershell. Thanks!
This worked for me opening directly in CMD (go to the folder you want to convert, just type cmd into the address bar), but I had to move ffmpeg.exe into the same folder, otherwise I got an error that it couldn't find the ffmpeg command. Additionally, I was converting mp4a files & it still worked after changing *.mp4 to *.mp4a
|
45

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

1 Comment

The default encoder for .mov is libx264 (if available), but this encoder ignores -qscale. Remove it and use the default settings, or use -crf instead (default is -crf 23).
39

To convert with subdirectories use e.g.

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

7 Comments

I used this, combined with this answer to convert VTT to SRT, to great effect. find -name "*.vtt" -exec ffmpeg -i {} {}.srt \;
I this command, with slight modif to convert all mp4 to mp3: find *.mp4 -exec ffmpeg -i {} {}.mp3 \;
Or, if you want to convert multiple file types: find . -name *.ogg -or -name *.wma -exec ffmpeg -i {} {}.mp3 \;
Convert all wma files to mp3 and after delete them: find . -name *.wma -exec ffmpeg -i {} {}.mp3 \; -exec rm {} \;
find **/*.wav -exec ffmpeg -i {} -map 0:a:0 -b:a 96k {}.mp3 \;
|
35

@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.

2 Comments

In my case I had to use single %. {string%%substring} deletes the longest match of substring from string - giving you the part before the first period whereas {string%substring} deletes the shortest match - deleting only the extension.
you are right - my wrong
29

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.

13 Comments

Hi, you can use an "Image to video wizard" available in latest versions, in case no other solution comes up.
Hi, well, you're right, wizard do not allow that. I found a workaround, you may try it, following these instructions (change image file path accordingly): - Add your audio files to file list. - On pre-input box write: -loop 1 -i "C:\flac\Test.jpg" -r 10 - On parameters box: -map 0:v:0 -c:v libx264 -preset ultrafast -r 10 -crf 23 -tune stillimage -pix_fmt yuv420p -vf scale=1280:720 -map 1:a:0 -c:a aac -b:a 128K -shortest If your audio files are mp3 or aac, you can use -c:a copy
Hi @Eibel and many thanks for the reply. It's working perfectly! I've made a step by step demo here: superuser.com/a/1706004/1105013 Thanks again and be well! On pre-input : -loop 1 -i "<MyImagePath>" On parameters box (for mp3s or aacs): -map 0:v:0 -c:v libx264 -preset ultrafast -r 10 -crf 23 -tune stillimage -pix_fmt yuv420p -vf scale=1280:720 -map 1:a:0 -c:a copy -b:a 128K -shortest On parameters box (for m4a tested): -map 0:v:0 -c:v libx264 -preset ultrafast -r 10 -crf 23 -tune stillimage -pix_fmt yuv420p -vf scale=1280:720 -map 1:a:0 -c:a copy -b:a 128K -shortest
Hi @Lod I've tuned the parameters to make process much faster. These would be the ones: -Pre input: -loop 1 -r 1/1 -i "[Youri Image Path]" ---Parameters: -map 0:v:0 -c:v libx264 -preset veryfast -tune stillimage -pix_fmt yuv420p -vf fps=1 -map 1:a:0 -c:a aac -b:a 128K -shortest (Image size should be video standard, like 1280x720, 1920x1080).
Hi @Lod, it is not possible to make that automatically yet, but you could add this parameter: -vf "pad=ceil(iw/2)*2:ceil(ih/2)*2" and iti should remove the error message. stackoverflow.com/questions/20847674/…
|
16

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.

3 Comments

PowerShell is great, thanks! In case anyone else runs into trouble running this: put this command in a .ps1 file, not a .bat file. You'll have to run Set-ExecutionPolicy RemoteSigned as administrator if you've never run a PS script before.
split-path is a better choice
@imba-tjd Sure, in place of the .Replace I can see that. However, I think this example could be even better anyway, by doing $_.FullName.Replace instead of $_.Name.Replace so absolute paths are handled more elegantly. If it were that, which I think is much better, then it'd get quite cumbersome to use Split-Path, especially for something that my intention was you'd type on the spot. Even if it does better support the very unlikely scenario that the replace approach doesn't work on
15

Using multiple cores, this is the fastest way, (using parallel):

parallel "ffmpeg -i {1} {1.}.mp4" ::: *.avi 

4 Comments

Note that ffmpeg already uses all available cores when encoding each file, so you might not get much (or any) real performance improvement by asking it to process multiple files in parallel.
@Luke, for video files yes, but not for all files e.g. sound files (FLAC) or some image formats, you can still speed up by using parallel.
@LukeTaylor I can confirm what Janghou said - it is a tremendous speedup if you have 20+ files.
Awesome! That way I converted a huge folder of opus files into mp3 real quickly.
9

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.

1 Comment

couldn't you could do the same by adding ! to the end of any of the bash one-liners?
8

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 :

  1. the extension you want to convert from
  2. 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.

Comments

8

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

Comments

7

If one wants to convert all the files matching several possible extensions in an entire directory with ffmpeg on or , one can use the following command:

for i in *.{avi,mkv,mov,mp4,webm}; do ffmpeg -i "$i" "${i%.*}.wav"; done

(I extended llogan's answer to support several possible file extensions, as in my case I had to convert all videos files into .wav regardless of the video type.)


To view the results, one can list the total number of files broken down by specific extension with this command by squozen:

find . -type f | sed 's/.*\.//' | sort | uniq -c

e.g.:

    176 mkv
    417 wav
    241 webm

Since 241 + 176 = 417, all video files were converted to .wav files.

In case one wants to transcribe all these videos, see How do I run Whisper on an entire directory?

Comments

5

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.

Comments

5

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"
    )

Comments

5

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"
    )

1 Comment

This works well in a batch file. For anyone trying to use this on the normal command line, use only one percent % symbol.
3

For giggles, here's solution in fish-shell:

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

1 Comment

this is exactly what I was looking for! Do you know how to do it for either avi or mov files in a folder?
3

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

Comments

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

Batch process flac files into mp3 (safe for file names with spaces) using [1] [2]

Comments

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

Comments

2

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.

Comments

2

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

enter image description here

Comments

2

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

Comments

1

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""

2 Comments

shellcheck.net has a few suggestions regarding your examples.
mywiki.wooledge.org/ParsingLs though you can simply replace ls with printf '%s\n' here.
1

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");

Comments

1

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 }

Comments

1

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

Comments

1

This one script finds and converts any files that ffmpeg supports (no need to specify only one type):

find . \( -name "*.3dostr" -o -name "*.3g2" -o -name "*.3gp" -o -name "*.aa" -o -name "*.aac" -o -name "*.ac3" -o -name "*.acm" -o -name "*.act" -o -name "*.adf" -o -name "*.adp" -o -name "*.ads" -o -name "*.adts" -o -name "*.afc" -o -name "*.aiff" -o -name "*.aix" -o -name "*.alp" -o -name "*.amr" -o -name "*.amrnb" -o -name "*.amrwb" -o -name "*.anm" -o -name "*.apc" -o -name "*.ape" -o -name "*.apm" -o -name "*.apng" -o -name "*.aptx" -o -name "*.aqtitle" -o -name "*.asf" -o -name "*.asf_o" -o -name "*.asf_stream" -o -name "*.ass" -o -name "*.ast" -o -name "*.au" -o -name "*.av1" -o -name "*.avi" -o -name "*.avisynth" -o -name "*.avm2" -o -name "*.avr" -o -name "*.avs" -o -name "*.avs2" -o -name "*.bethsoftvid" -o -name "*.bfi" -o -name "*.bfstm" -o -name "*.bin" -o -name "*.bink" -o -name "*.bit" -o -name "*.bmv" -o -name "*.boa" -o -name "*.brstm" -o -name "*.c93" -o -name "*.caf" -o -name "*.cavsvideo" -o -name "*.cdg" -o -name "*.cdxl" -o -name "*.cine" -o -name "*.codec2" -o -name "*.codec2raw" -o -name "*.concat" -o -name "*.crc" -o -name "*.dash" -o -name "*.data" -o -name "*.daud" -o -name "*.dcstr" -o -name "*.dds_pipe" -o -name "*.derf" -o -name "*.dfa" -o -name "*.dhav" -o -name "*.dirac" -o -name "*.dnxhd" -o -name "*.dsf" -o -name "*.dshow" -o -name "*.dsicin" -o -name "*.dss" -o -name "*.dts" -o -name "*.dtshd" -o -name "*.dv" -o -name "*.dvbsub" -o -name "*.dvbtxt" -o -name "*.dvd" -o -name "*.dxa" -o -name "*.ea" -o -name "*.eac3" -o -name "*.epaf" -o -name "*.f32be" -o -name "*.f32le" -o -name "*.f4v" -o -name "*.f64be" -o -name "*.f64le" -o -name "*.ffmetadata" -o -name "*.fifo" -o -name "*.filmstrip" -o -name "*.fits" -o -name "*.flac" -o -name "*.flic" -o -name "*.flv" -o -name "*.framecrc" -o -name "*.framehash" -o -name "*.framemd5" -o -name "*.frm" -o -name "*.fsb" -o -name "*.fwse" -o -name "*.g722" -o -name "*.g723_1" -o -name "*.g726" -o -name "*.g726le" -o -name "*.g729" -o -name "*.gdigrab" -o -name "*.gdv" -o -name "*.genh" -o -name "*.gif" -o -name "*.gif_pipe" -o -name "*.gsm" -o -name "*.gxf" -o -name "*.h261" -o -name "*.h263" -o -name "*.h264" -o -name "*.hash" -o -name "*.hca" -o -name "*.hcom" -o -name "*.hds" -o -name "*.hevc" -o -name "*.hls" -o -name "*.hnm" -o -name "*.ico" -o -name "*.idcin" -o -name "*.idf" -o -name "*.iff" -o -name "*.ifv" -o -name "*.ilbc" -o -name "*.image2" -o -name "*.image2pipe" -o -name "*.ingenient" -o -name "*.ipmovie" -o -name "*.ipod" -o -name "*.ircam" -o -name "*.ismv" -o -name "*.iss" -o -name "*.iv8" -o -name "*.ivf" -o -name "*.ivr" -o -name "*.j2k_pipe" -o -name "*.jacosub" -o -name "*.jpeg_pipe" -o -name "*.jpegls_pipe" -o -name "*.jv" -o -name "*.kux" -o -name "*.kvag" -o -name "*.latm" -o -name "*.lavfi" -o -name "*.libopenmpt" -o -name "*.live_flv" -o -name "*.lmlm4" -o -name "*.loas" -o -name "*.lrc" -o -name "*.lvf" -o -name "*.lxf" -o -name "*.m4v" -o -name "*.matroska" -o -name "*.webm" -o -name "*.mcc" -o -name "*.md5" -o -name "*.mgsts" -o -name "*.microdvd" -o -name "*.mjpeg" -o -name "*.mjpeg_2000" -o -name "*.mkvtimestamp_v2" -o -name "*.mlp" -o -name "*.mlv" -o -name "*.mm" -o -name "*.mmf" -o -name "*.mov" -o -name "*.mp4" -o -name "*.m4a" -o -name "*.3gp" -o -name "*.3g2" -o -name "*.mj2" -o -name "*.mp2" -o -name "*.mp3" -o -name "*.mp4" -o -name "*.mpc" -o -name "*.mpc8" -o -name "*.mpeg" -o -name "*.mpeg1video" -o -name "*.mpeg2video" -o -name "*.mpegts" -o -name "*.mpegtsraw" -o -name "*.mpegvideo" -o -name "*.mpjpeg" -o -name "*.mpl2" -o -name "*.mpsub" -o -name "*.msf" -o -name "*.msnwctcp" -o -name "*.mtaf" -o -name "*.mtv" -o -name "*.mulaw" -o -name "*.musx" -o -name "*.mv" -o -name "*.mvi" -o -name "*.mxf" -o -name "*.mxf_d10" -o -name "*.mxf_opatom" -o -name "*.mxg" -o -name "*.nc" -o -name "*.nistsphere" -o -name "*.nsp" -o -name "*.nsv" -o -name "*.null" -o -name "*.nut" -o -name "*.nuv" -o -name "*.oga" -o -name "*.ogg" -o -name "*.ogv" -o -name "*.oma" -o -name "*.opus" -o -name "*.paf" -o -name "*.pam_pipe" -o -name "*.pbm_pipe" -o -name "*.pcx_pipe" -o -name "*.pgm_pipe" -o -name "*.pgmyuv_pipe" -o -name "*.pgx_pipe" -o -name "*.pictor_pipe" -o -name "*.pjs" -o -name "*.pmp" -o -name "*.png_pipe" -o -name "*.pp_bnk" -o -name "*.ppm_pipe" -o -name "*.psd_pipe" -o -name "*.psp" -o -name "*.psxstr" -o -name "*.pva" -o -name "*.pvf" -o -name "*.qcp" -o -name "*.qdraw_pipe" -o -name "*.r3d" -o -name "*.rawvideo" -o -name "*.realtext" -o -name "*.redspark" -o -name "*.rl2" -o -name "*.rm" -o -name "*.roq" -o -name "*.rpl" -o -name "*.rsd" -o -name "*.rso" -o -name "*.rtp" -o -name "*.rtp_mpegts" -o -name "*.rtsp" -o -name "*.s16be" -o -name "*.s16le" -o -name "*.s24be" -o -name "*.s24le" -o -name "*.s32be" -o -name "*.s32le" -o -name "*.s337m" -o -name "*.s8" -o -name "*.sami" -o -name "*.sap" -o -name "*.sbc" -o -name "*.sbg" -o -name "*.scc" -o -name "*.sdl" -o -name "*.sdl2" -o -name "*.sdp" -o -name "*.sdr2" -o -name "*.sds" -o -name "*.sdx" -o -name "*.segment" -o -name "*.ser" -o -name "*.sgi_pipe" -o -name "*.shn" -o -name "*.siff" -o -name "*.singlejpeg" -o -name "*.sln" -o -name "*.smjpeg" -o -name "*.smk" -o -name "*.smoothstreaming" -o -name "*.smush" -o -name "*.sol" -o -name "*.sox" -o -name "*.spdif" -o -name "*.spx" -o -name "*.srt" -o -name "*.stl" -o -name "*.stream_segment" -o -name "*.ssegment" -o -name "*.streamhash" -o -name "*.subviewer" -o -name "*.subviewer1" -o -name "*.sunrast_pipe" -o -name "*.sup" -o -name -o -name "*.svag" -o -name "*.svcd" -o -name "*.svg_pipe" -o -name "*.swf" -o -name "*.tak" -o -name "*.tedcaptions" -o -name "*.tee" -o -name "*.thp" -o -name "*.tiertexseq" -o -name "*.tiff_pipe" -o -name "*.tmv" -o -name "*.truehd" -o -name "*.tta" -o -name "*.tty" -o -name "*.txd" -o -name "*.ty" -o -name "*.u16be" -o -name "*.u16le" -o -name "*.u24be" -o -name "*.u24le" -o -name "*.u32be" -o -name "*.u32le" -o -name "*.u8" -o -name "*.uncodedframecrc" -o -name "*.v210" -o -name "*.v210x" -o -name "*.vag" -o -name "*.vc1" -o -name "*.vc1test" -o -name "*.vcd" -o -name "*.vfwcap" -o -name "*.vidc" -o -name "*.vividas" -o -name "*.vivo" -o -name "*.vmd" -o -name "*.vob"  -o -name "*.vobsub" -o -name "*.voc" -o -name "*.vpk" -o -name "*.vplayer" -o -name "*.vqf" -o -name "*.w64" -o -name "*.wav" -o -name "*.wc3movie" -o -name "*.webp_pipe" -o -name "*.webvtt" -o -name "*.wsaud" -o -name "*.wsd" -o -name "*.wsvqa" -o -name "*.wtv" -o -name "*.wv" -o -name "*.wve" -o -name "*.xa" -o -name "*.xbin" -o -name "*.xmv" -o -name "*.xpm_pipe" -o -name "*.xvag" -o -name "*.xwd_pipe" -o -name "*.xwma" -o -name "*.yop" -o -name "*.yuv4mpegpipe" \) -exec sh -c 'ffmpeg -n -i "$0" -vn -q:a 0 "${0%.*}.mp3"' {} \;

Replace the last command with 'ffmpeg -n -i "$0" -vn -q:a 0 "${0%.*}.mp3" && rm "$0"' to delete the original after the conversion

P.S: for the record, that list is as follows:

*.3gp, *.aa, *.aac, *.ac3, *.acm, *.act, *.adf, *.adp, *.ads, *.adts, *.afc, *.aiff, *.aix, *.alp, *.amr, *.amrnb, *.amrwb, *.anm, *.apc, *.ape, *.apm, *.apng, *.aptx, *.aqtitle, *.asf, *.asf_o, *.asf_stream, *.ass, *.ast, *.au, *.av1, *.avi, *.avisynth, *.avm2, *.avr, *.avs, *.avs2, *.bethsoftvid, *.bfi, *.bfstm, *.bin, *.bink, *.bit, *.bmv, *.boa, *.brstm, *.c93, *.caf, *.cavsvideo, *.cdg, *.cdxl, *.cine, *.codec2, *.codec2raw, *.concat, *.crc, *.dash, *.data, *.daud, *.dcstr, *.dds_pipe, *.derf, *.dfa, *.dhav, *.dirac, *.dnxhd, *.dsf, *.dshow, *.dsicin, *.dss, *.dts, *.dtshd, *.dv, *.dvbsub, *.dvbtxt, *.dvd, *.dxa, *.ea, *.eac3, *.epaf, *.f32be, *.f32le, *.f4v, *.f64be, *.f64le, *.ffmetadata, *.fifo, *.filmstrip, *.fits, *.flac, *.flic, *.flv, *.framecrc, *.framehash, *.framemd5, *.frm, *.fsb, *.fwse, *.g722, *.g723_1, *.g726, *.g726le, *.g729, *.gdigrab, *.gdv, *.genh, *.gif, *.gif_pipe, *.gsm, *.gxf, *.h261, *.h263, *.h264, *.hash, *.hca, *.hcom, *.hds, *.hevc, *.hls, *.hnm, *.ico, *.idcin, *.idf, *.iff, *.ifv, *.ilbc, *.image2, *.image2pipe, *.ingenient, *.ipmovie, *.ipod, *.ircam, *.ismv, *.iss, *.iv8, *.ivf, *.ivr, *.j2k_pipe, *.jacosub, *.jpeg_pipe, *.jpegls_pipe, *.jv, *.kux, *.kvag, *.latm, *.lavfi, *.libopenmpt, *.live_flv, *.lmlm4, *.loas, *.lrc, *.lvf, *.lxf, *.m4v, *.matroska, *.webm, *.mcc, *.md5, *.mgsts, *.microdvd, *.mjpeg, *.mjpeg_2000, *.mkvtimestamp_v2, *.mlp, *.mlv, *.mm, *.mmf, *.mov, *.mp4, *.m4a, *.3gp, *.3g2, *.mj2, *.mp2, *.mp3, *.mpc, *.mpc8, *.mpeg, *.mpeg1video, *.mpeg2video, *.mpegts, *.mpegtsraw, *.mpegvideo, *.mpjpeg, *.mpl2, *.mpsub, *.msf, *.msnwctcp, *.mtaf, *.mtv, *.mulaw, *.musx, *.mv, *.mvi, *.mxf, *.mxf_d10, *.mxf_opatom, *.mxg, *.nc, *.nistsphere, *.nsp, *.nsv, *.null, *.nut, *.nuv, *.oga, *.ogg, *.ogv, *.oma, *.opus, *.paf, *.pam_pipe, *.pbm_pipe, *.pcx_pipe, *.pgm_pipe, *.pgmyuv_pipe, *.pgx_pipe, *.pictor_pipe, *.pjs, *.pmp, *.png_pipe, *.pp_bnk, *.ppm_pipe, *.psd_pipe, *.psp, *.psxstr, *.pva, *.pvf, *.qcp, *.qdraw_pipe, *.r3d, *.rawvideo, *.realtext, *.redspark, *.rl2, *.rm, *.roq, *.rpl, *.rsd, *.rso, *.rtp, *.rtp_mpegts, *.rtsp, *.s16be, *.s16le, *.s24be, *.s24le, *.s32be, *.s32le, *.s337m, *.s8, *.sami, *.sap, *.sbc, *.sbg, *.scc, *.sdl, *.sdl2, *.sdp, *.sdr2, *.sds, *.sdx, *.segment, *.ser, *.sgi_pipe, *.shn, *.siff, *.singlejpeg, *.sln, *.smjpeg, *.smk, *.smoothstreaming, *.smush, *.sol, *.sox, *.spdif, *.spx, *.srt, *.stl, *.stream_segment, *.ssegment, *.streamhash, *.subviewer, *.subviewer1, *.sunrast_pipe, *.sup, *.svag, *.svcd, *.svg_pipe, *.swf, *.tak, *.tedcaptions, *.tee, *.thp, *.tiertexseq, *.tiff_pipe, *.tmv, *.truehd, *.tta, *.tty, *.txd, *.ty, *.u16be, *.u16le, *.u24be, *.u24le, *.u32be, *.u32le, *.u8, *.uncodedframecrc, *.v210, *.v210x, *.vag, *.vc1, *.vc1test, *.vcd, *.vfwcap, *.vidc, *.vividas, *.vivo, *.vmd, *.vob, *.vobsub, *.voc, *.vpk, *.vplayer, *.vqf, *.w64, *.wav, *.wc3movie, *.webp, *.webp_pipe, *.webvtt, *.wsaud, *.wsd, *.wsvqa, *.wtv, *.wv, *.wve, *.xa, *.xbin, *.xmv, *.xpm_pipe, *.xvag, *.xwd_pipe, *.xwma, *.yop, *.yuv4mpegpipe

Comments

1

By calling ffmpeg just once and passing the file names as arguments:

ffmpeg         \
  -i 0.mp4     \
  -i 1.mp4     \
  -i 2.mp4     \
  -map 0 0.avi \
  -map 1 1.avi \
  -map 2 2.avi

where the argument list can be generated in an OS-dependent way. For example, using Z shell:

{
  for in in *.mp4
    print -- -i $in

  i=0
  for out in *.mp4(:s/mp4/avi/:)
    print -- -map $((i++)) $out
} |
  xargs ffmpeg

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.