Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use ffmpeg to add text subtitles [closed]

ffmpeg -i infile.mp4 -i infile.srt -c copy -c:s mov_text outfile.mp4

-vf subtitles=infile.srt will not work with -c copy


The order of -c copy -c:s mov_text is important. You are telling FFmpeg:

  1. Video: copy, Audio: copy, Subtitle: copy
  2. Subtitle: mov_text

If you reverse them, you are telling FFmpeg:

  1. Subtitle: mov_text
  2. Video: copy, Audio: copy, Subtitle: copy

Alternatively you could just use -c:v copy -c:a copy -c:s mov_text in any order.


NOTE: This solution "burns the subtitles" into the video, so that every viewer of the video will be forced to see them.

If your ffmpeg has libass enabled at compile time, you can directly do:

ffmpeg -i mymovie.mp4 -vf subtitles=subtitles.srt mysubtitledmovie.mp4

This is the case e.g. for Ubuntu 20.10, you can check if ffmpeg --version has --enable-libass.

Otherwise, you can the libass library (make sure your ffmpeg install has the library in the configuration --enable-libass).

First convert the subtitles to .ass format:

ffmpeg -i subtitles.srt subtitles.ass

Then add them using a video filter:

ffmpeg -i mymovie.mp4 -vf ass=subtitles.ass mysubtitledmovie.mp4

You are trying to mux subtitles as a subtitle stream. It is easy but different syntax is used for MP4 (or M4V) and MKV. In both cases you must specify video and audio codec, or just copy stream if you just want to add subtitle.

MP4:

ffmpeg -i input.mp4 -f srt -i input.srt \
-map 0:0 -map 0:1 -map 1:0 -c:v copy -c:a copy \
-c:s mov_text output.mp4

MKV:

ffmpeg -i input.mp4 -f srt -i input.srt \
-map 0:0 -map 0:1 -map 1:0 -c:v copy -c:a copy \
-c:s srt  output.mkv

MKV container supports video and audio codecs Virtually anything and also supports subtitles and DVD menus. So you can just copy codecs from input video to output video with MKV container with subtitles. First you should convert SRT to ASS subtitle format

ffmpeg -i input.srt input.ass

and embed ASS subtitles to video

ffmpeg -i input.mp4 -i input.ass -c:v copy -c:a copy -c:s copy -map 0:0 -map 0:1 -map 1:0 -y out.mkv

Also worked with VMW file.

ffmpeg -i input.wmv -i input.ass -c:v copy -c:a copy -c:s copy -map 0:0 -map 0:1 -map 1:0 -y out.mkv

see the wiki page Comparison of container formats


ffmpeg supports the mov_text subtitle encoder which is about the only one supported in an MP4 container and playable by iTunes, Quicktime, iOS etc.

Your line would read:

ffmpeg -i input.mp4 -i input.srt -map 0:0 -map 0:1 -map 1:0 -c:s mov_text output.mp4


I tried using MP4Box for this task, but it couldn't handle the M4V I was dealing with. I had success embedding the SRT as soft subtitles with ffmpeg with the following command line:

ffmpeg -i input.m4v -i input.srt -vcodec copy -acodec copy -scodec copy -map 0:0 -map 0:1 -map 1:0 -y output.mkv

Like you I had to use an MKV output file - I wasn't able to create an M4V file.


I will provide a simple and general answer that works with any number of audios and srt subtitles and respects the metadata that may include the mkv container. So it will even add the images the matroska may include as attachments (though not another types AFAIK) and convert them to tracks; you will not be able to watch but they will be there (you can demux them). Ah, and if the mkv has chapters the mp4 too.

ffmpeg -i <mkv-input> -c copy -map 0 -c:s mov_text <mp4-output>

As you can see, it's all about the -map 0, that tells FFmpeg to add all the tracks, which includes metadata, chapters, attachments, etc. If there is an unrecognized "track" (mkv allows to attach any type of file), it will end with an error.

You can create a simple batch mkv2mp4.bat, if you usually do this, to create an mp4 with the same name as the mkv. It would be better with error control, a different output name, etc., but you get the point.

@ffmpeg -i %1 -c copy -map 0 -c:s mov_text "%~n1.mp4"

Now you can simply run

mkv2mp4 "Video with subtitles etc.mkv"

And it will create "Video with subtitles etc.mp4" with the maximum of information included.