FFmpeg: Encode multiple video files at once (batch) - bash

How do I encode multiple video files in one batch with ffmpeg, using the same settings?
I found this one-line solution that converts .avi files in the current folder to .mov. Note that I want to encode .mov -> .mov :
for i in *.mov; do ffmpeg -i "$i" "${i%.mov}.mov" ; done
I wish to use the following settings for encoding:
ffmpeg -i "$i" -c:v libx265 -preset ultrafast -crf 20 -af "volume=25dB, highpass=f=200, equalizer=f=50:width_type=h:width=100:g=-15" -c:a aac -strict experimental -b:a 192k OUTPUT-ENCODED.MOV
Possible ways to prevent overwriting:
Add -ENCODED to the end of the filename before the file extension
Rename the files to something sequential, like OUTPUT01.MOV, OUTPUT02.MOV, etc
Put the encoded files in a directory subfolder but with the same file names

You can freely manipulate the output file ${i%.mov}.mov - here, the "key ingredient" is that the statement ${i%.mov} yields content of variable i with the shortest match of .mov deleted from the back. For details see this tutorial on manipulating strings in bash.

Related

How to convert a lump set of PPM files to a single .mp4 video using ffmpeg

I'm trying to convert some .ppm files into a single video using ffmpeg. The images are listed as image10.ppm, image20.ppm, all the way up to image2000.ppm
Essentially, there are 200 images following the format of image(1-200)0.ppm in a single folder.
I've navigated to the correct folder containing the images using cd and the terminal displays this folder as the directory I'm in.
Inputting the following command into the terminal:
ffmpeg -r 10 -f image2 -s 500x500 -i image%04d.ppm -vcodec libx264 -crf 25 -pix_fmt yuv420p presentation_video.mp4
I get the error that says:
[image2 # 0x7ff36180ba00] Could find no file with path 'image%04d.ppm' and index in the range 0-4
image%04d.ppm: No such file or directory
What am I missing? I've just downloaded ffmpeg and am fairly new in general to command line interface.
Your image inputs file names do not contain leading zeros, such as image0002.ppm, so use the the sequence pattern image%d.ppm:
ffmpeg -framerate 10 -i image%d.ppm -c:v libx264 -crf 25 -vf "scale=500:500,format=yuv420p" -movflags +faststart output.mp4
See the image demuxer documentation for more details about the sequence pattern.

How do I use FFMPEG with filter_complex to combine/join a full folder of 40+ audio files into one long mp3?

I have a full directory of 40-50 audio files that I am trying to "concat" into one long mp3.
I was able to do this just testing around with 2 files using the command shown below, but I need an easy way to do this with a script that I can make if I have a folder of many files with complicated file names. This is something I'm going to be doing frequently so if I had a script or something I could use quickly that would be most helpful.
ffmpeg -i a.webm -i b.webm -filter_complex "[0:a] [1:a] concat=n=2:v=0:a=1 [a]" -map [a] -c:a mp3 testfull.mp3
The simplest solution is to use the concat demuxer, but all inputs must be the same format and have the same attributes (sample rate, sample format, channel layout).
printf "file '%s'\n" *.webm > input.txt
ffmpeg -f concat -safe 0 -i input.txt -map 0:a output.mp3
-safe 0 is only needed if your input file names contain special characters.

Convert Multiple Audio Tracks of Multiple Files FFmpeg

I'm using a script to convert all video files in a folder. These files have multiple audio tracks and I want the converted files to have each audio track as well. I've tried both -c copy and -c:a mp3 and neither worked for me. Any ideas how I can modify this to copy all audio tracks?
#!/bin/sh
for i in *.mkv; do ffmpeg -i "$i" -c:a mp3 -vcodec libx264 -crf 18 -r 60 "${i%.mkv}.mp4"; done
You can do this by setting -c:a copy. In your example you're attempting to set the audio codec to mp3, which is actually just the container. Hope that helps!
I should amend this... My first thought will simply copy the single, highest-quality audio stream from the input file. To copy all streams we'll want to use the map option1. Your example, copying all audio streams could look like this:
#!/bin/sh
for i in *.mkv; do
ffmpeg -i "$i" -map 0 -c copy -c:v libx264 -crf 18 -r 60 "${i%.mkv}.mp4";
done

how to name the output file same as input file but different extension after video conversion? [duplicate]

This question already has answers here:
How do you convert an entire directory with ffmpeg?
(34 answers)
Closed 4 years ago.
I am using this line to batch convert mp4 files to webm files. For all mp4 files i need the output files to be of same name but .webm extension. For example if i have video1.mp4 and video2.mp4 then after conversion i need two files i.e video1.webm and video2.webm. How can i achieve this using bash script?
for f in *.mp4; do ffmpeg -i "$f" -c:v libvpx -crf 10 -b:v 1M -c:a libvorbis "$f".webm; done
The above code will change the output file to video1.mp4.webm. Thanks!
Try this ...
for f in *.mp4;
do
ffmpeg -i "$f" -c:v libvpx -crf 10 -b:v 1M -c:a libvorbis "${f%.mp4}".webm;
done
From what I can tell this link is the answer you're looking for. Though you may not need the part that removes the path since you're simply running this within the folder.
Try:
for f in *.mp4; do ffmpeg -i "$f" -c:v libvpx -crf 10 -b:v 1M -c:a libvorbis "${f%.mp4}".webm; done
How do I remove the file suffix and path portion from a path string in Bash?
Edit: Added example; After updating I realize someone else gave the same update.

FFmpeg how generate a sequence of videos with bash

i try to write an .sh that read a folder create a playlist of mp4 files and then generate an only big video with a sequence of all videos find in the folder, and encode it for dash:
printf "file '%s'\n" ./*.mp4 > playlist.sh
ffmpeg -f concat -safe 0 -i playlist.sh -c copy concat.mp4
Till now i follow the demux concat official guido to ffmpeg website.
Without result, also the following give me "more than 1000 frames duplicated between videos of the sequence"
ffmpeg -f concat -i playlist.sh -c:a aac -b:a 384k -ar 48000 -ac 2 -c:v libx264 -x264opts 'keyint=50:min-keyint=50:no-scenecut' -r 25 -b:v 2400k -maxrate 2400k -bufsize 1200k -vf "scale=-1:432 " out.mp4
Thanks a lot
Sry, cannot comment (yet)...
Your commands are correct, I could just concat some sample videos.
Do you always get the mentioned error, or also something else? And is the video working, or no video is created?
In most cases, the input video is incorrect. Wrong input format (not fitting to file extension) or worse like ending at wrong frame.
Perhaps you can make the video available?
PS: Needed to add -safe 0 to the second command to avoid error [concat # 0x7fbfd1000000] Unsafe file name './small.mp4'
Hint: Do not use file extension .sh for your list of video files. This extension is used for shell scripts, so it can be confusing. Just use .txt.
UPDATE #Massimo Vantaggio
We should not create new answers, but I cannot comment yours and I also don't know how to continue our discussion, so I edit my answer.
Your videos don't look very different. Can't see, what's wrong with the first one.
Perhaps you could use ffprobe -report input.mp4 to get more informations. Look for errors or warnings.
My assumption is still that the video was cut in a hard way (by conversion software), so keyframes are messed up or something else.
You can also try to first reencode your video with ffmpeg. After that, it should be complete compatible with ffmpeg ;)
Something like this:
ffmpeg -i small.mp4 -acodec aac -ab 192k -vcodec libx264 -vb 1024k -f mp4 output.mp4
Use -ab and -vb from your input video, or at least the bitrate from input. Quality will decrease a little bit and file size increase, but it should be okay.

Resources