I'd like to convert all .mp4 movies in a folder and delete the old one afterwards.
Does anyone have a hint? I've been trying for hours.
The only thing I found is:
How to make ffmpeg delete the original file after changing containers? (using a send to bat file)
my idea:
ffmpeg -i *.mp4 -c:v libx264 -b:v 1.5M -c:a aac *.mp4
It asks if files can be overwritten, but then it doesn't:https://pastebin.com/tJtWpm2n
In ffmpeg you can't directly write to the same file you're currently reading from, but one thing you can do instead is write to a temporary file, then replace the original if ffmpeg converted successfully.
for f in *.mp4; do
ffmpeg -i "${f}" -c:v libx264 -b:v 1.5M -c:a aac "tmp_${f}" && mv "tmp_${f}" "${f}"
done
So ffmpeg reads from variable ${f} containing the original filename matched in the *.mp4 pattern and writes to tmp_${f}, then && tests ffmpeg exited successfully before replacing the original file with mv.
You might also want to ensure "tmp_${f}" does not exist first, which only takes a few more steps.
for f in *.mp4; do
tmpf=$(mktemp -p ./ -t "tmp.XXXXXXXXXX.${f##*.}") # can now be extended for any file extension
ffmpeg -i "${f}" -c:v libx264 -b:v 1.5M -c:a aac "${tmpf}" && mv "${tmpf}" "${f}"
done
Related
I have folders within folders that have movie files, some of them are .mp4, .avi or .mov/.MOV. I need to re-compress them into H264 High Quality (Lets say, 10MBPS) and delete the originals when complete. I have the following code, but this is for audio and I don't know where to go from here. I am using Mac terminal.
for i in *.ogg; do ffmpeg -i "$i" -b:a 320000 "${i%.*}.mp3"; done
Here is a small example on how this can convert mp4 files to 10M h264 files, which can be easily modified and run again for other file types,and can be easily modified to remove files after they have been converted:
convert_file() {
# loop through all mp4 files in current directory
for i in $1*.mp4;
# convert to .h264
do ffmpeg -i "$i" -b:v 10M -b:a 192k -an -vcodec libx264 -crf 23 "${i%.*}.h264" -y
done
# recursive call
# call convert_file function for each sub directory
for d in $1*/; do
if [ -d "$d" ]
then
convert_file $d;
fi
done
}
# call with path/to/myvideos
convert_file ~/Videos/
Using trial and error I am using the following script on an OSX, to bulk convert a whole folder full of mp3 files, to mp4, by looping a specific video file:
for i in *.mp3; do /usr/local/bin/ffmpeg -stream_loop -1 -i /path_to_filename.mp4 -c copy -v 0 -f nut - | /usr/local/bin/ffmpeg -thread_queue_size 10K -i - -i "$i" -c copy -map 0:v -map 1:a -shortest "$(basename "$i" )".mp4 ; done; for f in *.mp3.mp4; do mv -v "$f" "${f/.mp3.mp4/.mp4}"; done
How can I also print/add/burn the mp3 filename, without the extension (.mp3), as an additional video layer at the bottom of the generated video screen, and with the added difficulty of word wrapping the text if is too long?
This command makes a temporary SRT file for the subtitles filter which will automatically deal with the placement and word wrapping:
for i in *.mp3; do echo "1" > subs.srt; echo "00:00:00,000 --> 10:00:00,000" >> subs.srt; echo "${i%.*}" >> subs.srt; ffmpeg -stream_loop -1 -i video.mp4 -i "$i" -filter_complex "[0:v]subtitles=subs.srt:force_style=Alignment=3,format=yuv420p[v]" -map "[v]" -map 1:a -c:v libx264 -c:a copy -shortest -movflags +faststart "${i%.*}.mp4"; done
Running the command in the directory containing the file allows avoidance of basename and creates a simpler command.
MP3 is not universally supported in MP4. Consider changing -c:a copy to -c:a aac if your player does not support it. But I suspect you're targeting YouTube which will be fine with MP3 in MP4.
The three instances of echo are inefficient but effective in avoiding any newline issues. Using one instance of printf would be more optimal, but I don't have access to macOS to test its printf implementation.
I am working on a batch conversion process where I need to add a random picture (a .jpg) on a random .mp3 and make an .mp4.
This is the code I am using in terminal Mac OS X putting all the .mp3 and the .jpg in the same folder:
for f in *.mp3; do /usr/local/Cellar/ffmpeg/4.1_1/bin/ffmpeg -r 1 -loop 1 -i abc5.jpg -i "$f" -c:a copy -c:v libx264 -vf scale=1280:720 -shortest "${f%mp3}mp4"; done
It works great, but I don't know how to add another random feature for the .jpg files, so every time I have to put a different .jpg and change the name (usually in the file not in the script). I also know this must be something with for ((..., but I don't know how to add it properly.
for f in *.mp3; do /usr/local/Cellar/ffmpeg/4.1_1/bin/ffmpeg -r 1 -loop 1 -i abc5.jpg -i "$f" -c:a copy -c:v libx264 -vf scale=1280:720 -shortest "${f%mp3}mp4"; done
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
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.