如果在音频播放时初始化麦克风,Safari 上的 iPhone 会混淆将音频输出到哪个扬声器

Hol*_*tly 6 mobile-safari html5-audio web-audio-api

iPhone 在 Safari 中通过扬声器播放音频时遇到问题。麦克风初始化后,我们会播放一个简短的音频剪辑(大约三秒),然后我们用麦克风记录用户的响应 - 这种事件模式会发生三次。第一个音频片段通过听筒扬声器播放 - 音量较低。然后,在麦克风记录第一个用户响应后,通过扬声器播放以下音频剪辑(这对于所有三个音频剪辑来说都是所需的)。在音频上下文目标方面,什么可能会让 iOS/Safari 感到困惑?是否可以设置一个设置来确保免提通话,或者可以使用另一个事件模式来实现我想要的行为。 所需行为:即使麦克风已初始化,iPhone 也会通过免提电话播放所有音频剪辑。

1:在“功能设置”(音频播放和录音响应)之前播放一小段音频剪辑 2:在麦克风初始化后设置超时,并开始麦克风流。3:我们已经调整了开始录制/播放音频的顺序。4:如果没有初始化麦克风并且从未开始录制,则会发生所需的行为。

audio = new Audio();
this.audio.src = audioUrl;
const audioFileLoadedPromise = this.audio.play()
//////////////////////////////////////////////////
const mediaStreamConstraints: MediaStreamConstraints = {
        audio: !enableAudio ? false : {
            echoCancellation: true,
            volume: 1.0
        },
        video: false : (enableVideo === true ? 

this.getCameraConstraints() : enableVideo),
};

navigator.mediaDevices.getUserMedia(mediaStreamConstraints)
/////////////////////////////////////////////////


await this.microphoneComponent.initComponent();
await this.microphoneComponent.startRecording();
await sleep(1000); //this pause was to test if timing somehow affected playback
this.beginAudio(); //this is the audio clip that is played through handset

////from here the pattern continues switching off between playing audio and recording user response and audio is played through speakerphone (as desired)
Run Code Online (Sandbox Code Playgroud)

所需行为:即使麦克风已初始化,iPhone 也会通过免提电话播放所有音频剪辑。

Mic*_*rk. 1

这是 iOS 的一个已知问题,记录在此处 https://bugs.webkit.org/show_bug.cgi?id=230902

我尝试过的解决方法如下(TypeScript)

public connectToSpeaker(remoteAudioStream: MediaStream, gain: number) {
        try {
            const AudioCtx = window.AudioContext || window['webkitAudioContext'];
            const context = new AudioCtx();
            const audioNode = context.createMediaStreamSource(remoteAudioStream);
            const gainNode: GainNode = context.createGain();
            // some device volume too low ex. iPad
            gainNode.gain.value = gain;
            audioNode.connect(gainNode);
            gainNode.connect(context.destination);
        } catch (ex) {
            // will throw an exception if no audio track exists
            console.error(ex)
        }
    }
Run Code Online (Sandbox Code Playgroud)