当前位置: 首页 > Web前端 > HTML

网络技术分享-React版anyRTC实例点对点连接

时间:2023-03-28 12:34:27 HTML

前言大家好,笔者过去发表了很多关于WebRTC的知识,以及很多基于anyRTCWebSDK的音视频通信实例,得到了很多人的一致好评开发商。前面的例子,笔者都是基于Vue框架编写的。有后台小伙伴私信作者,希望作者能拿出一个基于React框架的音视频例子。作者一收到私信就开始写了,现发布出来供参考。开发准备在开始编写代码之前,您需要做一些准备工作。如果你之前没有使用过任何RTCWebSDK,这里需要几分钟的准备时间。详见:开发前准备创建一个React程序并全局安装npminstall-gcreate-react-app通过create-react-app项目名下载导入项目依赖(注意:项目名不能大写)create-react-apppeerconnectionnpminstallar-rtc-sdk@4.1.3-S在App.js文件中引入importReact,{Component}from'react';从“ar-rtc-sdk”导入ArRTC;从'../anyrtc_config'导入配置;导入'./App.css';定义初始状态数据exportdefaultclassAppextendsComponent{state={channel:'',isLogin:false,rtcClient:null,videoDevices:null,audioDevices:null,audioTrack:null,videoTrack:null,list:[]}}创建rtcClient对象通过ArRTC.createClient客户端对象。componentDidMount(){this.createRtcClient();}createRtcClient=()=>{constconfig={mode:"rtc",codec:"h264"};constrtcClient=ArRTC.createClient(配置);//状态更新后,开始监听远程用户发布和取消发布音视频this.setState({rtcClient},()=>{this.listenUserPublished();this.listenUserUnpublished();});Videouser-published此回调通知远程用户已发布新的音轨或视频轨。您可以在该回调中订阅并播放远端用户的音视频轨道。有关详细信息,请参阅订阅和RemoteTrack.play。user-unpublishe此回调通知远程用户音频或视频轨道已取消发布。listenUserUnpublished=()=>{const{rtcClient,list}=this.state;rtcClient.on("user-unpublished",async(user,mediaType)=>{if(mediaType==='video'){constindex=list.findIndex(item=>item.uid===user.uid);if(index!==-1){list.splice(index,1);this.setState({list});}}});};listenUserPublished=()=>{const{rtcClient,list}=这个状态;rtcClient.on("user-published",async(user,mediaType)=>{awaitrtcClient.subscribe(user,mediaType);if(mediaType==='video'){list.push(user);this.setState({list},()=>{user.videoTrack.play('distal'+user.uid);});}elseif(mediaType==='audio'){user.audioTrack.play();}});}joinchanneljoin加入频道,该方法允许用户加入通话频道,同一频道内的用户可以互相通话。当调用该方法加入频道时,本地会触发ArRTCClient.on("connection-state-change")回调。通讯场景用户和直播场景主播加入频道后,远端会触发ArRTCClient.on("user-joined")回调。join=()=>{const{rtcClient,channel}=this.state;const{appid,uid}=配置;rtcClient.join(appid,channel,null,uid).then((uid)=>{this.setState({isLogin:true},async()=>{awaitthis.getDevices();awaitthis.createTrack();const{videoTrack,audioTrack}=this.state;videoTrack&&videoTrack.play('local');audioTrack&&rtcClient.publish(audioTrack);videoTrack&&rtcClient.publish(videoTrack);});}).catch(e=>{alert('加入频道失败');});}获取本地摄像头和麦克风并创建音视频轨道getCameras该方法枚举可用的视频输入设备,例如摄像头。调用成功后,SDK会通过MediaDeviceInfo对象返回可用的视频输入设备。getMicrophones此方法枚举可用的音频输入设备,例如麦克风。调用成功后,SDK会通过MediaDeviceInfo对象返回可用的音频输入设备。createMicrophoneAudioTrack从麦克风捕获的音频创建音轨。createCameraVideoTrack从摄像机捕获的视频创建视频轨道。getDevices=async()=>{const[videoDevices,audioDevices]=awaitPromise.all([ArRTC.getCameras(),ArRTC.getMicrophones(),]);this.setState({videoDevices,audioDevices});}createTrack=async()=>{this.setState({audioTrack:awaitArRTC.createMicrophoneAudioTrack()});if(this.state.videoDevices?.length){this.setState({videoTrack:awaitArRTC.createCameraVideoTrack()});}}挂断离开当调用该方法离开频道时,本地会触发ArRTCClient.on("connection-state-change")回调。通讯场景用户和直播场景主播离开频道后,远端会触发ArRTCClient.on("user-left")回调。hangUp=()=>{const{videoTrack,rtcClient}=this.state;videoTrack&&videoTrack.stop();rtcClient.离开();this.setState({channel:'',isLogin:false,videoDevices:null,audioDevices:null,audioTrack:null,videoTrack:null});}获取频道输入框的值channelInputChange=(e)=>{this.setState({channel:e.target.value});}render函数render(){const{isLogin,channel,list}=this.state;返回(anyRTCsamplesPeerconnection

本地用户id为{Config.uid}
{isLogin&&
}{isLogin&&list.map((user)=>{return(
)})}{isLogin&&挂断电话}{!isLogin&&}{!isLogin&&join}查看控制台以查看日志记录。MediaStream对象localStream和RTCPeerConnection对象pc1和pc2在全局范围内,因此您也可以在控制台中检查它们。有关anyRTCWebRTC的更多信息,请参阅anyRTC在GitHub上查看源代码);}CSS#container{边距:0自动0自动;最大宽度:60em;填充:1em1.5em1.3em1.5em;}.title{border-bottom:1pxsolid#ccc;保证金:000.8em0;填充:000.2em0;字体系列:'Roboto',无衬线字体;字体粗细:500;字体大小:2em;white-space:nowrap;}.titlea,.instructionsa{text-decoration:none;右边距:10px;颜色:#1D6EEE;}.titlea:hover{border-bottom:2pxsolid#1D6EEE;}.instructions{margin:0.8em0;字体系列:'Roboto',无衬线字体;颜色:#444;font-weight:300;}.instructions.userId{color:#1D6EEE;}#play容器{显示:flex;align-items:center;}#local,.distal{宽度:400px;高度:220px;右边距:20px;背景色:#222222;}.btn{宽度:70px;顶部边距:10px;行高:26px;文本对齐:居中;颜色:#fff;背景色:#409EFF;边框:无;边界半径:2px;游标:指针;transition:.1s;}.btn:active{transform:translateY(2px);}.channelInput{width:240px;高度:32px;边界半径:4px;边框:1px实心#409EFF;大纲:无;文本缩进:.5rem;margin-right:10px;}.joinBtn{width:80px;行高:34px;文本对齐:居中;颜色:#fff;背景色:#409EFF;边框:无;边界半径:4px;游标:指针;transition:.1s;}.joinBtn:active{transform:translateY(2px);}.joinBtn[disabled]{background-color:#E1E1E2;光标:不允许;}#viewSource{显示:块;保证金:1.3em000;border-top:1pxsolid#999;填充:1em000;颜色:#1D6EEE;字体粗细:300;text-decoration:none;}#viewSource:hover,.instructionsa:hover{text-decoration:underline;}对运行效果和示例代码感兴趣的可以到github下载源码