【Python】動画字幕・テロップ用のSRT(SubRip)ファイルを扱う

【Python】動画字幕・テロップ用のSRT(SubRip)ファイルを扱う プログラミング

「動画に日本語字幕・テロップを入れたい」
「SRTファイルをPythonプログラムで処理したい」

このような場合には、srtがオススメです。
この記事では、PythonでSRTファイルを扱うための方法を解説しています。

本記事の内容

  • srtとは?
  • srtのシステム要件
  • srtのインストール
  • srtの動作確認

それでは、上記に沿って解説していきます。

srtとは?

srtとは、SRTファイルを扱うためのPythonライブラリです。
具体的には、次の処理をSRTファイルに行うことができます。

  • 解析(パース)
  • 変更
  • 作成(合成)

また、SRTファイルを処理するPythonライブラリは何個か存在しています。
その中では、srtが最もメンテナンスされています。
(ある程度のダウンロード実績が前提)

その点からも、SRTファイルを扱う上ではsrtがオススメとなります。

以上、srtについて説明しました。
次は、srtのシステム要件を説明します。

srtのシステム要件

現時点(2022年9月末)でのsrtの最新バージョンは、3.5.2となります。
この最新バージョンは、2022年3月5日にリリースされています。

サポートOSに関しては、以下を含むクロスプラットフォーム対応です。

  • Windows
  • macOS
  • Linux

サポート対象となるPythonのバージョンは、以下。

  • Python 2.7
  • Python 3.5
  • Python 3.6
  • Python 3.7
  • Python 3.8
  • Python 3.9
  • Python 3.10

稼働しているPythonの全カバーという感じでしょうか。
でも、以下のPython公式開発サイクルからは大きく逸脱しています。

バージョンリリース日サポート期限
3.62016年12月23日2021年12月23日
3.72018年6月27日2023年6月27日
3.82019年10月14日2024年10月
3.92020年10月5日2025年10月
3.102021年10月4日2026年10月

Python 3.6が、すでに2021年末でサポート期限が切れています。
現在では、Python 3.7以降がPython公式の認めるバージョンになります。

ここまでより、srtのシステム要件はほぼありません。
何と言っても、srtはPure Pythonですからね。

Pythonのみで開発されていることになります。
このようなライブラリは、導入が非常に容易です。

以上、srtのシステム要件を説明しました。
次は、srtのインストールを説明します。

srtのインストール

検証は、次のバージョンのPythonで行います。

> python -V  
Python 3.10.4

まずは、現状のインストール済みパッケージを確認しておきます。

> pip list 
Package    Version 
---------- ------- 
pip        22.2.2 
setuptools 65.3.0 
wheel      0.37.1

次にするべきことは、pipとsetuptoolsの更新です。
pipコマンドを使う場合、常に以下のコマンドを実行しておきましょう。

python -m pip install --upgrade pip setuptools

では、srtのインストールです。
srtのインストールは、以下のコマンドとなります。

pip install srt

srtのインストールは、一瞬で終わります。
終了したら、どんなパッケージがインストールされたのかを確認します。

> pip list 
Package    Version 
---------- ------- 
pip        22.2.2 
setuptools 65.3.0 
srt        3.5.2 
wheel      0.37.1

srtが依存するパッケージは、存在しません。
Pure Pythonでもあり、srtのインストールはどんな環境にでも容易にできそうです。

以上、srtのインストールを説明しました。
次は、srtの動作確認を説明します。

srtの動作確認

srtの動作確認を行います。
ここでは、以下の動作を対象にします。

  • SRTファイルの読み込み
  • SRTファイルの作成

それぞれを以下で説明します。

SRTファイルの読み込み

まずは、SRTファイルを用意します。
用意できない場合は、次のページのサンプルを拝借しましょう。

SRTファイルの利用方法 | eラーニング教材作成ソフト STORM
https://suite.logosware.com/storm-maker/srt/

上記ページにある次のボタンをクリックすると、zipファイルをダウンロードできます。
(※ダウンロードできない場合は、以下のsample.srtからSRTファイルを作成してください)

ダウンロードしたzipをファイルを解凍すると、以下のファイルを確認できます。

ここでは、このSRTファイルをsrtで読み込みます。
sample.srtは、テキストファイルに過ぎません。

sample.srt

1 
00:00:00,000 --> 00:00:06,900 
講座「テレワーカーのためのセキュリティ」ではテレワーカーを対象に

2 
00:00:06,900 --> 00:00:13,610 
テレワークの情報セキュリティについてその基本的な考え方を解説します

3 
00:00:13,610 --> 00:00:18,650 
テレワークは勤務先とは別の場所で働く形のことです

4 
00:00:18,650 --> 00:00:23,150 
テレワークでは、PCやスマホなどの端末、

5 
00:00:23,150 --> 00:00:26,500 
会社とやり取りする通信経路、

6 
00:00:26,500 --> 00:00:31,640 
社外とやり取りできる社内システムが必要です

7 
00:00:31,640 --> 00:00:37,030 
テレワークでは会社の情報資産がインターネット上を行き交うことになり

8 
00:00:37,030 --> 00:00:40,460 
盗聴や漏洩の危険が高まります

9 
00:00:40,460 --> 00:00:45,960 
このためテレワークに対応したルールやセキュリティ対策が必須です

10 
00:00:45,960 --> 00:00:55,100 
テレワーカーはこれらを守ることで安心して業務にあたることができます

このSRTファイルを次のコードで読み込みます。

import srt

with open("sample.srt", mode='r', encoding="utf-8") as f: 
    subs = srt.parse(f.read()) 
    for sub in subs: 
        print(sub)

上記を実行すると、コンソールには以下のように表示されます。

Subtitle(index=1, start=datetime.timedelta(0), end=datetime.timedelta(seconds=6, microseconds=900000), content='講座「テレワーカーのためのセキュリティ」ではテレワーカーを対象に', proprietary='') 
Subtitle(index=2, start=datetime.timedelta(seconds=6, microseconds=900000), end=datetime.timedelta(seconds=13, microseconds=610000), content='テレワークの情報セキュリティについてその基本的な考え方を解説します', proprietary='') 
Subtitle(index=3, start=datetime.timedelta(seconds=13, microseconds=610000), end=datetime.timedelta(seconds=18, microseconds=650000), content='テレワークは勤務先とは別の場所で働く形のことです', proprietary='') 
Subtitle(index=4, start=datetime.timedelta(seconds=18, microseconds=650000), end=datetime.timedelta(seconds=23, microseconds=150000), content='テレワークでは、PCやスマホなどの端末、', proprietary='') 
Subtitle(index=5, start=datetime.timedelta(seconds=23, microseconds=150000), end=datetime.timedelta(seconds=26, microseconds=500000), content='会社とやり取りする通信経路、', proprietary='') 
Subtitle(index=6, start=datetime.timedelta(seconds=26, microseconds=500000), end=datetime.timedelta(seconds=31, microseconds=640000), content='社外とやり取りできる社内システムが必要です', proprietary='') 
Subtitle(index=7, start=datetime.timedelta(seconds=31, microseconds=640000), end=datetime.timedelta(seconds=37, microseconds=30000), content='テレワークでは会社の情報資産がインターネット上を行き交うことになり', proprietary='') 
Subtitle(index=8, start=datetime.timedelta(seconds=37, microseconds=30000), end=datetime.timedelta(seconds=40, microseconds=460000), content='盗聴や漏洩の危険が高まります', proprietary='') 
Subtitle(index=9, start=datetime.timedelta(seconds=40, microseconds=460000), end=datetime.timedelta(seconds=45, microseconds=960000), content='このためテレワークに対応したルールやセキュリティ対策が必須です', proprietary='') 
Subtitle(index=10, start=datetime.timedelta(seconds=45, microseconds=960000), end=datetime.timedelta(seconds=55, microseconds=100000), content='テレワーカーはこれらを守ることで安心して業務にあたることができます', proprietary='')

値を取り出す場合は、次のように記述します。

    for sub in subs: 
        print(sub.index) 
        print(sub.start) 
        print(sub.end) 
        print(sub.content)

そうすると、以下のように表示されます。

1 
0:00:00 
0:00:06.900000 
講座「テレワーカーのためのセキュリティ」ではテレワーカーを対象に 
2 
0:00:06.900000 
0:00:13.610000 
テレワークの情報セキュリティについてその基本的な考え方を解説します
~省略~

SRTファイルの作成

美しくないコードで説明します。
わかりやすさを優先したコードになります。

from datetime import timedelta 
from srt import Subtitle 
import srt

# list型 
subs = []

# 0秒 ~ 3.5秒 
index_1 = 1 
start_1 = 0 
end_1 = 3.5 
text_1 = "0秒 ~ 3.5秒" 
sub_1 = Subtitle(index=index_1, 
                 start=timedelta(seconds=timedelta(seconds=start_1).seconds, 
                                 microseconds=timedelta(seconds=start_1).microseconds), 
                 end=timedelta(seconds=timedelta(seconds=end_1).seconds, 
                               microseconds=timedelta(seconds=end_1).microseconds), 
                 content=text_1)

# 3.51秒 ~ 7.25秒 
index_2 = 2 
start_2 = 3.51 
end_2 = 7.25 
text_2 = "3.51秒 ~ 7.25秒" 
sub_2 = Subtitle(index=index_2, 
                 start=timedelta(seconds=timedelta(seconds=start_2).seconds, 
                                 microseconds=timedelta(seconds=start_2).microseconds), 
                 end=timedelta(seconds=timedelta(seconds=end_2).seconds, 
                               microseconds=timedelta(seconds=end_2).microseconds), 
                 content=text_2)

# 7.26秒 ~ 15秒 
index_3 = 3 
start_3 = 7.26 
end_3 = 15 
text_3 = "7.26秒 ~ 15秒" 
sub_3 = Subtitle(index=index_3, 
                 start=timedelta(seconds=timedelta(seconds=start_3).seconds, 
                                 microseconds=timedelta(seconds=start_3).microseconds), 
                 end=timedelta(seconds=timedelta(seconds=end_3).seconds, 
                               microseconds=timedelta(seconds=end_3).microseconds), 
                 content=text_3)

subs.append(sub_1) 
subs.append(sub_2) 
subs.append(sub_3)

with open("test.srt", mode="w", encoding="utf-8") as f: 
    f.write(srt.compose(subs))

timedeltaについては、初めて見た人もいるかもしれません。
詳細は、調べてみてください。

コードのポイントは、以下となります。

  • Subtitle型(<class ‘srt.Subtitle’>)でデータを生成する
  • Subtitle型のデータをlist型配列に追加する
  • compose関数でlist型配列をテキスト(文字列)に変換する

冗長なコードを見れば、内容はすぐに理解できるはずです。
そして、上記コードを実行すると次のファイルが作成されます。

test.srt

1 
00:00:00,000 --> 00:00:03,500 
0秒 ~ 3.5秒

2 
00:00:03,510 --> 00:00:07,250 
3.51秒 ~ 7.25秒

3 
00:00:07,260 --> 00:00:15,000 
7.26秒 ~ 15秒

もちろん、test.srtをsrtで読み込むことが可能です。
読み込めないと、SRTファイルを作成できていないことになってしまいます。

以上、srtの動作確認を説明しました。

タイトルとURLをコピーしました