動画に字幕を付ける方法は、大きく ハードサブ(焼き込み) と ソフトサブ(埋め込み) の2種類に分かれます。どちらも FFmpeg で行えます。

ハードサブとソフトサブの違い

方式 概要 主な用途
ハードサブ(焼き込み) 字幕テキストを映像ピクセルに直接描画する。映像の一部になるため後から消せない 字幕が外れないよう固定したい場合、再生環境を問わず表示させたい場合
ソフトサブ(埋め込み) 字幕を独立したトラックとしてコンテナ(MKVなど)に格納する。後からON/OFFや言語切替が可能 複数言語対応、編集の自由度を保ちたい場合

ハードサブは再エンコードが必要で処理時間がかかりますが、どのプレイヤーでも確実に表示されます。ソフトサブはコピー処理だけで済むことが多く高速ですが、対応プレイヤーが限られます。

ハードサブ(焼き込み)

SRT字幕の焼き込み — subtitles フィルタ

subtitles フィルタは libass を内部で使用して字幕ファイルを映像に描画します。

ffmpeg -i input.mp4 -vf subtitles=subtitle.srt output.mp4

各コマンドの subtitle.srt / subtitle.ass は、実際の字幕ファイルのパスに置き換えてください。

フォントサイズや位置を調整する場合:

ffmpeg -i input.mp4 -vf "subtitles=subtitle.srt:force_style='FontSize=24,Alignment=2'" output.mp4

force_style に ASS のスタイル書式を書くと、スタイルを上書きできます(FontSize・PrimaryColour・Alignment など)。

ASS字幕の焼き込み — ass フィルタ

ASS(Advanced SubStation Alpha)はフォント・色・アニメーションなど高度な書式指定が可能な字幕フォーマットです。subtitles フィルタでも読めます。

ffmpeg -i input.mp4 -vf ass=subtitle.ass output.mp4

subtitles=subtitle.ass と ass=subtitle.ass は、どちらも同じ libass で描画するため、出力は見た目では同じです。違いは、ass フィルタが ASS ファイル専用で、force_style や charenc のオプションがない点です。

フォント指定(ASS)

ASS ファイル内の [V4+ Styles] セクションで Fontname を指定します。システムにインストールされていないフォントを使う場合は fontsdir オプションでフォントディレクトリを指定できます。

ffmpeg -i input.mp4 -vf "ass=subtitle.ass:fontsdir=/path/to/fonts" output.mp4

ソフトサブ(埋め込み)

MKVに字幕トラックを埋め込む

MKV コンテナは複数の字幕トラックに対応しています。次のコマンドは、映像・音声をコピーしたまま SRT 字幕を追加します。

ffmpeg -i input.mp4 -i subtitle.srt -map 0:v -map 0:a -map 1 -c copy -c:s srt output.mkv
  • -map 0:v -map 0:a -map 1 は input.mp4 の映像・音声と、subtitle.srt の字幕を選ぶ(付けないと、input.mp4 にすでに字幕がある場合はそちらが入り、subtitle.srt は入りません)
  • -c copy は映像・音声を再エンコードせずコピー
  • -c:s srt は字幕ストリームを SRT フォーマットで埋め込む

複数言語の字幕を埋め込む場合は、-map で入れるストリームを指定します(指定しないと字幕は1本しか入りません):

ffmpeg -i input.mp4 -i sub_ja.srt -i sub_en.srt \
  -map 0:v -map 0:a -map 1 -map 2 \
  -c copy -c:s srt \
  -metadata:s:s:0 language=jpn \
  -metadata:s:s:1 language=eng \
  output.mkv

字幕ストリームのコピー(既存トラック)

すでに字幕トラックを持つ MKV ファイルから字幕を維持したまま変換する場合は -c:s copy を使います。-map 0 を付けないと、音声と字幕は1本ずつしか残りません。

ffmpeg -i input.mkv -map 0 -c:v libx264 -c:a aac -c:s copy output.mkv

MKV → MP4 への字幕変換

MP4 は字幕フォーマットとして mov_text(3GPP Timed Text、tx3g)を使います。MKV の字幕トラックを MP4 に変換する場合:

ffmpeg -i input.mkv -c:v copy -c:a copy -c:s mov_text output.mp4

注意点:

  • ASS/SSA 字幕は mov_text に変換するとスタイル情報が失われます
  • 字幕が表示されるかどうかは、プレイヤーによって違います
  • 再生環境が限定されるなら、ハードサブへの切り替えも検討してください

字幕トラックの確認・抽出

埋め込まれている字幕トラックを確認するには ffprobe を使います:

ffprobe -v error -show_streams -select_streams s input.mkv

字幕を外部ファイルとして抽出するには:

ffmpeg -i input.mkv -c:s srt extracted_subtitle.srt

SRT に変換できるのは、SRT や ASS などのテキストの字幕だけです。Blu-ray の PGS や DVD の VobSub のような画像の字幕は SRT にできず、Subtitle encoding currently only possible from text to text or bitmap to bitmap と表示されて止まります。

まとめ

ユースケース 推奨方式 コマンドのポイント
字幕固定・あらゆる環境で表示 ハードサブ -vf subtitles= または -vf ass=
後から切替可能にしたい ソフトサブ(MKV) -c:s srt で埋め込み
既存トラックをそのまま保持 コピー -c:s copy
MKV → MP4 変換 mov_text -c:s mov_text

関連記事:

よくある質問

ハードサブとソフトサブはどっちがいい?

配信先によって変わります。YouTube / Vimeo は CC 機能(ソフトサブ)に対応していて、字幕のオン / オフを切り替えられます。TikTok / Instagram など SRT に対応していないプラットフォームでは、ハードサブが必須です。

SRT と VTT の違いは?

SRT は最も普及している字幕フォーマットです(番号 + タイムコード + テキストの繰り返し)。VTT は HTML5 video 用で、色やスタイルのタグに対応しています。FFmpeg はどちらも入力に使えます。

字幕が文字化けする

SRT の文字コードが UTF-8 以外(Shift_JIS、UTF-16 など)になっています。テキストエディタで「UTF-8(BOM なし)」で保存し直してください。

字幕のフォントを変えたい

force_style='FontName=Noto Sans CJK JP' のようにスタイルを指定します。指定したフォントがシステムにインストールされているか、fontsdir でフォントのフォルダーを指定する必要があります(Linux では fc-list でインストール済みのフォントを確認できます)。

字幕の位置を画面下から上に移したい

Alignment=8(上)、Alignment=2(下中央、デフォルト)、Alignment=5(中央)で指定します。例: force_style='Alignment=8'。