1
votes

I'm trying to create a 1ch (mono) MediaStreamTrack with a MediaStreamAudioDestinationNode. According to the standard, this should be possible.

const ctx = new AudioContext();
const destinationNode = new MediaStreamAudioDestinationNode(ctx, {
    channelCount: 1,
    channelCountMode: 'explicit',
    channelInterpretation: 'speakers',
});
await ctx.resume(); // doesn't make a difference

// this fails
expect(destinationNode.stream.getAudioTracks()[0].getSettings().channelCount).equal(1);

Result:

  • Chrome 92.0.4515.107 always creates a stereo track
  • Firefox 90 returns nothing for destinationNode.stream.getAudioTracks()[0].getSettings() even though getSettings() should be fully supported

What am I doing wrong here?


Edit: Apparently both firefox and chrome actually produce a mono track, they just don't tell you the truth. Here's a workaround solution for Typescript:

async function getNumChannelsInTrack(track: MediaStreamTrack): Promise<number> {
    // unfortunately, we can't use track.getSettings().channelCount, because
    // - Firefox 90 returns {} from getSettings() => see: https://bugzilla.mozilla.org/show_bug.cgi?id=1307808
    // - Chrome 92 always reports 2 channels, even if that's incorrect => see: https://bugs.chromium.org/p/chromium/issues/detail?id=1044645
    // Workaround: Record audio and look at the recorded buffer to determine the number of audio channels in the buffer.

    const stream = new MediaStream();
    stream.addTrack(track);
    const mediaRecorder = new MediaRecorder(stream);

    mediaRecorder.start();

    return new Promise<number>((resolve) => {
        setTimeout(() => {
            mediaRecorder.stop();
            mediaRecorder.ondataavailable = async ({ data }) => {
                const offlineAudioContext = new OfflineAudioContext({
                    length: 1,
                    sampleRate: 48000,
                });
                const audioBuffer = await offlineAudioContext.decodeAudioData(
                    await data.arrayBuffer()
                );
                resolve(audioBuffer.numberOfChannels);
            };
        }, 1000);
    });
}
1

1 Answers

2
votes

I don't think you're doing anything wrong. It's a known issue (https://bugs.chromium.org/p/chromium/issues/detail?id=1044645) in Chrome which just didn't get fixed so far.

I think in Firefox it isn't even implemented. This bug (https://bugzilla.mozilla.org/show_bug.cgi?id=1307808) indicates that getSettings() only returns those values that can be changed so far.

I think it would be helpful if you star/follow theses issues or comment on them to make sure they don't get forgotten about.