-
-
Save kurlov/32cbe841ea9d2b299e15297e54ae8971 to your computer and use it in GitHub Desktop.
ffmpeg -i in.mkv -f srt -i in.srt -map 0:0 -map 0:1 -map 1:0 -c:v copy -c:a copy -c:s srt out.mkv |
To just add subtitles to file without removing any subtitles it is very easy:
ffmpeg -i input.mkv -i input.srt -map 0 -map 1 -c copy output.mkv
-map x
selects all streams from a file so all streams from both files get into the output file.
See the very conscious and simple documentation https://trac.ffmpeg.org/wiki/Map
P.S. Thanks @eladkarako for the metadata usage
I've tried all the above options without success... the only thing that happens is that there is a closed caption option listed yet no text is displayed and the file size of the video file was increased.
I'm using both mediainfo and vlc to look at the file info.
I'm running this thru a ubuntu server 22.04.1 LTS
is this supposed to add the CEA-708 metadata for Closed Captioning or is this a different type of embedded text?
I've tried all the above options without success..
This code I use both on my PC and my server, works perfectly, the sub file should be .ass format (use aegisub or even ffmpeg to convert your sub to it)
ffmpeg -loglevel 16 -i input.mp4 -f ass -i sub.ass -brand isom -tag:v avc1 -map 0:0 -map 0:1 -map 1:0 -c:v copy -c:a copy -c:s ass -disposition:s:0 default Fname.mkv
ffmpeg -i $1 -f ass -i $2 -map 0:0 -map 0:1 -map 1:0 -c:v copy -c:a copy -c:s ass $RANDOM.mkv
I confirm this code is fine.
Thanks.
tl;dr
why?.
the following example embed two subtitles without encoding, Hebrew and English (in a "one go", and in that order).if you want to embed more than one subtitle stream you must use map,
otherwise ffmpeg's automatic stream selection only takes the first one, of its kind (it does the same for audio/video streams as well).
note: the command is broken over several lines for better readability. linux users add
\
at line's end, windows users add^
at line's end, or just remove all line breaks to make it functional.note: vtt is like srt, commonly used by youtube. you can use any of your existing subtitles 'as is' though.
input.mp4
(the map command maps0
which means this file and whatever streams it contains first, using automatic assignment, it then runs a little cleanup to make sure no existing subtitles were left in it, so the next indexing addressing to the external subtitles is correct .subtitle.iw.vtt
this is the first of the subtitle streams, its index is zero based so.....s:0
, it is getting a proper 3 letter language code from ISO-639-1, and a label (you can write anything you like in it, even name it locally, I could have usedtitle=עברית
as well. but for compatibility with some old players I've chosentitle=Hebrew
.subtitle.en.vtt
second in the subtitle-list of streams, so index is1
-.....s:1
.output.mkv
.note about indexing:
I know the indexing might seem a bit confusing, first, remember it is zero based, so 0 is first, 1 is second, 2 is third, ...next:
-map 0
,-map "1:0"
,-map "2:0"
are the original input (-i ...
) files 'as whole', with whatever streams they have in them,the indexes in
"-metadata:s:s:0"
,"-metadata:s:s:1"
are limited with:s
so that means they are used in the list of subtitles "collected" from all the inputs together, potentially including all the subtitles already embedded in the video file.to avoid collecting any unknown amount of subtitles from the first input,
-map "-0:s"
is used, ignoring all subtitle-streams from the first input.b.t.w. this how YT-DLP (youtube-dl fork) is embedding subtitles, it fixes a lot of quirks.
yt-dlp's subtitle embedding related, python code, for ffmpeg
https://github.com/yt-dlp/yt-dlp/blob/1209b6ca5b720a2cd035ff86040bfb1fea7ac6c9/yt_dlp/postprocessor/ffmpeg.py#L591-L667
https://github.com/yt-dlp/yt-dlp/blob/1209b6ca5b720a2cd035ff86040bfb1fea7ac6c9/yt_dlp/postprocessor/ffmpeg.py#L648-L659
if you already have subtitles you want to keep you can extract them with
-na -nv mysubtitle.srt
(you can choose your extension) and embed them properly again (with language code and such) along with the new ones. you can also avoid the deletion of data and existing subtitles, but then you need to remember to shift the index of the added subtitles acording to how many subtitles are already embedded, and it is bad scripting. it is better to extract them in what ever format you want. if you are working on some subtitles with more data, such as colors, or placements over video (.ASS) which are commonly used in translated anime, to translate letters street signs etc.. make sure to keep the same format otherwise you'll loose that data and only keep the text of the translation. you can often check what subtitle type is being used with ffmpeg or vlc or media player classic.and you can always use
-c:s copy subtitle_of_unknown_format.txt
instead and figure it out later using a text editor or the great subtitle workshop program.source
another example with more languages:
edit:
default subtitle to play
(optional) use
-disposition
to set a default subtitle,and it does not even have to be the first one,
for example:
-disposition:s:s:5 forced
will make your sixth subtitle stream the default one to play.note: you can use this to make other streams the default ones to open as well...
-disposition:s:a:3 forced
for the fourth audio stream,-disposition:s:v:0 forced
for the first video stream..