FFmpeg: mp4 et plusieurs srt en mkv

3

J'ai quelques srtpistes de sous-titres pour une mp4vidéo. Comment puis-je les transformer mkven ffmpeg/ avconv?

Je voudrais utiliser l'espace efficacement. Conversion en cours sur Darwin v13 . Je serais reconnaissant si quelqu'un pouvait m'aider avec cela. Merci d'avance.

Je peux utiliser n'importe quel shell qui crée un environnement suffisamment pratique pour l'opération. Cependant, je l'utilise surtout zsh.

Exemple

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

Je veux générer à Lecture.mkvpartir du mp4fichier et de toutes les *.srtpistes de sous-titres. Mais je ne sais pas comment.

Théoden
la source

Réponses:

7

Utilisant 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
  • Ceci transmettra à copy ( -c copy) tous les flux, évitant ainsi le réencodage.

  • La sélection de flux par défaut ne choisit qu'un flux par type de flux, elle -mapest donc utilisée pour le remplacer manuellement.

  • Je ne l'utilise pas avconv, donc je ne sais pas si ces informations s'appliqueront. Assurez-vous que vous utilisez une version récente et réelle de ffmpeg. Le développement est très actif et la contrefaçon " ffmpeg" de la fourche Libav est ancienne et morte. Voir la page de téléchargement de FFmpeg pour diverses options.

llogan
la source
Est-il possible de le rendre indépendant du nombre de pistes de sous-titres?
theoden
@theoden Pouvez-vous expliquer plus en détail? Je ne suis pas tout à fait ce que vous demandez.
llogan
Je veux dire que tous srtles éléments d’un masque et d’un mp4fichier sont combinés en un seul mkvfichier. Bien que la solution que vous avez fournie semble fonctionner, elle ne vise que 2 pistes de sous-titres. Existe-t-il un système pour le faire? J'ai ajouté un exemple pour me rendre clair. Désolé d'être légèrement incompris.
theoden
@theoden Vous recherchez un script complet? Je ne suis pas un zshutilisateur, mais je recommande de regarder globbing et les tableaux. shellcheck est toujours utile pour bash.
llogan
@theoden Vous devrez lister explicitement chaque entrée SRT comme indiqué dans l'exemple.
llogan
1

Voici la réponse complète que j'ai faite en fonction de mes besoins.

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

Cela génère la commande pour le nombre de pistes de sous-titres dans le dossier.

Échantillon de sortie

$ 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

Crédits

Le crédit va à LordNeckbeard pour la réponse précédente qui m'a aidé à comprendre comment faire ce travail.

Théoden
la source