Agora视频呼叫Webrtc do react和laravel的展示
我正在研究React和Laravel项目,我想在视频通话中实施用户互相呼叫和联合的能力。我已经按照他们的文档指示实现了所有代码,并且我使用Laravel后端来生成令牌。显然,一切都起作用了,我没有任何错误。但是,我的相机打开了,但是在屏幕上没有显示本地流(视频)。我怀疑我的React代码有问题:
import React, { useEffect, useState, useRef } from "react";
import { connect } from "react-redux";
import Echo from "laravel-echo";
import axios from "axios";
import AgoraRTC from "agora-rtc-sdk";
import styles from "./css/settingspace.module.css";
const AGORA_ID = "my app id copyed from agora website";
const VideoCallPage = (props) => {
const [agoraConnection, setAgoraConnection] = useState({
callPlaced: false,
mutedAudio: false,
mutedVideo: false,
userOnlineChannel: null,
onlineUsers: [],
incomingCall: false,
incomingCaller: "",
agoraChannel: null,
});
const client = useRef(null);
const localStream = useRef(null);
useEffect(() => {
const initUserOnlineChannel = () => {
console.log("Initiate User Online Channel");
setAgoraConnection((prevAgoraConnection) => ({
...prevAgoraConnection,
userOnlineChannel: window.Echo.join("agora-online-channel"),
}));
console.log("Initiate User Online Channel - Finished");
};
const initUserOnlineListeners = () => {
console.log("Initiate User Online Listeners");
agoraConnection.userOnlineChannel.here((users) => {
setAgoraConnection((prevAgoraConnection) => ({
...prevAgoraConnection,
onlineUsers: users,
}));
});
agoraConnection.userOnlineChannel.joining((user) => {
// check user availability
const joiningUserIndex = agoraConnection.onlineUsers.findIndex(
(data) => data.id === user.id
);
if (joiningUserIndex < 0) {
setAgoraConnection((prevAgoraConnection) => ({
...prevAgoraConnection,
onlineUsers: [...agoraConnection.onlineUsers, user],
}));
}
});
agoraConnection.userOnlineChannel.leaving((user) => {
const leavingUserIndex = agoraConnection.onlineUsers.findIndex(
(data) => data.id === user.id
);
setAgoraConnection((prevAgoraConnection) => ({
...prevAgoraConnection,
onlineUsers: prevAgoraConnection.onlineUsers.splice(
leavingUserIndex,
1
),
}));
});
// listen to incoming call
agoraConnection.userOnlineChannel.listen("MakeAgoraCall", ({ data }) => {
console.log("Incoming call");
if (parseInt(data.userToCall) === parseInt(props.user.id)) {
const callerIndex = agoraConnection.onlineUsers.findIndex(
(user) => user.id === data.from
);
// the channel that was sent over to the user being called is what
// the receiver will use to join the call when accepting the call.
setAgoraConnection((prevAgoraConnection) => ({
...prevAgoraConnection,
incomingCaller: agoraConnection.onlineUsers[callerIndex]["name"],
incomingCall: true,
agoraChannel: data.channelName,
}));
}
});
};
initUserOnlineChannel();
if (agoraConnection.userOnlineChannel) {
initUserOnlineListeners();
}
}, [
agoraConnection.onlineUsers,
agoraConnection.userOnlineChannel,
props.user.id,
]);
const placeCall = async (id, calleeId) => {
try {
// channelName = the caller's and the callee's id. you can use anything. tho.
const channelName = `${props.user.id}_${calleeId}`;
const tokenRes = await generateToken(channelName);
// Broadcasts a call event to the callee and also gets back the token
await axios.post("api/agora/call-user", {
user_to_call: id,
channel_name: channelName,
});
initializeAgora();
joinRoom(tokenRes.data, channelName);
} catch (error) {
console.log(error);
}
};
const acceptCall = async () => {
initializeAgora();
const tokenRes = await generateToken(agoraConnection.agoraChannel);
joinRoom(tokenRes.data, agoraConnection.agoraChannel);
setAgoraConnection({
...agoraConnection,
incomingCall: false,
callPlaced: true,
});
};
const declineCall = () => {
// You can send a request to the caller to
// alert them of rejected call
setAgoraConnection({
incomingCall: false,
});
};
const generateToken = (channelName) => {
return axios.post("api/agora/token", {
channelName,
});
};
const initializeAgora = () => {
client.current = AgoraRTC.createClient({ mode: "rtc", codec: "vp8" });
client.current.init(
AGORA_ID,
() => {
console.log("AgoraRTC client initialized");
},
(err) => {
console.log("AgoraRTC client init failed", err);
}
);
};
const joinRoom = async (token, channel) => {
client.current.join(
token,
channel,
props.user.id,
(uid) => {
console.log("User " + uid + " join channel successfully");
setAgoraConnection({ ...agoraConnection, callPlaced: true });
createLocalStream();
initializedAgoraListeners();
},
(err) => {
console.log("Join channel failed", err);
}
);
};
const initializedAgoraListeners = () => {
// Register event listeners
client.current.on("stream-published", function (evt) {
console.log("Publish local stream successfully");
console.log(evt);
});
//subscribe remote stream
client.current.on("stream-added", ({ stream }) => {
console.log("New stream added: " + stream.getId());
client.current.subscribe(stream, function (err) {
console.log("Subscribe stream failed", err);
});
});
client.current.on("stream-subscribed", (evt) => {
// Attach remote stream to the remote-video div
evt.stream.play("remote-video");
client.current.publish(evt.stream);
});
client.current.on("stream-removed", ({ stream }) => {
console.log(String(stream.getId()));
stream.close();
});
client.current.on("peer-online", (evt) => {
console.log("peer-online", evt.uid);
});
client.current.on("peer-leave", (evt) => {
var uid = evt.uid;
var reason = evt.reason;
console.log("remote user left ", uid, "reason: ", reason);
});
client.current.on("stream-unpublished", (evt) => {
console.log(evt);
});
};
const createLocalStream = () => {
localStream.current = AgoraRTC.createStream({
audio: true,
video: true,
});
// Initialize the local stream
localStream.current.init(
() => {
// Play the local stream
localStream.current.play("me");
console.log("Local stream played");
// Publish the local stream
client.current.publish(localStream.current, (err) => {
console.log("publish local stream", err);
});
},
(err) => {
console.log(err);
}
);
};
const endCall = () => {
localStream.current.close();
client.current.leave(
() => {
console.log("Leave channel successfully");
setAgoraConnection({
...agoraConnection,
callPlaced: false,
});
},
(err) => {
console.log("Leave channel failed");
}
);
};
const handleAudioToggle = () => {
if (agoraConnection.mutedAudio) {
localStream.current.unmuteAudio();
setAgoraConnection({
...agoraConnection,
mutedAudio: false,
});
} else {
localStream.current.muteAudio();
setAgoraConnection({
...agoraConnection,
mutedAudio: true,
});
}
};
const handleVideoToggle = () => {
if (agoraConnection.mutedVideo) {
localStream.current.unmuteVideo();
setAgoraConnection({
...agoraConnection,
mutedVideo: false,
});
} else {
localStream.current.muteVideo();
setAgoraConnection({
...agoraConnection,
mutedVideo: true,
});
}
};
return (
<div className="mt-5">
<div>
<button
type="button"
className="btn btn-primary"
onClick={() => placeCall(4, 4)}
>
Call
</button>
</div>
{agoraConnection.incomingCall && (
<div className="row my-5">
<div className="col-12">
<p>
Incoming Call From{" "}
<strong>{agoraConnection.incomingCaller}</strong>
</p>
<div className="btn-group" role="group">
<button
type="button"
className="btn btn-danger"
data-dismiss="modal"
onClick={() => declineCall()}
>
Decline
</button>
<button
type="button"
className="btn btn-success ml-5"
onClick={() => acceptCall()}
>
Accept
</button>
</div>
</div>
</div>
)}
{agoraConnection.callPlaced && (
<section id="video-container">
<div id="me"></div>
<div id="remote-video"></div>
<div className="action-btns">
<button
type="button"
className="btn btn-info"
onClick={() => handleAudioToggle()}
>
{agoraConnection.mutedAudio ? "Unmute" : "Mute"}
</button>
<button
type="button"
className="btn btn-primary mx-4"
onClick={() => handleVideoToggle()}
>
{agoraConnection.mutedVideo ? "ShowVideo" : "HideVideo"}
</button>
<button
type="button"
className="btn btn-danger"
onClick={() => endCall()}
>
EndCall
</button>
</div>
</section>
)}
</div>
);
};
const mapStateToProps = (state) => {
return {
user: state.auth,
};
};
export default connect(mapStateToProps)(VideoCallPage);
在我打个电话后,我说我的网络相机启动了应显示我本地流的位置,但没有实际流:
我真的没有其他想法如何解决此问题。
I am working on react and laravel project and I want to implement the ability of to users to call each other and joint in a video call. I have implemented all of the code as instructed in their documentation and I have used Laravel back-end to generate the token. Apparently everything works and I get no errors. However, my camera opens but no local stream (video) is displayed on the screen. I suspect is something wrong with my react code:
import React, { useEffect, useState, useRef } from "react";
import { connect } from "react-redux";
import Echo from "laravel-echo";
import axios from "axios";
import AgoraRTC from "agora-rtc-sdk";
import styles from "./css/settingspace.module.css";
const AGORA_ID = "my app id copyed from agora website";
const VideoCallPage = (props) => {
const [agoraConnection, setAgoraConnection] = useState({
callPlaced: false,
mutedAudio: false,
mutedVideo: false,
userOnlineChannel: null,
onlineUsers: [],
incomingCall: false,
incomingCaller: "",
agoraChannel: null,
});
const client = useRef(null);
const localStream = useRef(null);
useEffect(() => {
const initUserOnlineChannel = () => {
console.log("Initiate User Online Channel");
setAgoraConnection((prevAgoraConnection) => ({
...prevAgoraConnection,
userOnlineChannel: window.Echo.join("agora-online-channel"),
}));
console.log("Initiate User Online Channel - Finished");
};
const initUserOnlineListeners = () => {
console.log("Initiate User Online Listeners");
agoraConnection.userOnlineChannel.here((users) => {
setAgoraConnection((prevAgoraConnection) => ({
...prevAgoraConnection,
onlineUsers: users,
}));
});
agoraConnection.userOnlineChannel.joining((user) => {
// check user availability
const joiningUserIndex = agoraConnection.onlineUsers.findIndex(
(data) => data.id === user.id
);
if (joiningUserIndex < 0) {
setAgoraConnection((prevAgoraConnection) => ({
...prevAgoraConnection,
onlineUsers: [...agoraConnection.onlineUsers, user],
}));
}
});
agoraConnection.userOnlineChannel.leaving((user) => {
const leavingUserIndex = agoraConnection.onlineUsers.findIndex(
(data) => data.id === user.id
);
setAgoraConnection((prevAgoraConnection) => ({
...prevAgoraConnection,
onlineUsers: prevAgoraConnection.onlineUsers.splice(
leavingUserIndex,
1
),
}));
});
// listen to incoming call
agoraConnection.userOnlineChannel.listen("MakeAgoraCall", ({ data }) => {
console.log("Incoming call");
if (parseInt(data.userToCall) === parseInt(props.user.id)) {
const callerIndex = agoraConnection.onlineUsers.findIndex(
(user) => user.id === data.from
);
// the channel that was sent over to the user being called is what
// the receiver will use to join the call when accepting the call.
setAgoraConnection((prevAgoraConnection) => ({
...prevAgoraConnection,
incomingCaller: agoraConnection.onlineUsers[callerIndex]["name"],
incomingCall: true,
agoraChannel: data.channelName,
}));
}
});
};
initUserOnlineChannel();
if (agoraConnection.userOnlineChannel) {
initUserOnlineListeners();
}
}, [
agoraConnection.onlineUsers,
agoraConnection.userOnlineChannel,
props.user.id,
]);
const placeCall = async (id, calleeId) => {
try {
// channelName = the caller's and the callee's id. you can use anything. tho.
const channelName = `${props.user.id}_${calleeId}`;
const tokenRes = await generateToken(channelName);
// Broadcasts a call event to the callee and also gets back the token
await axios.post("api/agora/call-user", {
user_to_call: id,
channel_name: channelName,
});
initializeAgora();
joinRoom(tokenRes.data, channelName);
} catch (error) {
console.log(error);
}
};
const acceptCall = async () => {
initializeAgora();
const tokenRes = await generateToken(agoraConnection.agoraChannel);
joinRoom(tokenRes.data, agoraConnection.agoraChannel);
setAgoraConnection({
...agoraConnection,
incomingCall: false,
callPlaced: true,
});
};
const declineCall = () => {
// You can send a request to the caller to
// alert them of rejected call
setAgoraConnection({
incomingCall: false,
});
};
const generateToken = (channelName) => {
return axios.post("api/agora/token", {
channelName,
});
};
const initializeAgora = () => {
client.current = AgoraRTC.createClient({ mode: "rtc", codec: "vp8" });
client.current.init(
AGORA_ID,
() => {
console.log("AgoraRTC client initialized");
},
(err) => {
console.log("AgoraRTC client init failed", err);
}
);
};
const joinRoom = async (token, channel) => {
client.current.join(
token,
channel,
props.user.id,
(uid) => {
console.log("User " + uid + " join channel successfully");
setAgoraConnection({ ...agoraConnection, callPlaced: true });
createLocalStream();
initializedAgoraListeners();
},
(err) => {
console.log("Join channel failed", err);
}
);
};
const initializedAgoraListeners = () => {
// Register event listeners
client.current.on("stream-published", function (evt) {
console.log("Publish local stream successfully");
console.log(evt);
});
//subscribe remote stream
client.current.on("stream-added", ({ stream }) => {
console.log("New stream added: " + stream.getId());
client.current.subscribe(stream, function (err) {
console.log("Subscribe stream failed", err);
});
});
client.current.on("stream-subscribed", (evt) => {
// Attach remote stream to the remote-video div
evt.stream.play("remote-video");
client.current.publish(evt.stream);
});
client.current.on("stream-removed", ({ stream }) => {
console.log(String(stream.getId()));
stream.close();
});
client.current.on("peer-online", (evt) => {
console.log("peer-online", evt.uid);
});
client.current.on("peer-leave", (evt) => {
var uid = evt.uid;
var reason = evt.reason;
console.log("remote user left ", uid, "reason: ", reason);
});
client.current.on("stream-unpublished", (evt) => {
console.log(evt);
});
};
const createLocalStream = () => {
localStream.current = AgoraRTC.createStream({
audio: true,
video: true,
});
// Initialize the local stream
localStream.current.init(
() => {
// Play the local stream
localStream.current.play("me");
console.log("Local stream played");
// Publish the local stream
client.current.publish(localStream.current, (err) => {
console.log("publish local stream", err);
});
},
(err) => {
console.log(err);
}
);
};
const endCall = () => {
localStream.current.close();
client.current.leave(
() => {
console.log("Leave channel successfully");
setAgoraConnection({
...agoraConnection,
callPlaced: false,
});
},
(err) => {
console.log("Leave channel failed");
}
);
};
const handleAudioToggle = () => {
if (agoraConnection.mutedAudio) {
localStream.current.unmuteAudio();
setAgoraConnection({
...agoraConnection,
mutedAudio: false,
});
} else {
localStream.current.muteAudio();
setAgoraConnection({
...agoraConnection,
mutedAudio: true,
});
}
};
const handleVideoToggle = () => {
if (agoraConnection.mutedVideo) {
localStream.current.unmuteVideo();
setAgoraConnection({
...agoraConnection,
mutedVideo: false,
});
} else {
localStream.current.muteVideo();
setAgoraConnection({
...agoraConnection,
mutedVideo: true,
});
}
};
return (
<div className="mt-5">
<div>
<button
type="button"
className="btn btn-primary"
onClick={() => placeCall(4, 4)}
>
Call
</button>
</div>
{agoraConnection.incomingCall && (
<div className="row my-5">
<div className="col-12">
<p>
Incoming Call From{" "}
<strong>{agoraConnection.incomingCaller}</strong>
</p>
<div className="btn-group" role="group">
<button
type="button"
className="btn btn-danger"
data-dismiss="modal"
onClick={() => declineCall()}
>
Decline
</button>
<button
type="button"
className="btn btn-success ml-5"
onClick={() => acceptCall()}
>
Accept
</button>
</div>
</div>
</div>
)}
{agoraConnection.callPlaced && (
<section id="video-container">
<div id="me"></div>
<div id="remote-video"></div>
<div className="action-btns">
<button
type="button"
className="btn btn-info"
onClick={() => handleAudioToggle()}
>
{agoraConnection.mutedAudio ? "Unmute" : "Mute"}
</button>
<button
type="button"
className="btn btn-primary mx-4"
onClick={() => handleVideoToggle()}
>
{agoraConnection.mutedVideo ? "ShowVideo" : "HideVideo"}
</button>
<button
type="button"
className="btn btn-danger"
onClick={() => endCall()}
>
EndCall
</button>
</div>
</section>
)}
</div>
);
};
const mapStateToProps = (state) => {
return {
user: state.auth,
};
};
export default connect(mapStateToProps)(VideoCallPage);
After I place a call like I said my web camera starts the place where my local stream should be displayed is shown but without the actual stream:
I really have no other ideas how to fix this.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
在大多数情况下,AgorARTC在两个Divs中插入HTML视频元素(第一div是TrackID,第二个DIV是视频元素包装器),您需要为此元素进行样式,因为它们具有宽度0px&amp; Heigth 0px,检查检查员,您还可以使用从Agora-RTC导入的Agoravideoplayer组件,也需要样式
in the most cases AgoraRTC insert the html video element inside two divs (first div is the trackid, second div is the video element wrapper), you need to style this elements cu'z they have width 0px & heigth 0px, check in the inspector, you can also use the AgoraVideoPlayer component imported from agora-rtc and need style this too