I'm surprised no one mentioned this:
It has impressive features, it's extremely easy to use and very well-polished. A lot of care and detail in its UI (check the char count in each line).
I use it all the time to shift subtitle timings to/from HDTV to BDRip/DVDRip releases.
Side-note: VLC player has on-the-fly subtitle timing shift. It will not change your .srt
file, only the playback, but it's very convenient for movies you'll only watch once and don't care about saving the adjustments. I assign them to UP and DOWN directional keys.
Softsubs
MP4 supports streaming text format subtitles, but playback support for this among players and devices is not universal.
Basic example using default stream selection behavior while stream copying the audio:
ffmpeg -i input.mkv -c copy -c:s mov_text output.mp4
Example to stream copy all of the video and audio streams, convert the all text based subtitle input streams (SRT, ASS, VTT, etc) to the streaming text format, and set the language for the first two subtitle streams.
ffmpeg -i input.mkv -map 0 -c copy -c:s mov_text -metadata:s:s:0 language=eng -metadata:s:s:1 language=ipk output.mp4
Same as above but re-encode the video and audio to formats compatible with the MP4 container (H.264 video:
ffmpeg -i input.mkv -map 0 -c:v libx264 -c:a aac -c:s mov_text -metadata:s:s:0 language=eng -metadata:s:s:1 language=ipk output.mp4
Same as above but use the -map
option to choose the first video stream, second audio stream, and third subtitle stream:
ffmpeg -i input.mkv -map 0:v:0 -map 0:a:1 -map 0:s:2 -c:v libx264 -c:a aac -c:s mov_text -metadata:s:s:0 language=eng output.mp4
Hardsubs
Text based subtitle format inputs
Use the subtitles filter to "burn-in" text based subtitle formats (SRT, ASS, VTT, etc). Note that this requires re-encoding, so it will by much slower than using softsubs.
Basic example using default stream selection behavior while stream copying the audio:
ffmpeg -i input.mkv -filter_complex "subtitles=input.mkv" -c:a copy output.mp4
Example to use the third video stream, fifth subtitle stream, and first audio stream:
ffmpeg -i input.mkv -filter_complex "[0:v:2]subtitles=input.mkv:si=4[v]" -map "[v]" -map 0:a:0 -c:a copy output.mp4
Example for a separate subtitle input file (your-subtitles-file.srt
):
ffmpeg -i input.mp4 -filter_complex "subtitles=your-subtitles-file.srt" -c:a copy output.mp4
Image based subtitle format inputs
Use the overlay filter. This example will overlay the fourth subtitle stream over the second video stream, and stream copy the seventh audio stream:
ffmpeg -i input.mkv -filter_complex "[0:v:2][0:s:3]overlay[v]" -map "[v]" -map 0:a:6 -c:a copy output.mp4
Also see
Best Answer
Short answer
You could use mkvmerge (
apt-get install mkvtoolnix
) to create a Matroska container and include the subtitles in the output:This does not require re-encoding, so it is pretty fast.
Further customization
You may set the language and name of each subtitle track:
Note that we used for both languages the same track ID (
0:
), which corresponds to the input video track.The
--language
needs to be properly encoded. You can list all allowed ISO 639-2 and ISO 639-1 codes with:Other useful features
You may also set the title of the output video with:
We can check how all subtitles were added to the output:
If you really want to "burn" the subtitles in the video, you may use
ffmpeg
instead.