Failed to execute 'createMediaElementSource' on 'AudioContext': HTMLMediaElement already connected previously to a different MediaElementSourceNode
Web Audio APIを初めて使うと次のエラーが出る場合があります。
Uncaught DOMException: Failed to execute 'createMediaElementSource' on 'AudioContext': HTMLMediaElement already connected previously to a different MediaElementSourceNode.
このエラーを日本語にすると
DOMExceptionが発生しました: 'AudioContext'で 'createMediaElementSource'を実行できませんでした:HTMLMediaElementはすでに別のMediaElementSourceNodeに接続されています。
という意味です。早い話、createMediaElementSource()を2回実行しないでねってことです。
エラーの回避方法
HTMLMediaElementをWeakMapオブジェクトで管理します。
var audioEle; var audioSourceNode; var wm = new WeakMap(); if(audioSourceNode){ audioSourceNode.disconnect(); } // WeakMapでHTMLMediaElementを管理する if (wm.has(audioEle)) { audioSourceNode = wm.get(audioEle); } else { audioSourceNode = audioCtx.createMediaElementSource(audioEle); wm.set(audioEle, audioSourceNode); }
使用例
次のコードは音声ファイルを読み込んで自動再生します。
<!doctype html> <html> <head> <meta charset="UTF-8"> </head> <body ondrop="onDrop(event);" ondragover="onDragOver(event);"> <script> var audioCtx; var analyserNode; var audioSourceNode; var audioEle; var wm = new WeakMap(); var firstFlag = true; window.onload= function(){ audioEle = document.getElementById('myAudio'); audioEle.autoplay = true; audioEle.preload = 'auto'; } function onDragOver(event){ event.preventDefault(); } function onDrop(event){ onAddFile(event); event.preventDefault(); } function onAddFile(event) { var files; var reader = new FileReader(); if(event.target.files){ files = event.target.files; }else{ files = event.dataTransfer.files; } reader.onload = function (event) { if(firstFlag){ // AudioContextの生成 audioCtx = new AudioContext(); firstFlag = false; } audioEle.onloadeddata = function (){ if(audioSourceNode){ audioSourceNode.disconnect(); } // WeakMapでHTMLMediaElementを管理する if (wm.has(audioEle)) { audioSourceNode = wm.get(audioEle); } else { audioSourceNode = audioCtx.createMediaElementSource(audioEle); wm.set(audioEle, audioSourceNode); } // AnalyserNodeの生成 if(analyserNode){ analyserNode.disconnect(); } analyserNode = audioCtx.createAnalyser(); audioSourceNode.connect(analyserNode); analyserNode.connect(audioCtx.destination); }; audioEle.onerror = function (e) { alert("このファイルは読み込めません。"); } audioEle.src = reader.result; }; if (files[0]){ reader.readAsDataURL(files[0]); } } </script> <input type="file" id="inputfile" onchange="onAddFile(event);" style="padding:0;width:240px;"> <br> <br> <audio id="myAudio" controls></audio> <br> </body> </html>
複数回、音声ファイルを読み込んでもエラーがでないようになりました。
では、各自の作業に戻りましょう :-)
参考サイト
WeakMap (MDN web docs)
スポンサーリンク
関連記事
公開日:2019年02月12日
記事NO:02729
この記事を書いた人
![]() | 💻 ITスキル・経験 サーバー構築からWebアプリケーション開発。IoTをはじめとする電子工作、ロボット、人工知能やスマホ/OSアプリまで分野問わず経験。 画像処理/音声処理/アニメーション、3Dゲーム、会計ソフト、PDF作成/編集、逆アセンブラ、EXE/DLLファイルの書き換えなどのアプリを公開。詳しくは自己紹介へ |
プチモンテ代表、アーティスト名:プチモンテ | |
🎵 音楽制作 BGMは楽器(音源)さえあれば、何でも制作可能。歌モノは主にロック、バラード、ポップスを制作。歌詞は叙情詩、叙情的な楽曲が多い。楽曲制作は2023年12月中旬 ~ |
オリジナル曲を始めました✨
YouTubeで各楽曲を公開しています🌈
https://www.youtube.com/@petitmonte