Add subtitles to multiple files at once - ffmpeg

I have a folder with episodes called ep and a folder with subtitles called sub
Each episode has corresponding subtitles and i need to bulk add them with ffmpeg.
I've read that i can add subtitles with the following command:
ffmpeg -i video.avi -vf "ass=subtitle.ass" out.avi
But that only does it one file at a time.
Is there a bulk variant?
Some useful info:
ls ep prints
<series name> - Ep<episode number>.mkv
ls sub prints
<series name> - Ep<episode number>.ass

I made a small sh script that will do this:
#!/bin/sh
SUBTITLES_FOLDER=sub
EPISODES_FOLDER=ep
OUTPUT_FOLDER=out
for i in "$EPISODES_FOLDER"/*.mkv; do
sub="$SUBTITLES_FOLDER/$(echo "$i" | sed 's/mkv$/ass/')"
ffmpeg -i "$i" -i "$sub" -c:v copy -c:a copy -c:s copy -map 0:0 -map 0:1 -map 1:0 -y "$OUTPUT_FOLDER/$i" &
done
Note the '&' at the end of the ffmpeg command: it makes sure ffmpeg runs in parallel (is this the correct term for it?)
You may want to modify the file extensions and check if ffmpeg supports subtitles with your format, the rest will be done by itself.

Related

Batch replace audio using ffmpeg

I have a folder with mkv and aac files on my Mac. I have used ffmpeg to replace audio in mkv files with success but I can't figure out how to loop it in a folder. Let's say I have a folder with vid1.mkv, vid1.aac, vid2.mkv, vid2.aac etc. I tried this but it doesn't work:
for i in *.mkv; do ffmpeg -i "$i" -i "${i%.*}.aac" -c copy -map 0:v:0 -map 1:a:0 "${i%.*}.remux.mp4" done

merge audio and video with ffmpeg doesnt work correctly

I have ubuntu 20.04 and in past days I did this job(merge video and audio) well in terminal and with ffmpeg:
ffmpeg -i input.mp4 -i input2.mp3 -c copy output.mp4
so fast I have recived output.mp4, but now I tried this one and get output without any sound!
I try another ways to merge this ones(also with ffmpeg) but there are no diffrent...
ffmpeg -f concat -safe 0 -i <(for f in ./input*.mp4; do echo "file '$PWD/$f'"; done) -c copy output.mp4
Note -f concat will select a demuxer. This alters the way -i nput files are read.
So instead video-files 'concat expects a txt-file listing the files to concatenate.
However we somehow omit the creation of that text file and use process substitution to generate and pass that list on the fly to demux.
For more details go here:
https://trac.ffmpeg.org/wiki/Concatenate#demuxer
If you want to merge several video files, you can use these command.
merge two video files.
ffmpeg -f concat -i 1.mp4 -1 2.mp4 -codec copy out.mp4
merge multiple video files.
ffmpeg -i 1.mp4 -i 2.mp4 -i 3.mpt -vcodec copy -acodec copy out.mp4

Using ffmpeg to convert mp3 to mp4 - how to draw filename on generated video?

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.

How can I remove metadata from a flv file?

with ffmpeg I can use the command below to remove the metadata in General section
ffmpeg -i input.flv -c copy -metadata description= -metadata title= output.flv
What if I want to remove the metadata in Video and Audio section?
EDIT:
I want to remove writing library
With FFmpeg v4.0 or newer, for your particular case,
ffmpeg -i in -c copy -bitexact -map_metadata -1 -vbsf filter_units=remove_types=6 out

Ffmpeg Ignore stream if it doesn't exist

I'm using ffmpeg to convert files to .mp3 and extract cover images from the metadata.
This works fine for files that have cover images, files that don't throw the error:
Output #1 does not contain any stream
ffmpeg -i kalimba.mp3 -y test.mp3 -acodec copy test.jpg
How can I tell ffmpeg to just ignore streams if they don't exist and continue converting to .mp3 if no cover image exists in the metadata?
First you should check what streams are provided in the file. You can do it with tool ffprobe. Then you run ffmpeg to copy one or two streams.
if [ -n "`ffprobe -show_streams -v quiet kalimba.mp3 | grep '^\[streams\.stream\.1\]'`" ] ; then
# the file has 2 streams
ffmpeg -i kalimba.mp3 -y test.mp3 -acodec copy test.jpg
else
# no cover image
ffmpeg -i kalimba.mp3 -y test.mp3 -acodec copy
fi

Resources