Cloudinary で字幕を重ねた動画を取得するまでのメモ
Cloudinary で動画に字幕を重ねて表示するのを試してみたのでそのメモ。
字幕の表示自体は特定のフォーマットの字幕ファイルをアップロードしてURLで指定するだけなので簡単ですが、字幕ファイルの生成で手間取りました。
Google AI Video Transcription Add-on
Google AI Video Transcription Add-on | Cloudinary
動画を上げるときに字幕ファイルも生成して一緒に上げるAdd-onがあるのでまずそれを試してみました。 ※ Freeプランだと120 Unit (処理15秒につき1 Unit) までという制限付き
Pythonの場合はcloudinaryをpipでインストール。
pip install cloudinary
Dashboardで見える諸々の値を環境変数として読み込むようにしておきます。
import os import cloudinary.uploader video_file = 'douga.mp4' cloudinary.config( cloud_name = os.environ['CLOUDINARY_CLOUD_NAME'], api_key = os.environ['CLOUDINARY_API_KEY'], api_secret = os.environ['CLOUDINARY_SECRET'] ) cloudinary.uploader.upload(video_file, resource_type = "video", raw_convert = "google_speech:srt:ja-JP")
と、上のコード一応エラーなく実行され、動画ファイルと字幕ファイルがCloudinaryにアップロードされることはされます。しかし、字幕ファイルが空でダウンロードしようとしてもGenerate Errorと表示されてしまい使い物にならず……。
内部的に使っているGoogle Speech to Textが何も検出できなかった場合に空のレスポンスを返すのでそのせいなのかも知れませんが、詳しくは調べられておらず。ffmpegで細かい調整をしていけば検出されそうな気もします。
Google Speech to Text
結局普通にGoogle Speech to Textで変換して字幕ファイルを作成しました。
ffmpegでmp4からflacに変換します。
※ffmpegが入っていない場合はpipとかで入れておく
# acodec: codec # ac: 1 -> monoral # ar: sampling rate # ffmpeg -i douga.mp4 -acodec flac -f flac -ac 1 -y -ar 16000 -filter:a "volume=35dB" output.flac
音量によって検出されないこともあったので、小さい場合は少し上げてやると良さそうです。
flacからGoogle Speech-to-text APIを使って srt を生成するコードは下記の通り。(Google Speech to Textのサンプルコードのまんま)
import io import os import math import output_srt # Imports the Google Cloud client library from google.cloud import speech from google.cloud.speech import enums from google.cloud.speech import types # Instantiates a client client = speech.SpeechClient() # The name of the audio file to transcribe file_name = os.path.join( os.path.dirname(__file__), 'output.flac') # Loads the audio into memory with io.open(file_name, 'rb') as audio_file: content = audio_file.read() audio = types.RecognitionAudio(content=content) config = types.RecognitionConfig( sample_rate_hertz=16000, language_code='ja-JP', enable_word_time_offsets=True) # Detects speech in the audio file response = client.recognize(config, audio) output_srt.format_transcript(response.results, file_name)
APIのレスポンスからsrtを生成するための処理(上記 ouput_srt.format_transcript
関数)については、この方のコードが参考になったので使わせてもらいました。
google-speech-to-text/format_response.py at master · Naki21/google-speech-to-text · GitHub
なんとか字幕は出たのですが短すぎてこんなのしか出ません……。
もっと文章っぽい言葉なら精度が上がるとは思うんですが、サンプルが一言だけの動画なのがよろしくなさそう。そもそもこの音声は数年前にWatson Text to Speechで生成したものなので無駄極まりないですが。
1 0:00:01,000 --> 0:00:02,700 マウスコンピューター
色々音量とかをいじると候補が変わったりはするのですが、文章らしい文章にはならなかったので手動で変更します。これまでの作業は一体...。
1 0:00:01,000 --> 0:00:02,700 マウス、コンピューターマウスが見えます
なんやかんやで作成したsrtファイルをCloudinaryにアップロードします。
そして動画のURLを https://res.cloudinary.com/<CloudName>/video/upload/l_subtitles:<字幕ファイル名>/douga.mp4
のようにすると字幕を重ねた動画を取得することが出来ました。めでたしめでたし。