FFmpeg : mp4 and multiple srt into mkv

8,031

Solution 1

Here's the full answer that I made according to my needs.

Code

#!/bin/zsh

mkv_sub_getshort() {
    sub=$1
    sub="${sub%.${sub:e}}"
    sub="$(sed 's/^.*[[:punct:]]//g' <<< "$sub")"
    echo $sub
}

mkv_maker() {
    local c=0
    for i in *srt; do
        LOCAL_SUB[((++c))]="$i"
        LOCAL_SUB_SHORT[$c]="$(mkv_sub_getshort "$i")"
    done

    local W="   "
    printf "ffmpeg -i *mp4"
    printf "$(for i in ${LOCAL_SUB[*]}; do printf "${W}-i \"$i\""; done)"
    printf "$(for i in $(seq $((${#LOCAL_SUB} + 1))); do printf "${W}-map $((i - 1))"; done)"
    printf "${W}-c copy"
    printf "$(for i in $(seq ${#LOCAL_SUB}); do ((--i)); printf "${W}-metadata:s:s:$i language=${LOCAL_SUB_SHORT[$((i + 1))]%.srt}"; done)"
    printf "${W}output.mkv"

    unset LOCAL_SUB LOCAL_SUB_SHORT
}

mkv_maker

This generates the command for the number of subtitle tracks in folder.

Sample output

$ ls -a
.           ..          mkvmaker vid.mp4     vid_eng.srt vid_fr.srt  vid_rus.srt vid_swe.srt

$ ./mkvmaker
ffmpeg -i *mp4 -i "vid_eng.srt" -i "vid_fr.srt" -i "vid_rus.srt" -i "vid_swe.srt" -map 0 -map 1 -map 2 -map 3 -map 4 -c copy -metadata:s:s:0 language=eng -metadata:s:s:1 language=fr -metadata:s:s:2 language=rus -metadata:s:s:3 language=swe output.mkv

Credits

Credit goes to LordNeckbeard for the previous answer which helped me to understand how to make this working.

Solution 2

Using ffmpeg:

ffmpeg -i video.mp4 -i subtitle1.srt -i subtitle2.srt -map 0 -map 1 -map 2 \
-c copy -metadata:s:s:0 language=eng -metadata:s:s:1 language=ipk output.mkv
  • This will stream copy (-c copy) all streams, so re-encoding is avoided.

  • The default stream selection will only choose one stream per stream type, so -map is used to manually override that.

  • I don't use avconv, so I don't know if any of this info will apply. Make sure you're using a recent, real version of ffmpeg. Development is very active and the counterfeit "ffmpeg" from the Libav fork is old and dead. See the FFmpeg Download page for various options.

Share:
8,031

Related videos on Youtube

theoden8
Author by

theoden8

Updated on September 18, 2022

Comments

  • theoden8
    theoden8 over 1 year

    I have a couple of srt subtitle tracks for an mp4 video. How do I make them into mkv using ffmpeg/avconv?

    I would like to use space efficiently. Performing conversion on Darwin v13. I will be grateful if anyone could help me with that. Thanks in advance.

    I can use any shell that makes a sufficiently convenient environment for the operation. However, I mostly use zsh.

    Example

    /some/path
        Lecture_About_Evolution_of_Evolution.mp4
        english.srt
        native.srt
        perl.srt
        elven.srt
    

    I want to generate Lecture.mkv out of the mp4 file and all *.srt subtitle tracks. But I have no idea how.

  • theoden8
    theoden8 over 8 years
    Is it possible to make it independant from the number of subtitle tracks?
  • Elisa Cha Cha
    Elisa Cha Cha over 8 years
    @theoden Can you explain in more detail? I'm not quite following what you're asking.
  • theoden8
    theoden8 over 8 years
    I mean so that all srts of a mask and an mp4 file are combined into one mkv file. Although the solution you provided seems to be working, it aims only 2 subtitle tracks. Is there a scheme for doing that? I added an example to make myself clear. Sorry for being slightly misunderstood.
  • Elisa Cha Cha
    Elisa Cha Cha over 8 years
    @theoden You are looking for a complete script? I'm not a zsh user, but I recommend looking at globbing and arrays. shellcheck is always helpful for bash.
  • Elisa Cha Cha
    Elisa Cha Cha over 8 years
    @theoden You will have to explicitly list each SRT input as shown in the example.
  • theoden8
    theoden8 over 8 years
    So, it's like ffmpeg -i vid.mp4 -i srt1 -i srt2 -i .. -i srtN -map 0 -map 1 ... -map N -c copy -metadata:s:s:0 language=lang1 ... -metadata:s:s:N-1 language=langN output.mkv, right?
  • Elisa Cha Cha
    Elisa Cha Cha over 8 years
    @theoden Looks good to me.