🌟
iiif-prezi3を使って、動画に字幕を設定する
概要
iiif-prezi3を使って、動画に字幕を設定する方法に関する備忘録です。
字幕の作成
OpenAIのAPIを使用して字幕ファイルを作成しました。動画のファイルを音声ファイルに変換しています。
from openai import OpenAI
from pydub import AudioSegment
from dotenv import load_dotenv
class VideoClient:
def __init__(self):
load_dotenv(verbose=True)
api_key = os.getenv("OPENAI_API_KEY")
self.client = OpenAI(api_key=api_key)
def get_transcriptions(self, input_movie_path):
audio = AudioSegment.from_file(input_movie_path)
# 一時ファイルにオーディオを書き込む
with tempfile.NamedTemporaryFile(suffix=".mp3") as temp_audio_file:
audio.export(temp_audio_file.name, format="mp3") # MP3形式でエクスポート
temp_audio_file.seek(0) # ファイルポインタを先頭に戻す
# Whisper APIでトランスクリプトを取得
with open(temp_audio_file.name, "rb") as audio_file:
# Whisper APIでトランスクリプトを取得
transcript = self.client.audio.transcriptions.create(
model="whisper-1",
file=audio_file,
response_format="vtt"
)
return transcript
使用するデータ
『県政ニュース 第1巻』(県立長野図書館)を使用します。
マニフェストファイルへの反映
以下の記事などを参考に、マニフェストファイルが作成済みであるとします。
以下のようなスクリプトにより、マニフェストファイルにvttファイルを追加します。
from iiif_prezi3 import Manifest, AnnotationPage, Annotation, ResourceItem, config, HomepageItem, KeyValueString
#| export
class IiifClient:
def load_manifest(self, manifest_path):
with open(manifest_path, "r") as f:
manifest_json = json.load(f)
manifest = Manifest(**manifest_json)
return manifest
def add_vtt(self, manifest_simple_path):
manifest = self.load_manifest(manifest_simple_path)
vtt_url = f"{self.prefix}/video.vtt"
canvas = manifest.items[0]
vtt_anno_page = AnnotationPage(id=f"{canvas.id}/page2")
canvas.annotations = [
vtt_anno_page,
]
vtt_body = ResourceItem(id=vtt_url, type="Text", format="text/vtt")
vtt_anno = Annotation(
id=f"{vtt_anno_page.id}/a1",
motivation="supplementing",
body=vtt_body,
target=canvas.id,
label = "WebVTT Transcript (machine-generated)"
)
vtt_anno_page.add_item(vtt_anno)
with open(f"{self.input_dir}/manifest_vtt.json", "w") as f:
f.write(manifest.json(indent=2))
以下のようなマニフェストファイルが作成されます。
https://d1u7hq8ziluwl9.cloudfront.net/sdcommons_npl-02FT0102974177/manifest.json
{
"@context": "http://iiif.io/api/presentation/3/context.json",
"id": "https://d1u7hq8ziluwl9.cloudfront.net/sdcommons_npl-02FT0102974177/manifest.json",
"type": "Manifest",
"label": {
"ja": [
"県政ニュース 第1巻"
]
},
"requiredStatement": {
"label": {
"ja": [
"Attribution"
]
},
"value": {
"ja": [
"『県政ニュース 第1巻』(県立長野図書館)を改変"
]
}
},
"homepage": [
{
"id": "https://www.ro-da.jp/shinshu-dcommons/library/02FT0102974177",
"type": "Text",
"label": {
"ja": [
"信州デジタルコモンズ 県立長野図書館所蔵資料"
]
}
},
{
"id": "https://jpsearch.go.jp/item/sdcommons_npl-02FT0102974177",
"type": "Text",
"label": {
"ja": [
"ジャパンサーチ"
]
}
}
],
"items": [
{
"id": "https://d1u7hq8ziluwl9.cloudfront.net/sdcommons_npl-02FT0102974177/canvas",
"type": "Canvas",
"height": 480,
"width": 640,
"duration": 619.61962,
"items": [
{
"id": "https://d1u7hq8ziluwl9.cloudfront.net/sdcommons_npl-02FT0102974177/canvas/page",
"type": "AnnotationPage",
"items": [
{
"id": "https://d1u7hq8ziluwl9.cloudfront.net/sdcommons_npl-02FT0102974177/canvas/page/annotation",
"type": "Annotation",
"motivation": "painting",
"body": {
"id": "https://d1u7hq8ziluwl9.cloudfront.net/sdcommons_npl-02FT0102974177/video.mp4",
"type": "Video",
"height": 480,
"width": 640,
"duration": 619.61962,
"format": "video/mp4"
},
"target": "https://d1u7hq8ziluwl9.cloudfront.net/sdcommons_npl-02FT0102974177/canvas"
}
]
}
],
"annotations": [
{
"id": "https://d1u7hq8ziluwl9.cloudfront.net/sdcommons_npl-02FT0102974177/canvas/page2",
"type": "AnnotationPage",
"items": [
{
"id": "https://d1u7hq8ziluwl9.cloudfront.net/sdcommons_npl-02FT0102974177/canvas/page2/a1",
"type": "Annotation",
"label": {
"ja": [
"WebVTT Transcript (machine-generated)"
]
},
"motivation": "supplementing",
"body": {
"id": "https://d1u7hq8ziluwl9.cloudfront.net/sdcommons_npl-02FT0102974177/video.vtt",
"type": "Text",
"format": "text/vtt"
},
"target": "https://d1u7hq8ziluwl9.cloudfront.net/sdcommons_npl-02FT0102974177/canvas"
}
]
}
]
}
]
}
ビューアでの表示例
ビューアでの表示例は以下です。Theseus Viewerを使用しています。
まとめ
IIIFを用いた動画ファイルへの字幕の設定にあたり、参考になりましたら幸いです。
Discussion