背景
用户在插入耳机的情况下,把耳机拔下来,pc不会出现静音的提示,但是在其他端(app、小程序)会发现pc端已经静音了,所以pc那边说话,其他端也听不到他说话
分析
其实在拔掉耳机的时候,音频流就已经停止了,只不过在pc那边没有对本地流进行监听,所以没有及时把声音的状态进行变更
解决
监听耳机拔掉的事件,属于stream的监听,而不是用户client的监听,耳机拔掉,触发了player-state-changed事件
this.localStream.on('player-state-changed', event => {console.warn(`${event.type} player is ${event.state}`);if (event.type === 'audio' && event.state === 'STOPPED') {// 移除音频--拔掉耳机this.removeAudioFlag = true;// 本地流操作icon修改为静音let obj = this.operatBarList.find(item => {return item.icon === 'micro'});if (obj.state === 'on') {obj.state = "off";obj.name = "取消静音";this.roomUserList.forEach(item => {if (item.user_id === this.localUserID) {item.micro_state = "off";}});}}});
- 拔耳机事件,实际上就是把音频流关闭了,就是移除了,所以其他端都听不到声音了,这个时候需要pc端手动把声音的icon进行修改,可以修改为静音标志,或者提醒用户,你触发了静音操作 - 设置一个标志位,到时候用户重新打开声音的时候,需要新建一个声音流,并且把原本本地的音频轨道替换成新建的声音轨道,不仅仅只是this.localStream.unmuteAudio();,因为这个时候其实音频轨道还在,只不过音频已经没有了,所以只能替换轨道 |
|---|
代码如下:
if (this.removeAudioFlag) {// 新建一个音频流const localAudioStream = TRTC.createStream({ audio: true, video: false });localAudioStream.initialize().then(() => {console.warn('local audio stream init success');this.localStream.replaceTrack(localAudioStream.getAudioTrack()).then(() => {console.log('add audio call success');});this.removeAudioFlag = false;});}
