代码

代码

我的视频有几个srt字幕轨道mp4。如何mkv使用ffmpeg/将它们制作成字幕轨道avconv

我想高效利用空间。执行转换达尔文 v13。如果有人能帮助我,我将不胜感激。提前致谢。

我可以使用任何可以为操作提供足够方便的环境的 shell。不过,我主要使用zsh

例子

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

我想生成Lecture.mkv文件mp4和所有*.srt字幕轨道。但我不知道该怎么做。

答案1

使用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
  • 这会流复制-c copy)所有流,因此避免了重新编码。

  • 默认流选择每个流类型只会选择一个流,因此-map用于手动覆盖它。

  • 我不用avconv,所以我不知道这些信息是否适用。请确保您使用的是 的最新真实版本ffmpeg。开发非常活跃,而ffmpegLibav 分支的仿冒版本“ ”已经过时了。请参阅FFmpeg 下载页面包含各种选项。

答案2

这是我根据自己的需要做出的完整答案。

代码

#!/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

这将生成文件夹中字幕轨道数量的命令。

示例输出

$ 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

致谢

功劳归于颈须领主先前的回答帮助我理解如何使其发挥作用。

相关内容