背景
用户在插入耳机的情况下,把耳机拔下来,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;
});
}