雑学ショート動画を11本まで一気に作った日|脂肪の出口ネタの記事化から、BGMの途切れ対策と1文ずつ直せるレビュー画面まで

開発misc-dev

雑学ショート動画を11本まで一気に作った日

朝、「脂肪の出口知ってる?たぶん9割が便と答えるはず」という投稿を見かけた。 本当なのかを確かめて記事にしたところから始まり、その日のうちに同じ型の縦型ショート動画が11本並んだ。

最後に残ったのは、合成音声のままで出すのか、自分の声に差し替えるのかという判断である。 差し替える仕組みまでは作った。 ただ、まだ自分のマイクで1文も吹き込んでいない。

脂肪の出口を記事にする(07:17〜)

/new-article で記事を作らせた。 一次資料は2014年のBMJの論文で、本体のページは Bot 検知で読めなかったため、PubMed Central 版から数値を取らせた。 燃えた脂肪の84%がCO2として吐く息から出ていく。 ここまでは投稿のとおりで、「だから腹圧を意識した深呼吸が大事」という後半は誤りだった。 呼吸の量は代謝で決まるので、深呼吸を増やしても脂肪は減らない。

記事は 脂肪の出口は本当に「吐く息」なのか としてコミットした(デプロイはまだ)。

縦型動画のビューアーを移植する

そのまま、このネタを縦型のショート動画にする計画を立てた。 手本にしたのは、別リポジトリ(eurekapu-nuxt4)にある縦動画のビューアーである。 調べさせると、時刻を渡すと画面が決まる純粋関数で動いていて、音声は拍ごとの wav、書き出しは Playwright でコマを撮って ffmpeg でつなぐ方式だった。

計画書には「動画は新しいリポジトリで作り、記事側は埋め込みで参照するだけ」という流れを SVG の図にして載せた。 判断が要る項目は7件あり、3択ボタンのフォームで答えた。 音声の置き場所はフォームで Git LFS を選んだが、書き添えたコメントに沿って、両リポジトリとも git に入れず Google ドライブへバックアップする形に変えた。

Codex のレビューは一度止まった。 標準入力の待ちで固まっていたので、標準入力を閉じて実行し直し、再レビューで「承認」が出た。

新しいリポジトリ(sns-shorts)は GitHub に非公開で作り、時間軸とテロップの純粋関数から移植させた。 ビューアーは最初 500 エラーで落ちた(find を undefined に対して呼んでいた)。 直したあと、1本目「脂肪の出口」を頭から終わりまで再生できるようになった。 ただし声はまだなく、文字数から見積もった約48秒の仮の時間で動いていた。

ここで「声は合成していいっすよ、先に。次行きましょう。」と伝えた。

声とBGMと書き出し

声は Irodori-TTS(本人の声)で合成し、読みは音声認識(Whisper)で聞き直させた。 この確認の準備で、Python のパッケージ av<15 が手元でのビルドに失敗したので、範囲を1段広げた av<16 を試させた。

BGM の生成スクリプトも移した。 語りを再生し直すたびに BGM が一瞬止まらないよう、移植元と同じ作りにそろえた。 MP4 の書き出しでは1,320コマを調べ、画が変わったコマだけを撮る。

イントロとエンディングは3つの型を作って並べ、そのあと「刀の一閃」型にも作り直した。 このあたりの作業では、一括置換でファイルが何度か壊れた。 Perl の置換が @click を配列として展開して消したり、区切り記号の | と式中の || が衝突してファイルの先頭に文を差し込んだりした。 結局、壊れた行は Edit ツールで直させた。

題材は、手元の書籍データベースに入っている雑学本1冊から選んだ。 見出し1,918本を全部読ませ、5つの基準(冒頭2秒で止まるか、常識がひっくり返るか、自分ごとか、図解にしやすいか、裏が取れるか)で採点させて、トップ10を計画書に書き込んだ。 上位は人体と食べ物の話に集まった。

10話の並びも SNS ショートの形もこれでいいと判断した。 ただ、セッションが重くなっていたので、引き継ぎをダウンロードフォルダのテキストファイルに書き出させて区切った。

残り9本に一度に手をつける(10:43〜)

引き継ぎから再開し、まず2本目「サウナで毒出し、ほぼウソ」を仕上げさせた。 汗から出る有害物質の量は、2リットルの汗で0.1ng未満、1日の摂取量の約0.02%にとどまる。 この数値は論文で確かめた。 一方、「サウナで減る体重はほとんど汗の水分」という一節は、根拠にした総説が支えていなかったので台本から外した。

0.02%は、100×100のマスのうち2マスだけを塗る図にした。 1万マスあることが伝わりにくかったので題に「=1万マス」を足し、「ng」も伝わりにくいので「1ng=10億分の1グラム」の行を添えた。 肝臓のアイコンはじゃがいもに見えたので形を描き直させた。 次回予告の「うん/ち」という改行は、Chrome の word-break: auto-phrase(lang="ja" が要る)で文節の境目に寄せた。 2本目は33秒の MP4 になった。

ここで「残り9個あるじゃないですか。一旦全部手をつけてほしいんですよ」と頼んだ。 9本はサブエージェントに1本1体で任せ、一度に5本まで、残り4本はその後に回させた。 1体ごとに、一次資料での裏取りから台本、図解までを書かせる。

取り込みで一度つまずいた。 アイコンのファイルの先頭にあった説明文までマージされ、Vue の v-if の連鎖が壊れた。 マージのスクリプトを、字下げしたマークアップの行だけを拾う形に直させた。 確認は、2.5秒おきのコマを1枚に並べたコンタクトシートで場面ごとに見た。

1本目とサウナを合わせて11本がそろい、テスト172件が通った。

BGMが途中で途切れる

全部そろって再生してみると、BGM の切れ目が耳についた。 曲そのものが短く、つないでいるから切れるのだろうと思ったので、「1分ベースで最初に作っておきませんか。そしたら45秒って切るとかはできるじゃないですか」と伝えた。

BGM は32小節から40小節に延ばして83秒にし(元は67秒)、繰り返しをやめて、動画ごとにその長さで切る形に変えさせた。 途切れの原因は2つあったと報告を受けた。 再生中に BGM の位置が飛んでいないかは、1本を通しで流しながら BGM のシークをすべて記録させて調べた。 レビューでは「再生中の小さなシークで BGM が動かない」という指摘も出た。 これも直し、0.5秒戻すと BGM も同じだけ戻る(10.96 → 10.45)ことを確かめた。 全11本をこの BGM で書き出し直した。

次の20本と、冒頭カードへの作り替え

中身を見た感想は「まあこんなもんかな」だった。 10本見て、微修正は一旦全部作ってからまとめてやるほうが早いと判断した。 次の20本(#11〜#30)の候補を決めさせ、計画書に加えた。 前回の採点結果はファイルに残っていなかったので、見出しは取り直しになった。

その前に、イントロとエンディングも作り替えさせた。 冒頭は1枚のカード(サムネイルを兼ねる)にし、エンディングは0秒にした。 使わなくなったエンディングの部品と刀の型の効果音は消し、テストは200件になった。

1文ずつ直せるレビュー画面

ここで気になったのが読み上げの癖である。 たとえば「ポイント還元」の読み方がおかしい。 なぜそうなるのかを知りたかったし、その場でフィードバックを書き込みたかった。 内容がよければ、合成をやめて自分の声で読んでしまえば品質も上がるのではないか、とも考えた。

そこで、左にスマホ実寸の動画、右に TTS へ送っている原稿を1文ずつ出す画面を頼んだ。 フィードバックと確認済みのチェックは、Excel のビューアーと同じ仕組みに合わせる。 調べさせると、Excel 側はフィードバックを Cloudflare の D1 に保存していた。 計画書の4件の判断にはボタンで答え、Codex のレビューを通してから実装用の引き継ぎを書き出させた。

音声レビューの実装(13:39〜)

午後のセッションで、Phase 1 から Phase 4 まで進めた。

  • Phase 1: 画面を左右に分け、右に1文ずつのカードを出す。再生中の文へ自動でスクロールする
  • Phase 2: 確認済みのチェックとフィードバックを D1 に保存する(本番の D1 に表を2つ足した)
  • Phase 3: 読みの辞書に「ポイント還元」→「ポイントかんげん」を足す。字幕は原稿の「ポイント還元」のまま
  • Phase 4: 録音した文を合成音声と差し替える(無音の切り詰め、速さと音量の合わせ込み)
  • Phase 5: 別セッションが同じファイルを編集中のため保留

Phase 3 では、書き出しと再生成が同じ音声を同時に触らないようロックを入れた。 書き出し中に再生成を走らせると「使用中…空くまで待つ」で待ち、書き出しが終わってから進むことを確かめた。

Phase 4 では、dev サーバーから起動した ffmpeg だけが失敗した。 シェルからは動く。 windowsHide: true を付けると通ったので、issue に記録させた。 試験では合成した1文を代わりの録音として使った。 1.38倍の速さが要る録音は「録り直しが必要」と表示され、範囲内の録音は差し替わった。 音量を30%に落とした入力でも、差し替えた文は-20.4dBで、前後の文(-18.7〜-19.9dB)に近い。 差し替えを取り消すと、音声は元のファイルとバイト単位で一致した(11ファイルすべて)。

振り返り

  • 短い曲を繰り返してつなぐと、つなぎ目で音が切れて耳につく。先に1分を超える1本を作り、動画ごとに尺で切れば、つなぎ目そのものがなくなる
  • 並行で作らせた成果は、取り込みの段階で壊れることがある。今回はマージのスクリプトがファイル先頭の説明文まで拾っていた
  • Perl の一括置換ではファイルが壊れ、sed -i はフックに止められた。壊れた箇所の修正は Edit ツールに任せた

差し替えの仕組みは、代わりの録音でしか試していない。 自分のマイクで1文を録って、MP4 を耳で確かめるところはまだである。 合成のまま出すか、自分の声にするかは、そこで決まる。

#ショート動画#Claude Code#TTS#BGM#Cloudflare D1#サブエージェント#ファクトチェック