我正在尝试在 nextjs 项目中使用 creatstream 和 mode live 构建语音聊天。但是遇到一些不正常的行为。通话开始后,如果有多个主持人或某人离开并加入,则屏幕上的鼠标单击事件丢失。这意味着不能主持/观众不能静音/取消静音或离开通话。但可以用键盘控件做同样的事情。有人可以解释一下,我错过了什么。我正在为主机附上agora 的代码。如果有人可以帮助我理解这个问题,那就太好了。我们也在生成 RTCtoken。提前致谢!
function AgoraVoiceCall({ channel, attendeeMode, appId, uid, user }) {
console.log(attendeeMode);
const [client, setClient] = useState(null);
const [localStream, setLocalStream] = useState(null);
//Mutation
const [generateAgoraToken, { data, loading }] = useMutation(
GENERATE_SPACE_TOKEN
);
var options = {
token: undefined,
uid: Math.floor(Math.random() * Date.now() * 0.001).toString(),
};
const join = async () => {
let clientInstance = Agora.createClient({ mode: 'live', codec: 'vp8' });
clientInstance.setClientRole(attendeeMode);
const token = await generateAgoraToken({
variables: { channelName: channel, uid: options.uid, role: attendeeMode },
});
(options.token = token && token.data.generateAgoraToken),
console.log('token', token.data.generateAgoraToken);
clientInstance.init(appId, () => {
clientInstance.join(options.token, channel, options.uid, uid => {
let localStreamInstance = Agora.createStream({
streamID: uid,
audio: true,
video: false,
screen: false,
});
setLocalStream(localStreamInstance);
localStreamInstance.init(() => {
clientInstance.publish(localStreamInstance);
const div = document
.getElementById('local_stream')
.insertAdjacentHTML(
'afterBegin',
`<div id="player-wrapper-${options.uid}">
<p class="player-name">LocalUser(${options.uid})</p>
</div>`
);
localStreamInstance.play('local_stream');
});
clientInstance.on('stream-added', evt => {
let remoteStream = evt.stream;
const id = remoteStream.getId();
const div = document
.getElementById('remote_stream')
.insertAdjacentHTML(
'afterBegin',
`<div id="player-wrapper-${id}">
<p class="player-name">RemoteUser(${id})</p>
</div>`
);
console.log(div);
clientInstance &&
clientInstance.subscribe(remoteStream, function(err) {
console.log('Subscribe stream failed', err);
});
});
clientInstance.on('stream-subscribed', evt => {
let remoteStream = evt.stream;
remoteStream.play('remote_stream');
});
clientInstance.on('stream-unpublished', evt => {
console.log('peer-leave', evt.stream);
let remoteStream = evt.stream;
const id = remoteStream.getId();
delete remoteUsers[id];
const remoteUserContainer = document.getElementById(
`player-wrapper-${id}`
);
remoteUserContainer.remove();
console.log(remoteUsers);
setRemoteUsersData(remoteUsers);
});
});
});
setClient(clientInstance);
};
const leaveCall = () => {
// Destroy the local audio and track.
client && client.unpublish(localStream);
localStream && localStream.close();
const id = localStream.getId();
const localStreamContainer = document.getElementById(
`player-wrapper-${id}`
);
localStreamContainer && localStreamContainer.remove();
// Leave the channel.
client &&
client.leave(
() => {
console.log('Client succeed to leave.');
},
() => {
console.log('Client failed to leave.');
}
);
setLocalStream(null);
};
const handleMic = () => {
const btn = document.getElementById('mic-btn');
if (localStream.isAudioOn()) {
localStream.muteAudio();
btn.innerHTML = 'UNMUTE';
} else {
localStream.unmuteAudio();
btn.innerHTML = 'MUTE';
}
};
return (
<Wrapper>
<div
style={{
display: 'flex',
flexDirection: 'column',
margin: '0 auto',
height: '100vh',
width: '60vw',
backgroundColor: 'lightblue',
}}
>
<h2>Welcome to Neospace Voice Call</h2>
<div
style={{
height: '30vh',
backgroundColor: 'pink',
border: '3px solid black',
}}
id="local_stream"
>
<Avatar src={user.avatarUrl ?? '/avatar_placeholder.svg'} />
</div>
<div
style={{
height: '30vh',
backgroundColor: 'yellow',
border: '3px solid black',
}}
id="remote_stream"
>
<Avatar src={user.avatarUrl ?? '/avatar_placeholder.svg'} />
</div>
<div
style={{
height: '20vh',
backgroundColor: 'orange',
border: '3px solid black',
}}
>
control
<div
style={{
margin: '5vh 0 0 30vh',
}}
>
{/* All these button onclick with the mouse is not working */}
<button
onClick={join}
style={{ marginRight: '15px', fontSize: '20px' }}
disabled={localStream}
>
JOIN CALL
</button>
<button
id="mic-btn"
onClick={e => {
handleMic(e);
}}
style={{ marginRight: '15px', fontSize: '20px' }}
>
MUTE
</button>
<button onClick={leaveCall} style={{ fontSize: '20px' }}>
END CALL
</button>
</div>
</div>
</div>
</Wrapper>
);
} export default withApollo(AgoraVoiceCall);