Eugene
Eugene

Reputation: 11545

How do you convert an entire directory with ffmpeg?

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

Upvotes: 430

Views: 591523

Answers (30)

adamerikus
adamerikus

Reputation: 35

A bash script below, who identify media-files and convert them to MP4. The script contain all needed explanations.

`

#!/bin/bash

#####################################################################################
#####################################################################################
# This is a script which is searching for media files in the current directory only.#
# Subdirectories will not be included in the conversion.                            #
#-----------------------------------------------------------------------------------#
#                   All media filles will be converted to mp4!                      #
#              I use x264 and aac codecs in this conversion script!                 #
#             So far you want to target a different codec/container                 #
#                   please adjust the script to your needs!                         #
#-----------------------------------------------------------------------------------#
# the converted files ($target = basename.conv.mp4) will remain in the current      #
# directory                                                                         #
#-----------------------------------------------------------------------------------#
#                               Prerequisits                                        #
# Prerequisit is 'ffmpeg'. All other commands should be available on your device.   #
# Could be that you have to adjust the 'sed' statements according to your platform. #
#####################################################################################
#####################################################################################


#####################################################################################
# $dir_orig_files = Directory where converted original files will be moved after    #
# successful run.                                                                   #
#####################################################################################

dir_orig_files=original_files

if [ -d "$directory" ]; then
    echo "$directory exist."
        else mkdir original_files
fi

#####################################################################################
# Replacing spaces " " in filenames with "_" since spaces will cause problems.      #
#####################################################################################

find . -maxdepth 1  -name '* *' \
        | while IFS= read -r f ; do mv -i "$f" "$(dirname "$f")/$(basename "$f" \
            |tr ' ' _)" ; done

#####################################################################################
# Definition of which media files should be converted.                              #
#####################################################################################

files=`find . -maxdepth 1 \( -name '*.mp4' -o -name '*avi' -o -name '*wmv' \
        -o -name '*flv' -o -name '*mpg' -o -name '*mpeg' -o -name '*divx' \
            -o -name '*m4a' -o -name '*mov' -o -name '*m4v' -o -name '*mkv' \
                -o -name '*m4v' \)`

#####################################################################################
#                       Defining taregt-name and bitrates                                                   #
# $target is finally the original basename with the ending '*.conv.mp4'             #
# $videobitrate of each media file will be extracted and this value will be used    #
# for the corresponding '*.conv.mp4' file.                                          #
# $audiobitrate -> serve same task as $videobitrate | 'grep -v something' is needed #
# for some files since some media files have e.g. different audio streams and to    #
# avoid an ambigous $audiobitrate we use this statement. We need just one value.    #
# So far the audio streams are ok and the codec is recognized, the audio stream     #
# will be processed and included in the media file.                                 #
# In *.mkv videos I also faced outputs in a sceond line,                            #
# like "cpb: bitrate max/min/avg: ..." and to avoid this ambigous value, I used     #
# again 'grep -v cpb' in this case.                                                 #
#####################################################################################

for f in $files; do

    target="${f%.*}.conv.mp4"
    videobitrate=$(ffprobe $f 2>&1|grep bitrate |grep -v cpb \
        |sed "s/.*bitrate: \([0-9]*\) \([km]*\).*/\1\2/")
    audiobitrate=$(ffprobe $f >&1|grep Audio|grep kb |grep -v default \
        |sed "s/.* \([0-9]*\) \([km]*\)b\/s.*/\1\2/")

#####################################################################################
# Find out that some files, especially *.mkv files don't list accuratley the Audio  #
# bitrate and this lead to an error. Therefore I assume that 192k should be enough  #
# and so far 'ffprobe' doesn't find the Audio bitrate 'ffmpeg' will use 192k.       #
# So far you want to use a different Audio bitrate, change this correspondingly     #
# by changing the value below -> '-b:a 192k'                                        #
#####################################################################################

        if [[ -z $audiobitrate ]]; then             # If $audiobitrate is empty
            ffmpeg -hide_banner -err_detect ignore_err -i "$f" -preset slow \
                -c:v libx264 -c:a aac -b:v $videobitrate -b:a 192k -map 0 \
                    -minrate 1024k -maxrate $videobitrate -bufsize 1024k -g 60 \
                        "$target" && mv "$f" $dir_orig_files

#####################################################################################
# If $audiobitrate delivered a processable result, $audiobitrate will be used       #
#####################################################################################

        else ffmpeg -hide_banner -err_detect ignore_err -i "$f" -preset slow -c:v \
            libx264 -c:a aac -b:v $videobitrate -b:a $audiobitrate -map 0 \
                -minrate 1024k -maxrate $videobitrate -bufsize 1024k -g 60 \
                    "$target" && mv "$f" $dir_orig_files
        fi

done

`

Upvotes: 1

Franck Dernoncourt
Franck Dernoncourt

Reputation: 83387

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?

Upvotes: 7

darw
darw

Reputation: 1057

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

Upvotes: 1

Mehrdad995
Mehrdad995

Reputation: 47

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

Upvotes: 2

EngineerJack
EngineerJack

Reputation: 39

Since this thread appears to be a mixture of everyone's different methods of converting files, I'll add what I've been using for a while.

This is a powershell command (.ps1) that will convert every video file in the folder (that meets the specifications) on Windows 10 and 11 to another video file.

I want to state that this is NOT my command, but one I found online. This link is the full instructions, but the code to convert TS to MP4 is below. Just put it into a PS1 file.

I named my file:

TS-To-MP4_Convert.ps1

$originalVids = Get-ChildItem *.ts -Recurse

foreach ($inputVid in $originalVids) {
    $outputVid = [io.path]::ChangeExtension($inputVid.FullName, '.mp4')
    ffmpeg.exe -i $inputVid.FullName -c:v libx264 -crf 18 -c:a aac -map_metadata 0 $outputVid
}

What I like about this command, is it CAN be used to convert any video file to any other video file (that is supported by FFMPEG).

To convert AVI to MP4, use the code below, and to convert "anything" to "anything" just make the changes I made below, to whatever you may need.

Everything that I have tried has worked.

$originalVids = Get-ChildItem *.avi -Recurse

foreach ($inputVid in $originalVids) {
    $outputVid = [io.path]::ChangeExtension($inputVid.FullName, '.mp4')
    ffmpeg.exe -i $inputVid.FullName -c:v libx264 -crf 18 -c:a aac -map_metadata 0 $outputVid
}

I have seen posts here that include multiple files into their command, I would be interested in knowing the code for this command, if it is possible.

Also, I saw where some included a code that also deletes the original file, I'd also be interested in knowing how to do this also, again, if that is possible.

This specific command DOES make my PC run hard, but the quality is good.

Upvotes: 0

shubhamr238
shubhamr238

Reputation: 1408

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.

Upvotes: 89

Yuriy N.
Yuriy N.

Reputation: 6127

Convert all .wav files in the folder to mp3 on Windows using a batch file.

  1. Create file convertToMp3.bat
  2. Put inside this line:

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

  1. Save the file in the same folder where .wav files are.
  2. Double click convertToMp3.bat

Upvotes: 0

Sam
Sam

Reputation: 381

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

Upvotes: 1

Joel
Joel

Reputation: 483

On Windows, for files in subdirectories, open a command prompt window and enter the following commands.

cd "C:\temp"
FOR /F "tokens=*" %G IN ('dir /s /b /o:gn *.mp4') DO ffmpeg -i "%G" -c copy "%~pG%~nG.mkv"

This converts all mp4 files to mkvs including files in subdirectories and places the mkv file where the mp4 file is i.e. a file C:\temp\test.mp4 will have it corresponding mkv in C:\temp\test.mkv

Upvotes: 0

user14644517
user14644517

Reputation:

Copying off of @HiDd3n, you can also do this if you want to recursively search through the directory of files in case you have numerous folders:

for /r %i in (*.webm) do "C:\Program Files\ffmpeg\bin\ffmpeg.exe" -i "%i" "%~ni.mp3"

Upvotes: 1

HiDd3N
HiDd3N

Reputation: 504

if you don't want to convert the file and just copy codec use the code bellow

for %i in (*.mkv) do ffmpeg -i "%i" -codec copy "%~ni.mp4"

like this you will reduce the convertion time.

Upvotes: 1

developer0hye
developer0hye

Reputation: 443

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

Upvotes: 2

Michal Przybylowicz
Michal Przybylowicz

Reputation: 1668

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

Upvotes: 3

Janghou
Janghou

Reputation: 1853

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

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

Upvotes: 14

Siwei
Siwei

Reputation: 21557

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

Upvotes: 1

Teknoist
Teknoist

Reputation: 51

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

Upvotes: 5

JayHawk
JayHawk

Reputation: 451

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

Upvotes: 35

zzapper
zzapper

Reputation: 5041

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 }

Upvotes: 1

steevee
steevee

Reputation: 2588

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

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

Upvotes: 2

Marco Eckstein
Marco Eckstein

Reputation: 4758

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

Upvotes: 8

Hasan Yilmaz
Hasan Yilmaz

Reputation: 128

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

Upvotes: 5

llogan
llogan

Reputation: 134103

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

Upvotes: 732

user1634000
user1634000

Reputation: 21

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.

Upvotes: 2

ABPerson
ABPerson

Reputation: 521

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.

Upvotes: 16

Morphy
Morphy

Reputation: 1

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.

Upvotes: 0

Halligallator
Halligallator

Reputation: 1

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"

Upvotes: 0

thesachinparmar
thesachinparmar

Reputation: 26

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

Upvotes: 1

Isaac
Isaac

Reputation: 2849

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

Upvotes: 276

user151496
user151496

Reputation: 1985

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

Upvotes: 2

stib
stib

Reputation: 3512

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.

Upvotes: 5

Related Questions