ホーム 記事一覧 ブック DH週間トピックス 検索 このサイトについて
English
Claude Codeを使って動画に多言語字幕を自動生成し、IIIF v3マニフェストで公開する

Claude Codeを使って動画に多言語字幕を自動生成し、IIIF v3マニフェストで公開する

動画コンテンツに字幕をつける作業は手間がかかります。本記事では、Claude Code(CLI版Claude)を使い、動画のフレーム分析から多言語字幕(VTT)の生成、IIIF v3マニフェストの作成までを効率的に行う方法を紹介します。 実際のプロジェクトについてはこちらの記事をご覧ください。 全体の流れ 1. 動画ファイル(mp4)を用意する 2. ffmpegでシーンチェンジを検出 3. シーンチェンジポイントのフレームを抽出 4. Claude Codeでフレーム画像を読み取り、内容を把握 5. シーンチェンジのタイムスタンプに基づいてVTTファイルを作成 6. 英語字幕も同様に作成 7. IIIF v3マニフェストを作成 8. HTMLプレーヤーで動画・字幕・読み上げを同期 前提条件 Claude Code(CLI版) ffmpeg / ffprobe 字幕をつけたい動画ファイル(mp4) # macOSの場合 brew install ffmpeg Step 1: シーンチェンジの検出 動画の画面が切り替わるタイミングを自動検出します。これが字幕のタイムスタンプの基準になります。 ffmpeg -i "video.mp4" \ -vf "select='gt(scene,0.15)',showinfo" \ -vsync vfr -f null - 2>&1 \ | grep "pts_time" \ | sed 's/.*pts_time:\([0-9.]*\).*/\1/' 出力例: 3.033333 8.066667 20.066667 25.066667 32.100000 ... なぜシーンチェンジ検出が重要か 最初は3秒間隔でフレームを抽出していましたが、実際の画面切り替えとずれが生じました。シーンチェンジ検出を使うことで、実際に画面が変わるタイミングに基づいた正確な字幕タイミングが得られます。 Step 2: シーンチェンジポイントのフレーム抽出 mkdir -p scenes ffmpeg -i "video.mp4" \ -vf "select='gt(scene,0.15)'" \ -vsync vfr -q:v 2 \ scenes/scene_%03d.jpg Step 3: Claude Codeでフレーム画像の内容を読み取る Claude Codeのマルチモーダル機能で、抽出したフレーム画像の内容を読み取ります。 ...

Chrome Headless の --screenshot で画面下部に白い余白が出る問題と対処法

Chrome Headless の --screenshot で画面下部に白い余白が出る問題と対処法

問題 Chrome の Headless モードで HTML を PNG 画像にキャプチャする際、画面下部に**白い余白(白帯)**が発生することがあります。 google-chrome --headless --screenshot=output.png \ --window-size=1920,1080 \ --hide-scrollbars \ --force-device-scale-factor=1 \ file:///path/to/slide.html HTML 側で width: 1920px; height: 1080px を指定しているにもかかわらず、生成された画像の下部に白い帯が残り、bottom で配置した要素(テロップ、フッターなど)が切れてしまいます。 原因 --window-size=1920,1080 はブラウザの外部ウィンドウサイズを指定するオプションであり、実際の**ビューポート(描画領域)**は若干小さくなります。Headless モードでもこのズレは発生します。 つまり: --window-size=1920,1080 → 実際のビューポートは約 1920×1058 程度 HTML は 1080px の高さで描画しようとする ビューポートに収まらない下部のコンテンツが見切れる スクリーンショットは 1920×1080 で出力されるが、下部はデフォルト背景色(白)で埋まる html や body に height: 1080px を指定しても、Chrome が実際に確保するビューポート高さとは一致しないため、CSS だけでは解決できません。 解決方法 ウィンドウサイズを大きめに設定し、スクリーンショット後に Pillow でクロップするのが最も確実です。 1. Chrome のウィンドウサイズを大きくする google-chrome --headless --screenshot=output.png \ --window-size=1920,1280 \ --hide-scrollbars \ --force-device-scale-factor=1 \ file:///path/to/slide.html 高さを 1280 に変更することで、1080px のコンテンツが確実にビューポート内に収まります。 ...

Three.js + Puppeteer で VRM キャラクターを動かして動画を自動生成する

Three.js + Puppeteer で VRM キャラクターを動かして動画を自動生成する

はじめに 技術ブログの記事を VTuber 風の解説動画に自動変換できたら面白いのでは――そんな思いつきから、Three.js + Puppeteer で VRM キャラクターをフレーム単位でレンダリングし、VOICEVOX の音声とリップシンクさせて動画を生成するパイプラインを作りました。 この記事では、実装で得られた知見とハマりどころを共有します。 全体のパイプライン 処理の流れは以下の通りです。 Markdown 記事を読み込み → LLM(OpenRouter API)でセクション分割された台本を生成 VOICEVOX でセクションごとに音声(WAV)と音素タイミングを生成 Three.js + @pixiv/three-vrm でヘッドレス Chrome 上に VRM モデルを描画し、音素データに基づくリップシンクアニメーションをフレーム連番 PNG として出力 スライド画像を自動生成(HTML → Chrome ヘッドレス → PNG) FFmpeg でスライド背景 + VRM アニメーション + 音声を合成し、MP4 動画を出力 Python スクリプトがオーケストレーション役を担い、VRM レンダリングは Node.js スクリプトを子プロセスとして呼び出す構成です。 使用技術 役割 技術 3D レンダリング Three.js v0.172 VRM 読み込み @pixiv/three-vrm v3.3.3 ヘッドレスブラウザ puppeteer-core (SwiftShader) 音声合成 VOICEVOX Engine (Docker) 動画合成 FFmpeg パイプライン制御 Python VRM モデル AvatarSample_C (VRoid Hub / 無料ライセンス) ヘッドレス Chrome で VRM を読み込む 課題: file:// の CORS 制限 最初の壁は、ヘッドレス Chrome 上で VRM ファイルを読み込む方法でした。ローカルの .vrm ファイルを file:// プロトコルで読もうとすると CORS エラーで弾かれます。 ...

360度動画・写真から歪みのないサムネイル画像を作成する方法

360度動画・写真から歪みのないサムネイル画像を作成する方法

Insta360などで撮影した360度コンテンツ(equirectangular形式)から、自然な見た目のサムネイル画像を作成する方法を紹介します。 課題:そのままリサイズすると歪む 360度動画や写真はequirectangular(正距円筒図法)形式で保存されています。この形式は球体を平面に展開したもので、特に上下の端に近いほど横方向に引き伸ばされています。 そのまま単純にリサイズしてサムネイルを作成すると、歪んだ不自然な画像になってしまいます。 # 単純なリサイズ(歪んだサムネイルになる) ffmpeg -i 360video.mp4 -ss 00:00:05 -vframes 1 -vf "scale=640:-1" thumb.jpg 解決策:v360フィルターでflat projectionに変換 ffmpegのv360フィルターを使用して、equirectangular形式からflat(rectilinear/透視投影)形式に変換することで、人間の目で見たような自然な画像を切り出せます。 使用ツール ffmpeg を使用します。macOSの場合、Homebrewでインストールできます。 brew install ffmpeg v360フィルターが含まれているか確認: ffmpeg -filters 2>/dev/null | grep v360 # 出力: .SC v360 V->V Convert 360 projection of video. 基本コマンド 動画からサムネイル作成 ffmpeg -i 360video.mp4 -ss 00:00:05 -vframes 1 \ -vf "v360=e:flat:h_fov=120:v_fov=90:yaw=0:pitch=0,scale=640:-1" \ thumbnail.jpg -y 写真からサムネイル作成 ffmpeg -i 360photo.jpg \ -vf "v360=e:flat:h_fov=120:v_fov=90:yaw=0:pitch=0,scale=640:-1" \ thumbnail.jpg -y v360フィルターのパラメータ解説 パラメータ 説明 e 入力形式:equirectangular flat 出力形式:flat(透視投影) h_fov=120 水平視野角(度) v_fov=90 垂直視野角(度) yaw=0 水平方向の回転(-180〜180) pitch=0 垂直方向の回転(-90〜90) 視野角の調整 用途に応じて視野角を調整できます。 ...

国立国会図書館 歴史的音源で公開されている音声をmp4に変換する

国立国会図書館 歴史的音源で公開されている音声をmp4に変換する

概要 国立国会図書館 歴史的音源(以下、れきおん)で公開されている音声をmp4に変換する機会がありましたので、備忘録です。 れきおんの提供形式 れきおんでは、m3u8形式のファイルが公開されていました。 例えば、以下の「講演:道徳、経済合一論(一)Union of Morality of Economy」を確認してみます。 https://rekion.dl.ndl.go.jp/pid/3574643 開発者ツールなどで確認すると、以下のURLからアクセスできることが確認できます。 https://rekion.dl.ndl.go.jp/contents/3574643/83389ec6-2b45-4fdd-88d6-89628841039f/317d6ab4-32ec-4085-88e6-cfe36ffd34c3/317d6ab4-32ec-4085-88e6-cfe36ffd34c3_hls.m3u8 このURLを構成するIDなどは、以下のAPIの返却結果の中で確認できました。 https://rekion.dl.ndl.go.jp/api/item/search/info:ndljp/pid/3574643 pidから上記のURLを取得するAPIの開発 上記のJSONを処理することで、m3u8ファイルのURLを取得します。 この部分をAPI化したので、試していただけますと幸いです。 https://iiif-demo-next.vercel.app/api/rekion/3574643 以下のような結果が得られます。 { "data": { "type": "rekion", "id": "3574643", "attributes": { "title": "講演:道徳、経済合一論(一)Union of Morality of Economy", "url": "https://rekion.dl.ndl.go.jp/pid/3574643", "hls": "https://rekion.dl.ndl.go.jp/contents/3574643/83389ec6-2b45-4fdd-88d6-89628841039f/317d6ab4-32ec-4085-88e6-cfe36ffd34c3/317d6ab4-32ec-4085-88e6-cfe36ffd34c3_hls.m3u8" } } } ソースコードは以下です。 https://github.com/nakamura196/iiif-demo-next/blob/main/src/app/api/rekion/[id]/route.ts ffmpegを使ってmp4に変換する 以下のようなコマンドにより、m3u8ファイルをmp4形式に変換できました。 ffmpeg -i "https://rekion.dl.ndl.go.jp/contents/3574643/83389ec6-2b45-4fdd-88d6-89628841039f/317d6ab4-32ec-4085-88e6-cfe36ffd34c3/317d6ab4-32ec-4085-88e6-cfe36ffd34c3_hls.m3u8" -c copy 3574643.mp4 まとめ 音声ファイルの利用にあたり、参考になりましたら幸いです。