16

How can I merge subtitle to a movie to play on my android TV?

I searched for a long time but almost program no longer work on ubuntu or I can't find the repository . Here is some answer but I think it's no longer supported on 16.04

2

4 Answers 4

28

If your TV can play movies that have subtitles muxed into the same file as the video, there are many advantages to adding the subtitles as a subtitle track, instead of burning them into the video.

mkvmerge -o movie_with_subs.mkv   movie.mp4  subs.srt

That will include all tracks from the mp4 (video, audio, chapters), and subs from the srt as a text subtitle track. It takes about as long as copying the file, since it doesn't have to decode/re-encode the video.

Ubuntu packages mkvmerge in mkvtoolnix. There's an mkvtoolnix-gui package, with a gui frontend. It has a lot of options to let you control things like the subtitle offset.

The major advantage to this is that you avoid degrading the quality with another decode/encode cycle of generation loss. It's impossible to avoid losing quality when transcoding, and it takes a lot of CPU time to even come close to the quality-per-filesize of a well-encoded source. (e.g. x264 with -preset slower, or if your player supports it, x265 if you're willing to spend a huge amount of CPU time to make smaller files that still look good). If you don't care about file size because you're just streaming it to your TV, transcoding with x264 with -preset veryfast -crf15 can run quickly and lose minimal quality.

Another advantage to muxing subs is that you can then toggle the subs on/off, or have your player show them in a different position on screen.

You can also extract them later and search them if you're trying to remember a line from the movie.

You can even extract them, fix typos, and mux them back in.

7
  • It would be so perfect if the output file would also have the subtitles when Chromecasting. Any idea how to elaborate your answer for Chromecast?
    – JKHA
    Apr 23, 2020 at 4:20
  • @JKHA: I don't know anything about chromecast or what containers or subtitle formats it supports. Hopefully some kind of "soft" subtitle (not burned into the video). Apr 23, 2020 at 4:24
  • Thanks for your reply. I'm trying to "convert srt to vobsub" before muxing as you wrote on Mohamed Slama's answer. Fingers crossed I'd work
    – JKHA
    Apr 23, 2020 at 4:26
  • @JKHA: good luck, then. If you find a way that works, you could post an answer to this question. Apr 23, 2020 at 4:33
  • 1
    Best solution, thank you. It needs only few seconds work instead other solutions which will need 1-2h. Dont forget to place srt file with same name as mkv file on usb. Great!
    – josifoski
    Apr 16, 2021 at 14:45
18

I use Hand Brake on my ubuntu 16.04 great application and very simple to use . https://launchpad.net/~stebbins/+archive/ubuntu/handbrake-releases

Installation:

sudo add-apt-repository ppa:stebbins/handbrake-releases
sudo apt-get update 
sudo apt-get install handbrake

How it work:

  • Click on source and chose movie.
  • From subtitle List tab click on Add.
  • don't forget to tick on Burn into video. List item
  • finally click on Start.
11
  • 1
    @PeterCordes i don't know if mkvmerge still supported on 16.04 but when i tried on 14.04 was buggy (not appering arabic subtitle) for me hand brake quality of the original file is the same and is fast may because i have SSD anyway it's great to post new answer for another technology :D Jun 11, 2016 at 2:18
  • 1
    mkvmerge does a 1GB file in a couple seconds with fast hard drives. Transcoding will take at least a few minutes (on a fast multi-core CPU), and that's only if you don't care at all about the file size of the output. If you use a high enough bitrate, you won't be able to notice the quality loss, but it's there. (And your new file will be significantly bigger than your original.) Jun 11, 2016 at 2:23
  • 3
    I know you want to play it on your TV. My point was that it's not actually mkvmerge that buggy, just that your TV's lack of support means muxing an srt probably can't work. If you're interested in trying out the bitmap-subtitle idea, google for "convert srt to vobsub", pick a program and try muxing that into an mkv. First check that it plays on your Ubuntu desktop, then see what happens on your TV. Your definition of "fine" is a lot different from mine; I wouldn't consider it acceptable to lose even a tiny bit of quality by transcoding, especially not to a larger file. Jun 11, 2016 at 2:46
  • 1
    @PeterCordes Thanks for valuable information it worth to try :D Jun 11, 2016 at 2:57
  • 2
    Doen't work. Subtitles do not get burnt
    – Rubi Shnol
    Apr 8, 2018 at 9:42
10

I think that MKVToolNix is the simplest and easiest-to-use free tool available for you to merge a video file with a subtitles file. Just install it by e.g. running a terminal/shell command such as:

sudo apt-get install mkvtoolnix mkvtoolnix-gui -y

...and then run it, right-click the Source files area in order to add your video file and your subtitles file (step 1, at the picture below), specify the location of the destination MKV video file (step 2) and then click on Start multiplexing (step 3). Done.

MVKToolNix's main window

MKVToolNix muxes/multiplexes the subtitles track/stream along with the video track/stream. This means that the output MKV file, like e.g. ~/Videos/output.mkv (the ~ character is a shortcut to your home account folder, e.g. /home/your-account/), will be a video file that contains subtitles embedded in it and you will be able to turn the subtitles on and off, while such MKV video is playing.

PS: if your Android TV doesn't play MKV video files, use MX Player, Kodi Player or VLC Media Player to add MKV playback support.


What if you want subtitles "fused" (hardcoded) in the video, instead of just muxed/multiplexed?

In such case, a laborious-yet-rewarding approach consists on (1) converting your subtitles file to the SSA format, (2) editing the SSA's Style line and then (3) using avconv (Ubuntu version 17.10 or previous) or ffmpeg (Ubuntu version 18.04 or later) to merge/hardcode such stylized subtitles into the video track/stream (the subtitles' characters will then be converted to pictograms or graphical symbols, i.e. pixels not only "laid over" the video's pictures/frames but replacing such pixels).

Here's how to do it:

  1. Use a subtitles editor such as GNOME Subtitles (to install it from the shell, run sudo apt-get install gnome-subtitles -y) to convert your subtitles file (e.g. input.srt) to the SSA format (e.g. input.ssa) and then save the SSA file in ~/Videos (you'll thus have ~/Videos/input.ssa).

  2. Use a simple text editor such as Gedit (install it with the shell command sudo apt-get install gedit -y) to open your SSA file and then replace the entire Style line by e.g. this one:

    Style: Default,Arial,16,&H00FFFF,&H00FFFF,&H00FFFF,&H77000000,2,0,3,2,1,2,10,10,10,0,0

    ...or e.g. this one:

    Style: Default,Times New Roman,18,&H00FFFF,&H00FFFF,&H00FFFF,&H77000000,2,0,3,2,1,2,10,10,10,0,0

    After replacing the Style line, save the SSA file and then close the text editor. The configuration line above will globally preset the subtitles with a 16pt yellow Arial (or an 18pt yellow Times New Roman) font and will add a semi-transparent black background behind the subtitles (to make reading them easier).

  3. Now it's time to use avconv/ffmpeg:

  • 3.1. If you're using Ubuntu version 17.10 or a previous one, install the avconv packages by running this shell command:

    sudo apt-get install ffmpeg libav-tools -y
    

    If you however are using Ubuntu version 18.04 or later, then avconv is deprecated and you must instead install ffmpeg with a shell command such as:

    sudo apt install ffmpeg -y
    

    ...or:

    sudo snap install ffmpeg
    
  • 3.2. Move your video file (e.g. input.avi) to e.g. your Videos folder, in order to end up having e.g. ~/Videos/input.avi and ~/Videos/input.ssa

  • 3.3. Run the shell command cd ~/Videos so the Linux shell enters the ~/Videos directory

  • 3.4. Hardcode the SSA subtitles into the video file by running this shell command:

    ffmpeg -i input.avi -map 0:0 -map 0:1 -c:v libx264 -aspect 16:9 -q:v 1 -b:v 512k -strict -2 -c:a aac -ac 2 -filter:v subtitles=input.ssa output.mp4
    

    Edit: if you're using Ubuntu 17.10 or a previous version, the command above must begin with avconv instead of with ffmpeg.

    The above command uses the libx264 video codec to create an H.264 video file (.mp4 is just the container's file extension). If you however prefer to create an MPEG-4 video file, use the mpeg4 video codec, instead:

    ffmpeg -i input.avi -map 0:0 -map 0:1 -c:v mpeg4 -aspect 16:9 -q:v 1 -b:v 512k -strict -2 -c:a aac -ac 2 -filter:v subtitles=input.ssa output.mp4
    

    Edit: if you're using Ubuntu 17.10 or a previous version, the command above must begin with avconv instead of with ffmpeg.

    The output of the commands above will be ~/Videos/output.mp4 and you'll notice that such MP4 (i.e. x264 or MPEG-4) video file will have hardcoded (i.e. bitmap) subtitles.


Footnotes

  • If you wish to attempt increasing the quality of the merged/output video (even though at the cost of getting a bigger file size), replace the 512k parameter with a larger one (e.g. 1024k).

  • If you however decide to get a smaller file size (even though at the cost of reducing the quality of the merged/output video), replace the 512k parameter with a smaller one (e.g. 256k).

  • If the original (input) video file has an aspect ratio of e.g. 4:2 and you want to preserve it, change -aspect 16:9 to -aspect 4:2.

  • If you don't know the aspect ratio of such video file, open it with a media player and then check it out. For instance, if you open it with VLC, then hit Ctrl + i while it's playing and then select the Codec tab, you'll see such aspect ratio informed at the field named Decoded format.

  • Reducing 512k (to e.g. 256k) works great with the libx264 codec to produce a smaller file, but the mpeg4 codec is more "resilient" to such parameter change. In case you're using -c:v mpeg4 and you want to produce a smaller output file, try changing -q:v 1 to -q:v 2 or -q:v 3. The bigger this number is, the smaller the final file size is.

2
  • Thanks, it works, but file size is blown up ~6 times and changing the parameter from 512k to 256k has no effect on file size at all. Jan 5, 2022 at 14:01
  • 1
    @YanKingYin No prob. Dealing with video codecs is a bit tricky. Changing 512k to 256k works great with the libx264 codec (256k produces a smaller file), but e.g. the mpeg4 codec is more "resilient" to such parameter change. In case you're using -c:v mpeg4, try changing -q:v 1 to -q:v 2 or -q:v 3. The bigger this number is, the smaller the final file size. Jan 5, 2022 at 16:21
4

It now works without converting to .ass on Ubuntu 20.10

They's enabled libass support recently it seems on the package, so now you can just do:

ffmpeg -i hello.mp4 -vf "subtitles=hello2.srt" hello-sub.mp4

Before it was enabled, you needed:

ffmpeg -i hello2.srt hello.ass
ffmpeg -i hello.mp4 -vf ass=hello.ass hello-sub.mp4

You can check for libsass support with:

ffmpeg --version

which now contains:

--enable-libass

The generated output can be seen at: https://www.youtube.com/watch?v=Q0nVA3mYXLU

The test files can be obtained with:

wget -O hello.mp4 https://github.com/cirosantilli/media/blob/master/Top_Down_2D_Continuous_Game_with_Urho3D_C++_SDL_and_Box2D_for_Reinforcement_Learning_first_8_seconds.mp4?raw=true
wget -O hello2.srt https://github.com/cirosantilli/media/blob/master/Top_Down_2D_Continuous_Game_with_Urho3D_C++_SDL_and_Box2D_for_Reinforcement_Learning_first_8_seconds.srt?raw=true

where:

With that said, .ass is a superior format as it can encode font appearance, so it is the best option if you are generating the subtitles yourself.

Related:

Tested on Ubuntu 20.04, ffmpeg 4.2.4.

You must log in to answer this question.