xjbeta / MkvAutoSubset

ASS字幕字体子集化 MKV批量提取/生成

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Mkv Auto Subset

GitHub release (latest SemVer including pre-releases)

ASS字幕字体子集化 MKV批量提取/生成

什么叫字幕字体子集化

  • 这里说的字幕特指ass(ssa)这种带有特效的文本字幕;
  • ass字幕会引用一些字体,这些字体在播放器所在的系统里可能有安装,也可能没有;
  • 为了实现在任意地方都能有完整的视觉体验,可以把字幕以及字幕里所引用的字体文件一起打包进mkv文件里;
  • 以上的操作存在一个问题,有些字幕会引用很多字体,这些字体文件体积动辄几十MB,而字幕只用到了其中的几个字而已;
  • 比如一个番剧本体200M,但打包了字体文件后变成400M了,这像画吗?
  • 综上所述,子集化的目的就是把字体拆包,找出字幕用到的那部分字形并重新打包;
  • 好处不仅限于节约存储空间,加快缓冲速度;
  • 想想看:在一个只有30Mbps上传的网络环境下,要看上面那个光字体就200M的番剧,这河里吗?

mkvtool 安装

依赖

  • FontTools

    apt install fonttools #Debian/Ubuntu
    apk add py3-fonttools #Alpine
    brew install fonttools #macOS
    pip install fonttools #Use pip
  • MKVToolNix

    apt install mkvtoolnix #Debian/Ubuntu
    apk add mkvtoolnix #Alpine
    brew install mkvtoolnix #macOS
  • ass2bdnxml

    这里获取

关于Windows用户

  • 这里 下载并安装Python
  • 命令提示符(CMD)里参考上面使用pip的方式安装FontTools依赖
  • 这里 获取ass2bdnxml
  • 这里 下载并安装MKVToolNix
  • 保证以上两个依赖项的相关可执行文件(ttx.exe,pyftsubset.exe,mkvextract.exe,mkvmerge.exe,ass2bdnxml.exe)在 path 环境变量里

本体

  • 有安装Go的情况:

    go install github.com/KurenaiRyu/MkvAutoSubset/mkvtool@latest #安装和更新
  • Arch Linux用户(通过Arch User Repository):

    • 点击这里 查看具体信息或使用AUR Helper
    yay -S mkvtool #yay
    paru -S mkvtool #paru
  • 手动安装:

    点此下载

  • macOS用户请注意

    • 由于系统默认的maxfiles值过低,会导致建立字体缓存等操作不能正常完成,请手动调高
    • 详细操作请参考这里
    • 调高限制后请完全重启终端进行后续操作
    • *如其他类unix平台遇到相同的问题也可参照

mkvtool 功能及使用示例

  • 2022.04更新的ASS转PGS说明
    mkvtool -a2p -apc -pr 1920*1080 -pf 23.976 ...xxx...
    
    #-a2p: 启用ass转pgs(依赖ass2bdnxml)
    #-apc: 使pgs字幕与子集化后的ass字幕共存(该选项会影响混流行为)
    #-pr: 设置psg字幕的分辨率(例如"720p,1080p,2k"或者类似“720*480”)
    #-pf: 设置psg字幕的帧率(例如"23.976, 24, 25, 30, 29.97, 50, 59.94, 60"或者类似“15/1”)
  • 2022.04新增的输出MKS格式说明(影响“-m”,"-c"模式)
    mkvtool -mks ...xxx...
    
    #-mks: 启用MKS格式输出
  • 缓存相关(缓存会影响工作流,即无需额外准备在缓存内的字体.)
    • 创建字体缓存(推荐缓存 超级字体整合包 XZ "完整包"可完全缓存,但不保证所有字体都能成功子集化.)
      mkvtool -cc -s input #从${input}获取字体信息并创建缓存
      
      #可选"-cp"参数:指定缓存文件的保存路径.
    • 取得一个目录里所有ass字幕文件所需要的全部字体
      mkvtool -l -s input #从${input}获取
      
      #可选"-cfc"参数:当"-cfc"存在时,将从字体缓存中复制需要的字体到指定目录.
      #可选"-co"参数:指定字体复制的目标目录.
      #可选"-cp"参数:指定要使用的缓存文件.
  • 标准工作流
    mkvtool -s bangumi 
    
    #从${bangumi}文件夹抽取所有mkv文件的字幕和字体,
    #遇到ass字幕就自动进行子集化,
    #输出替换字幕和字体后的新mkv文件.
    #-data参数默认值为"${workdir}/data",指定提取mkv的输出文件夹.
    #-dist参数默认值为"${workdir}/dist",指定重组后mkv的输出文件夹.
  • 从单个(或文件夹的)mkv文件里抽取字幕和字体并创建子集化后的版本(可选)
    mkvtool -d -f file.mkv #单个文件
    mkvtool -d -s bangumi #文件夹
    
    #可选"-n"参数:当"-n"存在时,只抽取内容,不进行子集化操作.
    #可选"-data"参数,指定输出文件夹,默认输出到"${workdir}/data".
  • 检测单个(或文件夹的)mkv文件字幕和字体,判断是否需要子集化.
    mkvtool -q -f file.mkv #单个文件,会直接输出是否需要子集化
    mkvtool -q -s bangumi #文件夹,会将需要子集化的文件列表输出至"${workdir}/list.txt".
  • 将子集化后的字幕与字体替代原有的内容
    mkvtool -m -s bangumi -data data -dist dist
    
    #-data参数默认值为"${workdir}/data",字幕和字体的数据文件夹.
    #-dist参数默认值为"${workdir}/dist",重组后mkv的输出文件夹.
    #假设bangumi文件夹里的目录结构如下所示:
    #bangumi
    # |-- S01
    # ||-- abc S01E01.mkv
    # ||-- abc SxxExx.mkv
    # |-- SP.mkv
    # |-- xx.mkv
    #那么对应的data文件夹的目录结构应该是如下的所示:
    #data
    # |-- S01
    # ||-- abc S01E01
    # |||-- ...
    # |||-- subsetted
    # |||-- xxx.sub
    # ||-- abc SxxExx
    # |||-- ...
    # |||-- subsetted
    # |||-- xxx.sub
    # |||-- ...
    # |-- SP
    # |||-- ...
    # |||-- subsetted
    # |||-- xxx.sub
    # |||-- ...
    # |-- xx
    # |||-- ...
    # |||-- subsetted
    # |||-- xxx.sub
    # |||-- ...
    
    #*奇淫巧技:指定一个没有任何内容的data文件夹,将输出一个"干净"的mkv文件.
  • 从一组文件夹获得情报并生成一组mkv
    mkvtool -c -s bangumi
    
    #可选"-clean"参数:当"-clean"存在时,将清空原有的字幕和字体(默认为追加).
    #bangumi文件夹里的目录结构应如下所示:
    #bangumi
    # |-- v
    # ||-- aaa.mkv
    # ||-- bbb.mp4
    # ||-- ccc.avi
    # |-- s
    # ||-- aaa.ass
    # ||-- aaa.srt
    # ||-- aaa.sup
    # ||-- aaa.xxx
    # ||-- bbb.xxx
    # ||-- ccc.xxx
    # |-- f
    # ||-- abc.ttf
    # ||-- def.ttc
    # ||-- ghi.otf
    # ||-- ...
    
    #若遇到ass字幕会自动进行子集化操作.
    #成品会放在"${bangumi}/o"文件夹中.
  • 对一个(或多个)ass字幕进行字体子集化
    mkvtool -a aaa.ass -a bbb.ass -af fonts -ao output [-ans]
    
    #"-a"参数为ass字幕文件路径,可复用.
    #"-af"参数为字体文件夹路径,默认值为"${workdir}/fonts".
    #"-ao"参数为子集化成品输出路径,默认值为"${workdir}".
    #*当"-ans"参数存在时输出文件夹为"${output}",否则为${output}/subsetted".
    #*由于会预先清空${output}文件夹,为了安全请慎用"-ans".

一些碎碎念

  • "-cp"参数:手动指定缓存文件路径,当提供的字体目录里缺少字体时,会尝试在缓存里查找.

  • "-log"参数:输出终端输出到指定文件,空为不输出,默认为空.

  • "-m","-c"模式下的"-sl","-st"参数:

    -sl:字幕语言.格式为语言缩写如"chi","jpn","eng"等,默认值为"chi".
    -st:字幕标题.该字幕在播放器里显示的标题,默认值为空.
    
  • 字幕文件名规范:

    抽取出来的字幕长得像是如下的样子:
    a_b_c.d
    a:轨道编号(在"-c"模式里,这里应该和视频文件的文件名相同.)
    b:字幕语言代码
    c:字幕标题
    d:字幕文件后缀名
    
    那么,请体会在"-c"模式中,以下的命名方式所带来的便利:
    |-- v
    ||-- aaa.mp4
    |-- s
    ||-- aaa_chi_简体中文.ass
    ||-- aaa_chi_繁體中文.srt
    ||-- aaa_jpn_日本語.sup
    ||-- aaa_eng_English.srt
    
  • 字幕语言代码表:

    点此获取

About

ASS字幕字体子集化 MKV批量提取/生成

License:GNU General Public License v3.0


Languages

Language:Go 53.6%Language:C# 41.6%Language:Python 2.8%Language:Roff 1.8%Language:C 0.2%