都是官方文档,仅供我自己巩固
1、准出
- 有个项目 vue(别的项目也行 react啥的)
- 注册声网,在控制台创建个应用获取 appID(必须)
2、开始创建
- 这段代码是视频的时候,会将视频插入的dom,可以把这段dom放到你要视频的页面中;
- videoIdList 这个变量是我自己定义的,主要是存放远端视频(别人的视频)的id
- local_stream 这个元素id是我要插入本地视频的地方,也可以叫别的名字;(下面会讲)
- remote_video_ + 远端视频id ,这个元素id是我要插入远端视频的地方,也可以叫别的名字;(下面会讲)
- 注意 这两个最好包在一个id为video的元素下 不然总会插入到别的地方 (我也不会调 哈哈哈哈)*
<div id='video' :style="{height:'100%',width:'100%'}"> <div class="video-view review-right-video"> <div id="local_stream" :style="{height:'100%',width:'100%'}"></div> // 本地的视频会插入到这个ID下 <div id="local_video_info" class="video-profile hide"></div> <div id="video_autoplay_local" class="autoplay-fallback hide"></div> </div> <div v-for="item in videoIdList" :key="item" :id="`remote_video_panel_`+item" // 远端的视频会插入到这个id 下 :class="['video-view review-center-video',imageUrl ? 'active' : '']" > <div :style="{height:'100%',width:'100%'}" :id="`remote_video_`+item" ></div> <div :id="`remote_video_info_`+item" class="video-profile hide"></div> <div :id="`video_autoplay_`+item" class="autoplay-fallback hide"></div> </div> </div>
3、对接声网
-
安装
-
npm install agora-rtc-sdk; -
也可以使用CDN
-
CDN
<script src="https://cdn.agora.io/sdk/release/AgoraRTCSDK-3.0.0.js"></script>; -
引入
-
import AgoraRTC from 'agora-rtc-sdk';
4、整个声网的文件
*
*
*
- 完整的代码在最下面,直接看代码就行
- 我建了一个文件 叫 agoraRTCfunct(都是网易翻译来的)
1.引入 sdkimport AgoraRTC from 'agora-rtc-sdk';
2.设置两个参数变量
主要的就是appID
频道是自己定义的,就像设置一个房间,别人会根据你的频道号加入到你的视频当中
const rtc = {
client: null,
joined: false, //是否已经加入频道
published: false, // 是否已经发布
localStream: null,
remoteStreams: [],
params: {}
};
const option = {
appID: "f3e69727bee94580be65eb6193a72b89",
channel: "123", // 频道
uid: 1123, // 用户id
token: "" // 手机app上用的 没用
};
3.开始声网
- 开始监听的代码在下面 , 监听视频过程中的很多事件
- 创建本地流的代码也在下面
- 主要是创建了一个频道,
- 初始化一个频道
- 加入到这个频道
- 在页面中引入 import agora from ‘./agoraRTCfunct.js’; 创建的这个文件*
- thet是vue页面的this,我在页面初始化(mounted)的时候调用了 agora.agoraFunction(this); 传入了this*
- 因为有用户加入的时候会用到
const agoraFunction = function(thet){ if(rtc.joined){ Notification.info("您已经加入频道"); return; }; // 创建客户端 rtc.client = AgoraRTC.createClient({mode: "live", codec: "vp8"}); rtc.params = {mode:'live', codec: 'vp8'}; // 赋值输入框的值 Listening(thet); // 开始监听 // 初始化 rtc.client.init(option.appID, function () { console.log("初始化成功"); //加入频道 rtc.client.join(option.token ? option.token : null, option.channel, option.uid ? +option.uid : null, function (uid) { console.log("成功----频道号码: " + option.channel + "你的id: " + uid); rtc.joined = true; rtc.params.uid = uid; // 获取到自己的id createStream(); // 创建本地流 }, function(err) { console.error("加入频道失败", err) }) }, (err) => { console.error(err); }); };
4.创建本地流(就是打开摄像头能看到自己)
重要的是
- rtc.localStream.play(‘local_stream’); // 插入到这个id中
- local_stream 这个是我自己定义的ID 本地的视频会插入到这个元素中
- 发布本地流是把,本地的视频推到远端 、要不别人看不见
const createStream = function(){ //创建本地流 // 创建本地流 rtc.localStream = AgoraRTC.createStream({ streamID: rtc.params.uid, // 在上一步获取到的自己的视频id audio: true, video: true, screen: false, // 是不是需要共享屏幕 这个只在谷歌浏览器有用 不咋好使 }); // 初始化本地流 rtc.localStream.setVideoProfile("360p_1"); // 640X360 15 400 视频清晰度 rtc.localStream.init(function () { console.log("本地流-初始化-成功",rtc.localStream); // 发布本地流 rtc.localStream.play('local_stream'); // 插入到这个id中 publish(); // 发布本地流 }, function (err) { console.error("本地流-初始化-失败", err); }); } - 发布根底流*
const publish = function () { // 发布本地流 if (!rtc.client) { Notification.info("您还没加入频道"); return; } if (rtc.published) { Notification.info("您已经发布频道"); return; } const oldState = rtc.published; // publish localStream rtc.client.publish(rtc.localStream, function (err) { rtc.published = oldState; console.log("publish failed"); Toast.error("publish failed") console.error(err); }) Notification.success("发布频道成功"); rtc.published = true }
5.监听视频过程中的事件
- 重要的是有别人加入你的视频中的事件(和离开)
- 主要是有用户加入频道的时候,要及时创建一个指定的对方id的元素*
- remoteStream.play(“remote_video_” + id); // 插入到 id为 remote_video_ + id 元素中
- “remote_video_” + id 这个就是我定义的元素, 对方的视频会插入到这里
const Listening = function(thet){ // 订阅事件 // ---- 订阅开始 rtc.client.on("error", (err) => { console.log("===>",err) }); rtc.client.on("peer-leave", function(evt) { // 有用户离开时 var uid = evt.uid; var reason = evt.reason; // 离线原因 Quit -- 主动离开 ServerTimeOut -- 超时掉线(也有可能是主动离开) if (uid != rtc.params.uid) { thet.deleteView(uid); }; Notification.info("用户离开"); console.log("用户离线" , uid, "reason: ", reason); }); rtc.client.on("stream-published", function(evt){ // 发布视频流本地触发 var remoteStream = evt.stream; var id = remoteStream.getId(); thet.myId = id; }); rtc.client.on("stream-added", function (evt) { //有远程流加入时 var remoteStream = evt.stream; var id = remoteStream.getId(); if (id !== rtc.params.uid) { rtc.client.subscribe(remoteStream, function (err) { // 订阅加入的远程端视频 console.log("订阅远程端视频失败", err); }) }; console.log('加入的远程端视频流: ', id); }); rtc.client.on("stream-subscribed", function (evt) { //订阅远程流 var remoteStream = evt.stream; var id = remoteStream.getId(); rtc.remoteStreams.push(remoteStream); // 不知道干啥的 Notification.success("用户加入"+id); thet.addView(id); setTimeout(()=>{ // vue创建元素 是异步的 (一会处理) remoteStream.play("remote_video_" + id); // 插入到 id为 remote_video_ + id 元素中 },300); console.log('接收到的远程端视频: ', id); }); rtc.client.on("stream-removed", function (evt) { // 对方取消发布 var remoteStream = evt.stream; var id = remoteStream.getId(); remoteStream.stop("remote_video_" + id); rtc.remoteStreams = rtc.remoteStreams.filter(function (stream) { return stream.getId() !== id; }) thet.deleteView(id); console.log('stream-removed remote-uid: ', id); }); rtc.client.on("onTokenPrivilegeWillExpire", function(){ // token过期前30秒调用 // client.renewToken(token); console.log("token即将过期") }); rtc.client.on("onTokenPrivilegeDidExpire", function(){ // token已经失效 // client.renewToken(token); console.log("token已经失效"); }); rtc.client.on("network-quality", function(stats) { // 本地用户的网络质量 console.log("下行", callQuality[stats.downlinkNetworkQuality]); console.log("上行", callQuality[stats.uplinkNetworkQuality]); }); rtc.client.on("mute-audio", function(evt) { // 对方关闭了语音 var uid = evt.uid; Notification.info("用户"+uid+"已静音"); console.log("mute audio:" + uid); //alert("mute audio:" + uid); }); rtc.client.on("unmute-audio", function (evt) { // 对方打开了语音 var uid = evt.uid; Notification.info("用户"+uid+"打来了语音"); console.log("unmute audio:" + uid); }); rtc.client.on("mute-video", function (evt) { // 对方关闭摄像头 var uid = evt.uid; Notification.info("用户"+uid+"关闭了摄像头"); console.log("mute video" + uid); //alert("mute video:" + uid); }); rtc.client.on("unmute-video", function (evt) { // 对方打开了摄像头 var uid = evt.uid; Notification.info("用户"+uid+"打开了了摄像头"); console.log("unmute video:" + uid); }); // ---- 订阅结束 }; - 我在监听到有用户加入的时候,把用户的id插入到一个数组里,循环渲染出了有特定id的元素(thet.addView(id);)
- 我在监听到有用户离开的时候,把用户的id从这个数组中去除掉,在循环渲染出了有特定id的元素(thet.deleteView(id);)
addView(id){ if(id == this.myId || this.videoIdList.indexOf(id) != -1) return; const list = this.videoIdList; list.push(id); this.videoIdList = list; }, deleteView(id){ const index = this.videoIdList.indexOf(id); const list = this.videoIdList; list.splice(index,1); this.videoIdList = list; },
其他的就没有比较重要的了
- 导出了这几个方法
export default { rtc, // 参数 option, // 参数 agoraFunction, // 声网开始的方法 创建 初始化 加入频道 publish, // 发布本地流 unpublish, // 停止发布本地流 leave, // 离开频道 getDevices, // 获取可用的 摄像头 麦克风 }; - 完整的代码*
import AgoraRTC from 'agora-rtc-sdk'; import {Notification} from 'element-ui'; const callQuality = { // 通话质量 0:"质量未知", 1:"质量极好", 2:"用户主观感觉和极好差不多,但码率可能略低于极好", 3:"用户主观感受有瑕疵但不影响沟通", 4:"勉强能沟通但不顺畅", 5:"网络质量非常差,基本不能沟通", 6:"网络连接断开,完全无法沟通", } const rtc = { client: null, joined: false, //是否已经加入频道 published: false, // 是否已经发布 localStream: null, remoteStreams: [], params: {} }; const option = { appID: "f3e69727bee94580be65eb6193a72b89", channel: "123", // 频道 uid: 1123, // 用户id token: "" // 手机app上用的 没用 }; const leave = function () { // 离开频道 if (!rtc.client) { Notification.info("您还没加入频道"); return; } if (!rtc.joined) { Notification.info("您还没加入频道(2)"); return; } rtc.client.leave(function () { rtc.localStream.stop(); rtc.localStream.close(); while (rtc.remoteStreams.length > 0) { var stream = rtc.remoteStreams.shift(); var id = stream.getId(); stream.stop(); removeView(id); } rtc.localStream = null; rtc.remoteStreams = []; rtc.client = null; rtc.published = false; rtc.joined = false; Notification.info("离开频道成功"); }, function (err) { Notification.error("离开频道失败"); console.error(err); }) } function unpublish (rtc) { // 取消发布本地流 if (!rtc.client) { Notification.info("您还没加入频道"); return; } if (!rtc.published) { Toast.error("您已经发布频道"); return; } var oldState = rtc.published; rtc.client.unpublish(rtc.localStream, function (err) { rtc.published = oldState; console.error(err); }) Notification.info("取消发布成功"); rtc.published = false; } const createStream = function(){ //创建本地流 // 创建本地流 rtc.localStream = AgoraRTC.createStream({ streamID: rtc.params.uid, audio: true, video: true, screen: false, }); // 初始化本地流 rtc.localStream.setVideoProfile("360p_1"); // 640X360 15 400 rtc.localStream.init(function () { console.log("本地流-初始化-成功",rtc.localStream); // 发布本地流 rtc.localStream.play('local_stream'); // 插入到这个id中 publish(); // 发布本地流 }, function (err) { console.error("本地流-初始化-失败", err); }); } const publish = function () { // 发布本地流 if (!rtc.client) { Notification.info("您还没加入频道"); return; } if (rtc.published) { Notification.info("您已经发布频道"); return; } const oldState = rtc.published; // publish localStream rtc.client.publish(rtc.localStream, function (err) { rtc.published = oldState; console.log("publish failed"); Toast.error("publish failed") console.error(err); }) Notification.success("发布频道成功"); rtc.published = true } const Listening = function(thet){ // 订阅事件 // ---- 订阅开始 rtc.client.on("error", (err) => { console.log("===>",err) }); rtc.client.on("peer-leave", function(evt) { // 有用户离开时 var uid = evt.uid; var reason = evt.reason; // 离线原因 Quit -- 主动离开 ServerTimeOut -- 超时掉线(也有可能是主动离开) if (uid != rtc.params.uid) { thet.deleteView(uid); }; Notification.info("用户离开"); console.log("用户离线" , uid, "reason: ", reason); }); rtc.client.on("stream-published", function(evt){ // 发布视频流本地触发 var remoteStream = evt.stream; var id = remoteStream.getId(); thet.myId = id; }); rtc.client.on("stream-added", function (evt) { //有远程流加入时 var remoteStream = evt.stream; var id = remoteStream.getId(); if (id !== rtc.params.uid) { rtc.client.subscribe(remoteStream, function (err) { // 订阅加入的远程端视频 console.log("订阅远程端视频失败", err); }) }; console.log('加入的远程端视频流: ', id); }); rtc.client.on("stream-subscribed", function (evt) { //订阅远程流 var remoteStream = evt.stream; var id = remoteStream.getId(); rtc.remoteStreams.push(remoteStream); // 不知道干啥的 Notification.success("用户加入"+id); thet.addView(id); setTimeout(()=>{ // vue创建元素 是异步的 (一会处理) remoteStream.play("remote_video_" + id); // 插入到 id为 remote_video_ + id 元素中 },300); console.log('接收到的远程端视频: ', id); }); rtc.client.on("stream-removed", function (evt) { // 对方取消发布 var remoteStream = evt.stream; var id = remoteStream.getId(); remoteStream.stop("remote_video_" + id); rtc.remoteStreams = rtc.remoteStreams.filter(function (stream) { return stream.getId() !== id; }) thet.deleteView(id); console.log('stream-removed remote-uid: ', id); }); rtc.client.on("onTokenPrivilegeWillExpire", function(){ // token过期前30秒调用 // client.renewToken(token); console.log("token即将过期") }); rtc.client.on("onTokenPrivilegeDidExpire", function(){ // token已经失效 // client.renewToken(token); console.log("token已经失效"); }); rtc.client.on("network-quality", function(stats) { // 本地用户的网络质量 console.log("下行", callQuality[stats.downlinkNetworkQuality]); console.log("上行", callQuality[stats.uplinkNetworkQuality]); }); rtc.client.on("mute-audio", function(evt) { // 对方关闭了语音 var uid = evt.uid; Notification.info("用户"+uid+"已静音"); console.log("mute audio:" + uid); //alert("mute audio:" + uid); }); rtc.client.on("unmute-audio", function (evt) { // 对方打开了语音 var uid = evt.uid; Notification.info("用户"+uid+"打来了语音"); console.log("unmute audio:" + uid); }); rtc.client.on("mute-video", function (evt) { // 对方关闭摄像头 var uid = evt.uid; Notification.info("用户"+uid+"关闭了摄像头"); console.log("mute video" + uid); //alert("mute video:" + uid); }); rtc.client.on("unmute-video", function (evt) { // 对方打开了摄像头 var uid = evt.uid; Notification.info("用户"+uid+"打开了了摄像头"); console.log("unmute video:" + uid); }); // ---- 订阅结束 }; // 开始声网 const agoraFunction = function(thet){ // 创建客户端 if(rtc.joined){ Notification.info("您已经加入频道"); return; }; rtc.client = AgoraRTC.createClient({mode: "live", codec: "vp8"}); rtc.params = {mode:'live', codec: 'vp8'}; // 赋值输入框的值 Listening(thet); // 开始监听 // 初始化 rtc.client.init(option.appID, function () { console.log("初始化成功"); //加入频道 rtc.client.join(option.token ? option.token : null, option.channel, option.uid ? +option.uid : null, function (uid) { console.log("成功----频道号码: " + option.channel + "你的id: " + uid); rtc.joined = true; rtc.params.uid = uid; createStream(); // 创建本地流 }, function(err) { console.error("加入频道失败", err) }) }, (err) => { console.error(err); }); }; const getDevices = function (next) { // 获取音视频设备信息 AgoraRTC.getDevices(function (items) { items.filter(function (item) { return ['audioinput', 'videoinput'].indexOf(item.kind) !== -1 }).map(function (item) { return { name: item.label, value: item.deviceId, kind: item.kind, } }); var videos = []; var audios = []; for (var i = 0; i < items.length; i++) { var item = items[i]; if ('videoinput' == item.kind) { var name = item.label; var value = item.deviceId; if (!name) { name = "camera-" + videos.length; } videos.push({ name: name, value: value, kind: item.kind }); } if ('audioinput' == item.kind) { var name = item.label; var value = item.deviceId; if (!name) { name = "microphone-" + audios.length; } audios.push({ name: name, value: value, kind: item.kind }); } } console.log({videos: videos, audios: audios}); // next({videos: videos, audios: audios}); }); } export default { rtc, // 参数 option, // 参数 agoraFunction, // 声网开始的方法 publish, // 发布本地流 unpublish, // 停止发布本地流 leave, // 离开频道 getDevices, // 获取可用的 摄像头 麦克风 };
到此结束