LoginSignup
1
0

Google ChromeでMediaStreamSourceの音がならない問題

Posted at

simple-peerを使ってボイスチャットをするwebアプリを作ってたらstream関連のWeb Audio APIで3時間くらい沼にはまってしまったので供養しようと思います。

問題提起

良い例.js
peer.on("stream", stream => {
    const audioElement = document.querySelector("audio");
    audioElement.srcObject = stream;
    audioElement.play();
});

simple-peerのgithubに例示されているようにAudioElementのsrcObjectに直接streamを代入した場合はどのブラウザでも音が鳴るのですが、

良くない例.js
let audioContext = new AudioContext();

peer.on("stream", stream => {
    const audioElement = document.querySelector("audio");
    const mediaStreamSource = audioContext.createMediaStreamSource(stream);
    const destination = audioContext.createMediaStreamDestination();
    mediaStreamSource.connect(destination);
    audioElement.srcObject = destination.stream;
    audioElement.play();
});

Web Audio APIを噛ませた場合、Safariなどでは音が鳴るのにも関わらずChromeでは音が鳴らなくなってしまいます。

原因

何年も前からあるChromeのバグ ( https://issues.chromium.org/issues/40094084 ) が原因のようで、elementのsourceになっていないstreamは音がならないようになってしまっているようです(多分)。

で、どうすればいいのよ?

適当なelementのsrcObjectに生のstreamを入れた後、別のelementにWeb Audio APIから出力したstreamを入れるとChromeでも鳴るようになります。
この時、未編集の音とWeb Audio APIで編集した音が2重で鳴ってしまうので生のstreamが入っているelementはmutedをtrueに設定しておきます。

解決策.js
let audioContext = new AudioContext();

peer.on("stream", stream => {
    /* 適当なAudioElementのsrcObjectにstreamを直接入れる */
    const fakeAudioElement = document.querySelector("audio"); /* new Audio()とかでも可 */
    fakeAudioElement.srcObject = stream;
    fakeAudioElement.muted = true;
    fakeAudioElement.play();
    /* 別のAudioElementにWeb Audio APIから出力したstreamを入れる */
    const audioElement = new Audio();
    const mediaStreamSource = audioContext.createMediaStreamSource(stream);
    const destination = audioContext.createMediaStreamDestination();
    // TODO: write Web Audio API processing here
    mediaStreamSource.connect(destination);
    audioElement.srcObject = destination.stream;
    audioElement.play();
});

これで鳴るようになっている...はず!

参考文献

(最終閲覧日はともに2024/05/29)

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0