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月中旬 ~ | |









