TEDの動画と字幕の合成方法(上級編)


以下の方法は、字幕データの簡易入手サイトがダウンした場合に、自力で字幕データを入手し、動画と字幕を合成する方法です。これは、Windows, Mac, UNIX系OSの全てで実行可能です。しかし、この方法はスクリプト言語の使用や、コマンドプロンプトの利用に慣れていないと難しいため、万人向けではありません

ここでの解説は、Windows上での作業を前提にしています。MacやUNIX系OSでは、スクリプトの日本語処理を、それぞれの環境に合わせて修正する必要があります。

  • 必要な言語環境とプログラムなど
  1. Python Ver. 2系をインストール(環境によっては、追加のパッケージが必要になる場合あり)
    http://www.python.jp/Zope/Zope/download/pythoncore

  2. Avidemux Ver. 2.5系をインストール
    http://sourceforge.net/projects/avidemux/files/avidemux/2.5.6/

  3. 作業ディレクトリの作成

  4. TTFフォントを入手して、作業ディレクトリに置く
    見やすいPゴチック系フォント
    http://ipafont.ipa.go.jp/ipafont/download.html

    レトロなシネマ系フォント(漢字は、第1水準のみ)
    http://www.forest.impress.co.jp/library/software/cinecaption/

  5. 動画をダウンロードし、作業ディレクトリに置く
  • 字幕データの入手
    wgetコマンドが利用可能な場合は、以下のコマンドで字幕データが入手できる。
    ${TALKID}の部分は、TEDのサイトで、動画の埋め込みタグ情報を見ると確認できる。

    wget -O - http://www.ted.com/talks/subtitles/id/${TALKID}/lang/jpn > jpn.json

    wgetコマンドが利用できない場合は、以下のスクリプトを作成し、ファイル名get.pyで保存。

    #!/usr/bin/python
    # -*- encoding: utf-8 -*-
    
    import urllib
    import sys
    
    id = raw_input('Enter TED ID: ')
    url = 'http://www.ted.com/talks/subtitles/id/%s/lang/jpn' % id
    
    try:
      (filename, headers) = urllib.urlretrieve(url, 'jpn.json')
    except IOError:
      print error
      sys.exit(1)
    urllib.urlcleanup()  # キャッシュの削除
    
    # ヘッダーを全て表示させたい場合
    #for l in str(headers).splitlines():
    #  print l
    #print "-" * 80
    
    print 'Content-Length: %s <== ここがゼロの場合、ID 間違いの可能性あり。' % headers['Content-Length']
    print 'Filename: %s' % filename
    

    実行コマンド例(ID番号は標準入力から対話型で入力):

    python get.py

  • 字幕データの変換
    上記で入手した字幕データはjson形式のため、このままでは利用できない。
    以下のスクリプトをファイル名sub.pyで作成して、字幕の汎用srt形式に変換する。

    #!/usr/bin/python
    # -*- encoding: utf-8 -*-
    
    import sys
    import codecs
    from datetime import date, datetime, time, timedelta
    
    import simplejson as json
    
    sys.stdin  = codecs.getreader('utf-8')(sys.stdin)
    sys.stdout = codecs.getwriter('utf-8')(sys.stdout)
    
    def timestr(timeobj):
        return timeobj.strftime('%H:%M:%S,') + '%03d' % (timeobj.microsecond // 1000)
    
    # MAX_CHARS文字より長いときは2行に分ける
    MAX_CHARS=40
    
    def main():
        f = open(sys.argv[1], 'r')
        captions = json.load(f)['captions']
        for i, c in enumerate(captions):
            startTime = int(c['startTime'])
            duration = int(c['duration'])
            # TEDのスプラッシュの時間を加える
            startTime += 16000
            st = datetime.combine(date.today(), time(0, 0)) + timedelta(milliseconds=startTime)
            et = st + timedelta(milliseconds=duration)
    
            if len(c['content']) > MAX_CHARS:
                print u'%d\n%s --> %s\n%s\n%s\n' % (i+1, timestr(st), timestr(et),
                                                    c['content'][0:MAX_CHARS],
                                                    c['content'][MAX_CHARS:])
            else:
                print u'%d\n%s --> %s\n%s\n' % (i+1, timestr(st), timestr(et), c['content'])
    
    if __name__ == '__main__':
        main()

    実行コマンド例:

    python sub.py jpn.json > jpn.srt

  • 動画と字幕の合成
  1. 上記で作成した字幕データjpn.srtファイルを作業ディレクトリに置く。
  2. Avidemuxで動画を読み込む。
  3. 動画の変換形式でMPEG-4 AVCなどを選択する。
  4. Videoタブで、Filters -> Subtitles -> Subtitlerを選択。
    ここで、フォントの種類、サイズ、色、表示位置などを指定して、合成を実行する。
    Windowsの場合、システムフォルダのフォントを利用できないため、予め作業ディレクトリに保存しておいたフォントを指定する。

Shibasaki Lab.