ショートのテロップ、作ってみたら面倒すぎた — 文字起こしを少しでも楽に

ショート動画のテロップ(字幕)は、見る分には当たり前。でも自分で作ると、どこで何を喋っているかを見て聞いて起こす、ものすごく面倒な作業でした。その面倒をどう減らすか考えて、音声認識で文字起こしとタイムスタンプを自動化し、DogaRunを作るまでの話です。

ショートのテロップ、作ってみたら面倒すぎた — 文字起こしを少しでも楽に

自分でショート動画を作るようになって、テロップ(字幕)付けが想像以上にしんどい作業だと知りました。とくにきついのが文字起こしです。1分ぶんの喋りを起こすだけで、十分以上かかることもあります。一度では聞き取れないので、再生しては数秒戻し、また聞き直す——この往復を延々と繰り返すからです。

テロップはどのショートにも当たり前に入っているので、外から見ると簡単そうに見えます。でも実際に入れる側に回ると、「見て・聞いて・起こして・合わせる」の連続で、地味に一番時間を溶かす工程でした。

見るのは一瞬、作るのはしんどい

面倒は、文字起こしだけで終わりません。起こした文字を、映像の「どのタイミングで出すか」に合わせる作業がまた重い。前に書いた記事(iMovieでテロップが思い通りに置けないときの解決法)のように、iMovieだと自由な位置に置くために、テロップごとグリーンバックの画像を作る羽目になったりもします。字幕の数だけ、この「合わせる・置く」の地味な作業が積み上がっていきます。

どうにかならないか、と考えた

さすがに毎回これは続けられない。どうにかならないか、と考えました。

順番に手をつけるなら、最初に引っかかるのは「聞いて手で打つ」ところです。ここは音声認識(自動文字起こし)に任せてしまえばいい。実際、手作業だと1分ぶんに十分以上かかっていたのが、自動にすると起こす時間そのものがなくなり、残るのは誤変換や区切りを直す数分だけになります。

さらに欲を言えば、文字と一緒に「それをいつ喋ったか」のタイムスタンプまで出したい。言葉に時刻がくっついていれば、さっきの「合わせる」作業の土台が、最初から手に入ることになります。

原理はシンプル。でも「使える道具」にするのは別だった

調べてみると、文字起こしとタイムスタンプを取得する仕組み自体は、Google Cloudの Speech-to-Text などのAPIを使って実現できます。ポイントは、単語ごとの「開始・終了時刻」を返してもらうこと。Speech-to-Text(v2)なら、chirp_2 というモデルに音声を渡し、enable_word_time_offsets を有効にするだけです。ざっくり、こんな感じになります。

from google.cloud.speech_v2 import SpeechClient
from google.cloud.speech_v2.types import cloud_speech
from google.api_core.client_options import ClientOptions

REGION = "us-central1"
# chirp_2 はリージョナルのエンドポイントを使う
client = SpeechClient(client_options=ClientOptions(
    api_endpoint=f"{REGION}-speech.googleapis.com"))

config = cloud_speech.RecognitionConfig(
    explicit_decoding_config=cloud_speech.ExplicitDecodingConfig(
        encoding=cloud_speech.ExplicitDecodingConfig.AudioEncoding.LINEAR16,
        sample_rate_hertz=16000,
        audio_channel_count=1,
    ),
    language_codes=["ja-JP"],
    model="chirp_2",
    features=cloud_speech.RecognitionFeatures(
        enable_word_time_offsets=True,  # ← 単語ごとの開始・終了時刻を返す
    ),
)

req = cloud_speech.RecognizeRequest(
    recognizer=f"projects/{PROJECT}/locations/{REGION}/recognizers/_",
    config=config,
    content=audio_bytes,  # 16kHz・モノラル・LINEAR16 の WAV
)
res = client.recognize(request=req)

for result in res.results:
    for w in result.alternatives[0].words:
        # start_offset / end_offset が、音から実測した時刻
        print(w.word, w.start_offset.total_seconds(), w.end_offset.total_seconds())

キモは enable_word_time_offsets=True の一行と、返ってくる start_offset / end_offset です。これは音声そのものから測った時刻なので、字幕の表示タイミングの土台に、そのまま使えます。

ただ、自分だけが使えるプログラムを作ることと、毎日の動画制作で使える道具にすることは別でした。動画をアップロードしたら、時刻付きで文字起こしされ、読みやすい単位に区切られ、直して、mp4やSRTとして書き出すまでが1つの画面で完結する。そこまでつながって、やっと毎日使えるものになりました。

DogaRun では、実際にこの仕組みを使っている

DogaRunは、その「文字起こしと時刻付けという、一番時間のかかる初期工程を自動化して、あとは出てきた下地を直すだけにしたい」という気持ちからスタートして、誰でもブラウザから使える形にしたものです。

中身は、まさにさっきの仕組みそのものです。アップロードされた動画や音声を、まず ffmpeg で 16kHz・モノラルの音声に変換し、それを Speech-to-Text の chirp_2 に渡して、単語ごとの実測時刻つきで文字起こしします。長い音声は内部で分割して処理し、時刻は動画の実尺でクリップします。その結果が、編集画面にそのまま並びます。

DogaRunの文字起こし結果。実際に喋った内容が「[0:00.0] …」のように、秒数つきで一行ずつ並んでいる DogaRunで文字起こしした結果(実際の画面)。文・単語に、音声から実測した秒数がついています。この時刻をそのまま字幕のタイミングに使うので、「合わせ直す」作業が要りません(画面は筆者の実際のショート動画のものです)。

あとは、この下地を直すだけです。時刻つきの字幕として区切られて出てくるので、誤変換を直しても表示タイミングは崩れません。1枚に詰まりすぎた字幕は、意味の切れ目で区切り直すだけ。ゼロから文字を打って、秒数を合わせて……という往復が、「出てきたものを直す」に変わります。

料金と、無料でできること

料金まわりも隠さず書いておきます。

  • 音声認識による自動文字起こしは、無料のFreeプランでも毎月一定量まで試せます(月20クレジット=文字起こし約10分ぶんに相当)。それ以上や本格的な運用は有料プランです。音声認識にはAPI利用料などのコストがかかるため無制限ではありませんが、まずは無料で試せる、というのは伝えておきます。
  • 自動文字起こしを使わなくても、字幕の編集そのものは無料で試せます。時刻付きで区切られた字幕をブラウザ上で直していく、という基本の操作から触ってもらえます。
  • そして自動文字起こしは万能ではありません。固有名詞や数字は誤変換しますし、早口やBGMの被りでも精度は落ちます。出てくるのはあくまで「下書き」で、最後は人の目で直す前提だと思ってください。

まとめ

字幕づくりで一番重いのは、聞いて・手で起こして・時刻を合わせる、の繰り返しです。ここを音声認識の文字起こしと時刻付きデータ化に任せて、人は「出てきた下地を直す」だけにする——DogaRunは、そこを自動化したくて作ったツールです。同じところで消耗している人は、Freeプランから触ってみてください。

DogaRun

ショートの編集を楽に

AI搭載の縦型動画特化の編集サービス。 まずは無料の Free プランから。

クレジットカード不要で まずは無料で始める。