[{"data":1,"prerenderedAt":655},["ShallowReactive",2],{"content-/audio-wav-to-opus-pipeline":3,"all-pages-for-dir":633,"related-/audio-wav-to-opus-pipeline":634,"og-image-/audio-wav-to-opus-pipeline":654},{"id":4,"title":5,"body":6,"category":616,"concepts":616,"description":617,"extension":618,"meta":619,"navigation":534,"ogImage":616,"path":620,"project_name":616,"published":621,"publishedAt":622,"seo":623,"source":616,"stem":624,"tags":625,"todo":616,"unpublished":621,"updatedAt":622,"__hash__":632},"pages/2025-12/2025-12-12/audio-wav-to-opus-pipeline.md","音声ファイル変換パイプライン（WAV→Opus）",{"type":7,"value":8,"toc":595},"minimark",[9,13,17,30,41,44,49,52,58,66,75,97,118,122,177,180,184,231,235,292,298,301,340,346,349,353,411,415,452,455,458,472,475,492,504,513,553,560,563,591],[10,11,12],"h1",{"id":12},"音声ファイル変換パイプライン",[14,15,16],"h2",{"id":16},"概要",[18,19,20,21,25,26,29],"p",{},"このプロジェクトでは",[22,23,24],"strong",{},"WAVファイルをGitHubにプッシュ","し、",[22,27,28],{},"ビルド時に自動でOpusに変換","してCloudflareにデプロイする。",[31,32,37],"pre",{"className":33,"code":35,"language":36},[34],"language-text","[開発PC]          [GitHub Actions]           [Cloudflare]\n   │                    │                        │\n   │  .wav をpush       │                        │\n   ├──────────────────►│                        │\n   │                    │  FFmpegで変換          │\n   │                    │  .wav → .opus          │\n   │                    │                        │\n   │                    │  .opus をデプロイ       │\n   │                    ├───────────────────────►│\n   │                    │                        │\n","text",[38,39,35],"code",{"__ignoreMap":40},"",[14,42,43],{"id":43},"あなたがやること",[45,46,48],"h3",{"id":47},"_1-wavファイルを保存","1. WAVファイルを保存",[18,50,51],{},"WAVファイルを以下のディレクトリに保存する。",[31,53,56],{"className":54,"code":55,"language":36},[34],"apps/web/public/audio/\n└── boki3/\n    └── chapter4_0/\n        ├── boki3_ch4_0_00.wav  ← ここにWAVを置く\n        ├── boki3_ch4_0_01.wav\n        └── ...\n",[38,57,55],{"__ignoreMap":40},[45,59,61,62,65],{"id":60},"_2-vueコンポーネントでは-webm-を指定","2. Vueコンポーネントでは ",[38,63,64],{},".webm"," を指定",[18,67,68,71,72,74],{},[22,69,70],{},"重要",": コード内では ",[38,73,64],{}," 拡張子を使う（変換後のファイル名）",[31,76,80],{"className":77,"code":78,"language":79,"meta":40,"style":40},"language-vue shiki shiki-themes vitesse-light vitesse-light","// animation-demo-2.vue\naudioUrl: '/audio/boki3/chapter4_0/boki3_ch4_0_00.webm'  // ← .webm\n","vue",[38,81,82,91],{"__ignoreMap":40},[83,84,87],"span",{"class":85,"line":86},"line",1,[83,88,90],{"class":89},"sG7-3","// animation-demo-2.vue\n",[83,92,94],{"class":85,"line":93},2,[83,95,96],{"class":89},"audioUrl: '/audio/boki3/chapter4_0/boki3_ch4_0_00.webm'  // ← .webm\n",[98,99,100],"blockquote",{},[18,101,102,112,114,115,117],{},[22,103,104,105,108,109,111],{},"なぜ",[38,106,107],{},".opus","ではなく",[38,110,64],{},"？",[38,113,107],{},"ファイル（生のOpusストリーム）はdurationメタデータが欠けやすく、ブラウザで再生時間が取得できない問題があります。",[38,116,64],{},"コンテナ（Opus音声入り）なら正しくdurationが保持されます。",[45,119,121],{"id":120},"_3-githubにプッシュ","3. GitHubにプッシュ",[31,123,127],{"className":124,"code":125,"language":126,"meta":40,"style":40},"language-bash shiki shiki-themes vitesse-light vitesse-light","git add .\ngit commit -m \"Add audio files\"\ngit push origin master\n","bash",[38,128,129,142,163],{"__ignoreMap":40},[83,130,131,135,139],{"class":85,"line":86},[83,132,134],{"class":133},"senZ8","git",[83,136,138],{"class":137},"sdGka"," add",[83,140,141],{"class":137}," .\n",[83,143,144,146,149,153,157,160],{"class":85,"line":93},[83,145,134],{"class":133},[83,147,148],{"class":137}," commit",[83,150,152],{"class":151},"snbK4"," -m",[83,154,156],{"class":155},"sMJiu"," \"",[83,158,159],{"class":137},"Add audio files",[83,161,162],{"class":155},"\"\n",[83,164,166,168,171,174],{"class":85,"line":165},3,[83,167,134],{"class":133},[83,169,170],{"class":137}," push",[83,172,173],{"class":137}," origin",[83,175,176],{"class":137}," master\n",[18,178,179],{},"これだけでOK。あとは自動で処理される。",[14,181,183],{"id":182},"自動で起こることgithub-actions","自動で起こること（GitHub Actions）",[185,186,187,194,204,217,223],"ol",{},[188,189,190,193],"li",{},[22,191,192],{},"FFmpegをインストール","（Ubuntu環境）",[188,195,196,199,200,203],{},[22,197,198],{},"Nuxtビルド実行","（",[38,201,202],{},"pnpm build","）",[188,205,206,209,210,213,214,216],{},[22,207,208],{},"ビルドフック","が ",[38,211,212],{},".wav"," → ",[38,215,64],{},"（Opus音声）に変換",[188,218,219,222],{},[22,220,221],{},"元のWAVを削除","（デプロイサイズ削減）",[188,224,225,199,228,230],{},[22,226,227],{},"Cloudflareにデプロイ",[38,229,64],{},"ファイルのみ）",[14,232,234],{"id":233},"なぜwavをgithubにプッシュするのか","なぜWAVをGitHubにプッシュするのか？",[236,237,238,254],"table",{},[239,240,241],"thead",{},[242,243,244,248,251],"tr",{},[245,246,247],"th",{},"方法",[245,249,250],{},"メリット",[245,252,253],{},"デメリット",[255,256,257,271,282],"tbody",{},[242,258,259,265,268],{},[260,261,262],"td",{},[22,263,264],{},"WAVをpush（採用）",[260,266,267],{},"編集しやすい、履歴管理できる",[260,269,270],{},"リポジトリサイズが大きくなる",[242,272,273,276,279],{},[260,274,275],{},"Opusに変換してからpush",[260,277,278],{},"リポジトリが軽い",[260,280,281],{},"毎回手動変換が必要",[242,283,284,287,289],{},[260,285,286],{},"外部ストレージ（S3等）",[260,288,278],{},[260,290,291],{},"設定が複雑、コスト発生",[18,293,294,297],{},[22,295,296],{},"結論",": 音声ファイルが少量ならWAVをpushするのがシンプルで管理しやすい。",[14,299,300],{"id":300},"ファイルサイズ削減効果",[236,302,303,316],{},[239,304,305],{},[242,306,307,310,313],{},[245,308,309],{},"形式",[245,311,312],{},"1分あたり",[245,314,315],{},"品質",[255,317,318,329],{},[242,319,320,323,326],{},[260,321,322],{},"WAV",[260,324,325],{},"~10MB",[260,327,328],{},"完全（非圧縮）",[242,330,331,334,337],{},[260,332,333],{},"Opus 96kbps",[260,335,336],{},"~0.7MB",[260,338,339],{},"高品質（音声に最適）",[18,341,342,345],{},[22,343,344],{},"約90%のサイズ削減","になる。",[14,347,348],{"id":348},"関連ファイル",[45,350,352],{"id":351},"変換処理nuxtconfigts","変換処理（nuxt.config.ts）",[31,354,358],{"className":355,"code":356,"language":357,"meta":40,"style":40},"language-typescript shiki shiki-themes vitesse-light vitesse-light","// apps/web/nuxt.config.ts の hooks セクション\n'nitro:build:public-assets': async (nitro) => {\n  // ... WAV→Opus変換処理\n}\n","typescript",[38,359,360,366,400,405],{"__ignoreMap":40},[83,361,362],{"class":85,"line":86},[83,363,365],{"class":364},"sxvE3","// apps/web/nuxt.config.ts の hooks セクション\n",[83,367,368,371,374,376,379,383,387,391,394,397],{"class":85,"line":93},[83,369,370],{"class":155},"'",[83,372,373],{"class":137},"nitro:build:public-assets",[83,375,370],{"class":155},[83,377,378],{"class":89},": ",[83,380,382],{"class":381},"stQ0i","async",[83,384,386],{"class":385},"shFtX"," (",[83,388,390],{"class":389},"s4oTP","nitro",[83,392,393],{"class":385},")",[83,395,396],{"class":385}," =>",[83,398,399],{"class":385}," {\n",[83,401,402],{"class":85,"line":165},[83,403,404],{"class":364},"  // ... WAV→Opus変換処理\n",[83,406,408],{"class":85,"line":407},4,[83,409,410],{"class":385},"}\n",[45,412,414],{"id":413},"github-actionsdeployyml","GitHub Actions（deploy.yml）",[31,416,420],{"className":417,"code":418,"language":419,"meta":40,"style":40},"language-yaml shiki shiki-themes vitesse-light vitesse-light","# .github/workflows/deploy.yml\n- name: Install FFmpeg\n  run: sudo apt-get update && sudo apt-get install -y ffmpeg\n","yaml",[38,421,422,427,442],{"__ignoreMap":40},[83,423,424],{"class":85,"line":86},[83,425,426],{"class":364},"# .github/workflows/deploy.yml\n",[83,428,429,432,436,439],{"class":85,"line":93},[83,430,431],{"class":385},"-",[83,433,435],{"class":434},"sz8Xr"," name",[83,437,438],{"class":385},":",[83,440,441],{"class":137}," Install FFmpeg\n",[83,443,444,447,449],{"class":85,"line":165},[83,445,446],{"class":434},"  run",[83,448,438],{"class":385},[83,450,451],{"class":137}," sudo apt-get update && sudo apt-get install -y ffmpeg\n",[14,453,454],{"id":454},"トラブルシューティング",[45,456,457],{"id":457},"音声が再生されない",[185,459,460,466,469],{},[188,461,462,463,465],{},"コードで ",[38,464,64],{}," を指定しているか確認",[188,467,468],{},"ビルドログで変換成功を確認",[188,470,471],{},"ブラウザの開発者ツールでネットワークエラーを確認",[45,473,474],{"id":474},"ローカル開発時",[18,476,477,478,480,481,484,485,488,489,491],{},"ローカルでは ",[38,479,212],{}," ファイルがそのまま ",[38,482,483],{},"public/"," にあるため、開発サーバー（",[38,486,487],{},"pnpm dev","）では ",[38,490,212],{}," が配信される。",[18,493,494,497,498,500,501,503],{},[22,495,496],{},"フォールバック機能","により、コードで",[38,499,64],{},"を指定していても、自動的に",[38,502,212],{},"にフォールバックするので、開発時もそのまま動作する。",[18,505,506,509,510,512],{},[22,507,508],{},"ビルド後のプレビュー","（本番と同じ",[38,511,64],{},"で確認したい場合）:",[31,514,518],{"className":515,"code":516,"language":517,"meta":40,"style":40},"language-powershell shiki shiki-themes vitesse-light vitesse-light","# PowerShellの場合（セミコロンで区切る）\npnpm build; npx wrangler pages dev dist\n\n# または別々に実行\npnpm build\nnpx wrangler pages dev dist\n","powershell",[38,519,520,525,530,536,541,547],{"__ignoreMap":40},[83,521,522],{"class":85,"line":86},[83,523,524],{},"# PowerShellの場合（セミコロンで区切る）\n",[83,526,527],{"class":85,"line":93},[83,528,529],{},"pnpm build; npx wrangler pages dev dist\n",[83,531,532],{"class":85,"line":165},[83,533,535],{"emptyLinePlaceholder":534},true,"\n",[83,537,538],{"class":85,"line":407},[83,539,540],{},"# または別々に実行\n",[83,542,544],{"class":85,"line":543},5,[83,545,546],{},"pnpm build\n",[83,548,550],{"class":85,"line":549},6,[83,551,552],{},"npx wrangler pages dev dist\n",[18,554,555,556,559],{},"※ ",[38,557,558],{},"&&"," はPowerShellでは使えません",[14,561,562],{"id":562},"まとめ",[185,564,565,575,582,588],{},[188,566,567,570,571,574],{},[22,568,569],{},"WAVファイル","を ",[38,572,573],{},"public/audio/"," に保存",[188,576,577,65],{},[22,578,579,580],{},"コードでは ",[38,581,64],{},[188,583,584,587],{},[22,585,586],{},"git push"," するだけ",[188,589,590],{},"自動で変換＆デプロイされる",[592,593,594],"style",{},"html pre.shiki code .sG7-3, html code.shiki .sG7-3{--shiki-default:#393A34;--shiki-dark:#393A34}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .senZ8, html code.shiki .senZ8{--shiki-default:#59873A;--shiki-dark:#59873A}html pre.shiki code .sdGka, html code.shiki .sdGka{--shiki-default:#B56959;--shiki-dark:#B56959}html pre.shiki code .snbK4, html code.shiki .snbK4{--shiki-default:#A65E2B;--shiki-dark:#A65E2B}html pre.shiki code .sMJiu, html code.shiki .sMJiu{--shiki-default:#B5695977;--shiki-dark:#B5695977}html pre.shiki code .sxvE3, html code.shiki .sxvE3{--shiki-default:#A0ADA0;--shiki-dark:#A0ADA0}html pre.shiki code .stQ0i, html code.shiki .stQ0i{--shiki-default:#AB5959;--shiki-dark:#AB5959}html pre.shiki code .shFtX, html code.shiki .shFtX{--shiki-default:#999999;--shiki-dark:#999999}html pre.shiki code .s4oTP, html code.shiki .s4oTP{--shiki-default:#B07D48;--shiki-dark:#B07D48}html pre.shiki code .sz8Xr, html code.shiki .sz8Xr{--shiki-default:#998418;--shiki-dark:#998418}",{"title":40,"searchDepth":93,"depth":93,"links":596},[597,598,604,605,606,607,611,615],{"id":16,"depth":93,"text":16},{"id":43,"depth":93,"text":43,"children":599},[600,601,603],{"id":47,"depth":165,"text":48},{"id":60,"depth":165,"text":602},"2. Vueコンポーネントでは .webm を指定",{"id":120,"depth":165,"text":121},{"id":182,"depth":93,"text":183},{"id":233,"depth":93,"text":234},{"id":300,"depth":93,"text":300},{"id":348,"depth":93,"text":348,"children":608},[609,610],{"id":351,"depth":165,"text":352},{"id":413,"depth":165,"text":414},{"id":454,"depth":93,"text":454,"children":612},[613,614],{"id":457,"depth":165,"text":457},{"id":474,"depth":165,"text":474},{"id":562,"depth":93,"text":562},null,"WAVファイルをGitHubにプッシュし、ビルド時に自動でOpusに変換する仕組みの解説","md",{},"/audio-wav-to-opus-pipeline",false,"2025-12-12T00:00:00.000Z",{"title":5,"description":617},"2025-12/2025-12-12/audio-wav-to-opus-pipeline",[626,627,628,629,630,631],"audio","wav","opus","ffmpeg","github-actions","cloudflare","HcgiID4V66VVrXWAyTGmIohlNhlaJl-ZDsYyDTNFf_o",[],[635,638,642,646,650],{"title":636,"path":637,"publishedAt":622},"WAV・MP3・Opus - Webに最適なオーディオフォーマットは？","/wav-vs-mp3",{"title":639,"path":640,"publishedAt":641},"浅草寺サウンドスケーププレイヤーの開発 - GPX地図・音声解析・MGS風UIの統合","/soundscape-player-2026-02-16","2026-02-16T00:00:00.000Z",{"title":643,"path":644,"publishedAt":645},"QQQ銘柄 動画バッチ生成・R2配信計画","/video-batch-generation-plan","2025-12-16T00:00:00.000Z",{"title":647,"path":648,"publishedAt":649},"Cloudflare Pages Git統合からGitHub Actions Direct Uploadへの移行記録","/cloudflare-github-actions-migration","2025-12-07T00:00:00.000Z",{"title":651,"path":652,"publishedAt":653},"開発環境のバックアップを仕上げ、復旧手順をスキル化してGitHubで版管理する","/claude-env-backup-and-restore-skill","2026-07-30T00:00:00.000Z","https://log.eurekapu.com/og/blog/audio-wav-to-opus-pipeline.png?v=2025-12-12T00%3A00%3A00.000Z&title=%E9%9F%B3%E5%A3%B0%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E5%A4%89%E6%8F%9B%E3%83%91%E3%82%A4%E3%83%97%E3%83%A9%E3%82%A4%E3%83%B3%EF%BC%88WAV%E2%86%92Opus%EF%BC%89&author=Kei%20Komatsu&sig=16bbf1c386b2bb9e",1785654973630]