daily-log
2026年3月17日の開発日記
朝はPRを2つマージするだけの予定だった。デプロイしたら本番の音声が全て消え、CORSの調査に半日費やした。午後は会計入門10ページをMiller Columnに載せ替え、合間にFish Audio S2で自分の声のクローンを試した。
今日やったこと
1. PRレビュー → R2 CORS問題の発見と解決
タブレット音声修正PRとコンテンツPRの2つをレビュー・マージし、Cloudflare Pagesにデプロイした。本番で音声が404になり、環境変数の設定漏れを直したあと、今度はWeb Audio APIのステレオパニングでCORSエラーが発覚。crossorigin="anonymous" を追加したら音声が完全にロードできなくなり、即ロールバック。Codexレビューを経て「3段階CORS検証 + キャッシュバスター」で最終的に解決した。
主な成果:
- R2カスタムドメインのCORS設定を wrangler CLI で適用
- 3段階CORS検証(1行目はcrossoriginなし → 2行目でcorsチェック + キャッシュバスター → 3行目以降ステレオパニング有効)を実装
- ブラウザのメディアキャッシュがcors/no-corsリクエストを分離しない仕様を発見・文書化
2. Fish Audio S2ボイスクローン実験
自分の声のクローンモデル(test_akira)を使ってTTS生成を試した。API経由で402エラーに当たりWebプレイグラウンドに切り替え、感情タグを3パターン比較し、固有名詞「ユイ」の発音ズレをひらがな変換で対処した。
主な成果:
- Fish Audio S2の料金調査($10で約22万文字 — ElevenLabsの10倍以上のコスパ)
to_tts_text()関数でカタカナ→ひらがな変換を共通化(エンジン非依存の前処理)- Fish Audio S2用のページ・データファイルをeurekapu-nuxt4に追加
3. 会計入門コンテンツのMiller Column移行
旧プロジェクトの会計入門編(全7パート + 補足 + 目次 + 概要 = 計10ページ)をMiller Column Layoutに載せ替えた。Codexレビューで計画を2回修正し、サブエージェント7本で並行データ変換、Chrome DevToolsで全ページ表示確認してUI問題を4件修正した。
主な成果:
- 10ページ分のMillerChapterデータ変換完了(サブエージェント7本並行)
- noChapterCol改善、補足の入れ子分離、ドットナビサイズ統一、TOCインデックス除外
- 双方向TOC-MillerChapter整合性テスト追加
- buildRangesのlet/push → reduceリファクタリング
4. その他
- e-taxプロジェクトのCLAUDE.md作成 — 確定申告ツール用のプロジェクト説明を10分で作成
- Remotion調査 — React専用でVue.js版は存在しないことを確認
- リップシンク調査 — アニメ画像 + 音声の口パク手法を調査。LatentSync(ByteDance製OSS)とLive2Dが有力候補
今日の試行錯誤
| # | テーマ | 試したこと | 結果 | 気づき |
|---|---|---|---|---|
| 1 | PR並列レビュー | サブエージェント2つ同時起動 | 権限不足で両方失敗 | 権限設定を詰めてから並列化すべき |
| 2 | 本番音声404 | デプロイ後に環境変数確認 | NUXT_PUBLIC_AUDIO_BASE_URL 未設定 | デプロイ前チェックリストに環境変数を入れる |
| 3 | CORSエラー | crossorigin="anonymous" 追加 | 音声が完全にロードできなくなる | メディアキャッシュがcors/no-corsを分離しない |
| 4 | CORS回避 | 即ロールバック → Codexレビュー | 3段階CORS検証 + キャッシュバスター | ?_cors=1でR2はクエリ無視、ブラウザはキャッシュ分離 |
| 5 | TTS API | Fish Audio S2 API | 402残高不足 | Free枠のクレジット確認してから叩く |
| 6 | 発音ズレ | 感情タグ3パターン | パターン差は控えめ | カタカナ→ひらがな変換の方が効果大 |
| 7 | 移行計画 | Codex初回レビュー | 致命的指摘3点 | 1回で満足せず修正後に再レビュー |
| 8 | Miller Column UI | Chrome DevToolsで全ページ確認 | UI問題4件発見 | データ上正しくても画面で初めて気づく問題がある |
| 9 | 整合性テスト | TOC→MillerChapter片方向 | Codexに「片方向」と指摘される | 整合性テストは最初から双方向で書く |
今日の学び
<audio>のメディアローダーはFetch APIと違い、cors/no-corsでキャッシュを分離しない。この仕様を知っているかでデバッグ時間が数時間変わるcreateMediaElementSource()は一度呼ぶと不可逆。CORSが通るか先に確認してから呼ぶ- Codexレビューは2回回す。初回で致命的な漏れを潰し、修正後に
resume --lastでもう1回 - サブエージェント並行起動はデータ変換タスクと相性が良い。7並列で走らせても品質が安定する
- TTS固有名詞の発音問題は、エンジン非依存の前処理レイヤー(
to_tts_text())で吸収するのが最も汎用的