Google Colaboratoryでセッション動画から、YouTubeやサイトに掲載する文章を生成する
DevRelとして企画運営に携わるJP_Stripesコミュニティでは、登壇者のセッションを動画アーカイブ化しており、Google ColaboratoryとWhisperを使用して動画の説明文やコミュニティウェブサイトの文章作成を行っています。動画のアーカイブ化により、過去のセッション内容の理解を深める取り組みをしており、Shifterを用いてウェブサイトの保守時間を短縮しています。文字起こしや動画紹介文章の生成を自動化するためにWhisperやClaude 3.5 Sonnetを活用しています。
目次
DevRelとして企画運営に携わっているコミュニティ、JP_Stripesでは登壇者からOKいただいたセッションについて動画のアーカイブを作成しています。その中で動画の説明文やコミュニティウェブサイトに掲載する文章の作成にGoogle ColaboratoryとWhisperを使い始めたので、その方法を紹介します。
やりたかったこと
各地でStripeの事例について登壇いただいています。そしてユーザーさんと会話していると、「あ、それ前回の大阪で話している人いましたよ」「え、そうなんですか!?どんな話されていましたか??」のような流れになることが定期的に出てきています。こうなったときに、登壇資料だけでも内容を把握できるとは思うのですが、やはりセッションの映像があった方がよりわかりやすいのではということで、セッションのアーカイブを少しずつ始めているところです。
ただ、動画撮影と編集・公開で結構手がいっぱいいっぱいになっており、動画の紹介文などが暫定的なものばかりな状態でした。その影響かYouTubeや検索で動画を見つけることがなかなか難しかったため、「やはりテキスト情報を追加していこう」となりました。
作ったもの
ウェブサイトに過去のセッションを一覧で確認できるページを作成しました。まだ全動画のサポートはできていませんが、テキスト生成ができたものから反映させています。
ウェブサイトの保守時間を減らすためにShifterを利用しています。Shifterの機能でAlgolia検索へのインデックスが作成できるので、これを使った検索も進めようと思っています。
参考にした記事など
今回参考にしたのは次の2記事です。動画から音声に変換する方法や「そういうやり方があるんだ!」と気づくことができたのが1記事目。そしてそれをできるだけ簡単にローコストで実現する方法を知れたのが2記事目です。
- 生成AIによる「ブログの原稿作り」手順やプロンプトを公開 – SORACOM公式ブログ
- 生成AIをGoogle Colaboratoryで簡単に 【Part5 音声認識AI faster-whisper編】
進め方
ざっくり進め方をまとめると、このような流れです。
- 動画を
ffmpeg
でmp4 -> m4a変換する - CodelaboratoryでWhisperを使った文字起こしの処理を用意する
- m4aファイルをアップロードし、スクリプトを実行する
- Claude 3.5 Sonnetで生成されたtranscriptを整形する
動画をffmpeg
でmp4 -> m4a変換する
Whisperが処理できるファイルサイズや、Corelaboratoryにアップロードできるファイルの上限があるため、音声データだけを取得します。今回セッションごとに動画ファイルを分けていたため、ここの変換処理はかなりシンプルなコマンドで行っています。
ffmpeg -i session1.mp4 session1.m4a
CodelaboratoryでWhisperを使った文字起こしの処理を用意する
続いて参考記事を元に、Whisperを実行する環境を整えます。
!pip install git+https://github.com/openai/whisper.git
オプショナルですが、アップロードフォルダと生成結果を保存するフォルダをそれぞれ用意する方法、地味に便利でした。
import os
# Add folders
checkContentFolder = os.path.exists("content")
checkDownLoadFolder = os.path.exists("download")
if not checkContentFolder:
os.mkdir("content")
if not checkDownLoadFolder:
os.mkdir("download")
m4aファイルをアップロードし、スクリプトを実行する
ffmpeg
で変換したm4aファイルをCodelaboratoryにアップロードします。その後スクリプトのFILE_NAME
をアップロードしたファイル名に変更し、スクリプトを実行します。スクリプトは元記事のコードからClaude3.5 Sonnetを利用して幾つかの調整をいれています。
import whisper
# Configuration
FILE_NAME = "session1.m4a"
LANGUAGE = "ja"
MODEL_TYPE = "medium" # モデルサイズを大きくする
INPUT_DIR = "content"
OUTPUT_DIR = "download"
try:
# Load model
model = whisper.load_model(MODEL_TYPE)
# Transcribe audio
result = model.transcribe(f"{INPUT_DIR}/{FILE_NAME}", language=LANGUAGE, fp16=False)
# Print result
print(result["text"])
# Write result to file
output_path = f"{OUTPUT_DIR}/{FILE_NAME}.txt"
with open(output_path, "w", encoding="utf-8") as f:
f.write(f"▼ Transcription of {FILE_NAME}\n")
f.write(result["text"])
print(f"Transcription saved to {output_path}")
except Exception as e:
print(f"An error occurred: {e}")
実行に成功すると、標準出力と出力先フォルダに文字起こし結果が表示されます。
この時点では、表記揺れやタイポなどが目立つ状態です。そのため、生成結果を利用して動画に字幕を設定するような、この結果をそのまま利用する想定のワークフローは人の手を入れる必要がありそうです。
Claude 3.5 Sonnetで生成されたtranscriptを整形する
今回は動画の紹介文を作るのが目的です。そのため、生成された文字列を別のLLM、今回はClaude 3.5 Sonnetに渡します。今回は次のようなプロンプトを利用して生成を行いました。
次の文字起こしは、Stripeに関するセッションの文字起こしです。 生成AIを利用したため、表記揺れなどがあることに注意して熟読してください。 その上で、以下の内容を生成してください。
- 1: セッションの内容を詳細にまとめてください。
- 2: この動画を紹介するための、YouTube動画紹介文章を作成してください。
- 3 "2"で作成した文章を、Markdown形式で再度生成してください
- 4: 最後に、この動画を紹介するブログ記事のスラッグを提案してください
== transcript start ===
生成結果はだいたいこんな感じです。
そのまま使える部分と、多少大げさな表現や本題ではない部分も混ざっている状態です。そのため動画内容を再度確認しながら、記事や動画の説明文として編集していきます。
やってみての感想
10本ほど動画をこのワークフローで処理してみたのですが、体感70-80%くらいの精度で動画紹介文章を作ってくれています。会社名・氏名・製品名などは表記揺れや認識間違いが起きやすい印象があるのと、セッション内の雑談・余談・質疑応答部分もセッション内容として処理されることがある点に注意すれば、そのまま使える部分もなかなか多いなと思いました。
今後について
表記揺れや大げさな表現等については、プロンプトのチューニングである程度対応できると思っています。また、LlamaIndexのStripeDocsReaderを使ったRAGなどを挟むことで、「こんな製品について触れているよ」などの補足情報も追加できるかなと思っています。
最終的には自動化まで行きたいとは思いますが、それはまだまだYAGNIなので、手作業で試行錯誤を続けます。