官方文档地址:AgoraRtc Vue文档
创建项目
使用@vue/cli 脚手架工具 (opens new window)创建一个 Vue 2 版本的项目。
组件库对vue版本的要求是"^2.6.12"
vue create agora-demo
cd ./agora-demo
安装组件库
yarn add agora-rtc-sdk-ng
yarn add agora-rtc-vue
引入组件库
按照引入组件库的指引引入组件库。
打开main.js,修改为以下代码:
import Vue from "vue";
import App from "./App.vue";
import AgoraRtcVue from "agora-rtc-vue";
import "agora-rtc-vue/lib/agora-rtc-vue.css";
Vue.use(AgoraRtcVue,{
appid: "/** Your appid */",
token: "/** Your token */"
});
new Vue({
render: h => h(App),
router
}).$mount("#app");
创建组件
打开app.vue,将app.js修改为如下内容:
<template>
<div>
<agora :channel="channel">
<agora-audio-sender />
<agora-audio-receiver />
<agora-video-receiver />
<agora-video-sender />
</agora>
</div>
</template>
<script>
export default {
name: "App",
data() {
return {
channel: "123111"
};
}
};
</script>
启动项目
在项目根目录中输入以下命令:
yarn serve --https
AgoraRtc 组件
AgoraRtc 组件创建一个通话所需要的基础环境。
AgoraRtc 组件具备丰富的参数控制功能,它的参数设置具备很大的弹性。
最简单的情况下,它只需要传入一个频道名称 channel 即可加入对应频道并具备组件内已实现的丰富的功能。
基础用法
const template = `
<div>
<agora :appid="appid" :channel="channel" :token="token">
<agora-audio-sender/>
<agora-audio-receiver/>
<agora-video-sender/>
<agora-video-receiver/>
</agora>
</div>
`;
const data = {
appid: localStorage.getItem("appid"),
channel: "agora_rtc_vue_special_channel",
token: null
};
const demoObj = {
template,
data: () => data
};
const DEMO = Vue.component("AgoraDemo", demoObj);
new Vue({
el: "#agora-app",
components: { DEMO }
});
clientConfig
clientConfig 指定client创建时的参数。
直播与通信模式的选择
- 设置为直播模式:
<template>
<agora :channel="channel" :clientConfig="{ mode: 'live' }"></agora>
</template>
- 设置为通信模式:
<template>
<agora :channel="channel" :clientConfig="{ mode: 'rtc' }"></agora>
</template>
直播与通信模式的选择
仅 mode 为 live 时生效。
直播过程中可以切换 role。
v-bind的clientConfig的role的值被组件所监听,值在改变时,将按照新值自动重新设置角色。
role 默认为 “audience”。
- 设置为听众:
<template>
<agora :channel="channel" :clientConfig="{ mode: 'live', role: 'audience' }"></agora>
</template>
- 设置为主播:
<template>
<agora :channel="channel" :clientConfig="{ mode: 'live', role: 'host' }"></agora>
</template>
视频格式的选择
- 设置为 VP8 格式:
<template>
<agora :channel="channel" :clientConfig="{ codec: 'vp8' }"></agora>
</template>
- 设置为 H264 格式:
<template>
<agora :channel="channel" :clientConfig="{ codec: 'h264' }"></agora>
</template>
手动加入和离开频道
可以通过手动调用组件上的方法 : start() 和 leave() 加入和离开频道。
加入频道
在默认情况下,autoStart 为 true,表示开启组件自动加入频道的功能,此时组件在 mounted 钩子中会自动创建 client 和加入频道,无需手动调用 start() 。
但是如果业务需求不允许自动连通媒体,而是由用户在某个自认为合适的时刻主动发起连接,那么一种可以主动执行这些操作的方法就是必要的了。
start()正是解决这一问题的方法,可以通过调用 start() 发起媒体连接。
1 首先,我们把autoStart置为 false,避免组件自动发起连接
2 在元素绑定的click事件处理函数或者任何合适的地方调用start()
离开频道
在任何情况下,组件 beforeDestroy 钩子被触发时,用户都将会自动离开频道。
但是如果想要在不销毁页面组件的前提下离开频道,例如为了渲染性能考虑,页面组件是放在中的,那么手动控制组件做出相应反应就是必要的了。
可以通过调用 leave() 主动离开频道。
const template = `
<div>
<input type="button" value="Start" @click="start" class="agora-button">
<input type="button" value="Leave" @click="leave" class="agora-button">
<agora
ref="ar"
:autoStart="false"
:appid="appid" :channel="channel" :token="token">
<agora-video-sender/>
<agora-video-receiver/>
</agora>
</div>
`;
const data = {
appid: localStorage.getItem("appid"),
channel: "agora_rtc_vue_special_channel",
token: null
};
const methods = {
start(e) {
this.$refs.ar.start();
},
leave(e) {
this.$refs.ar.leave();
}
};
const demoObj = {
template,
data: () => data,
methods
};
const DEMO = Vue.component("AgoraDemo", demoObj);
new Vue({
el: "#agora-app",
components: { DEMO }
});
错误处理函数 DEMO
errorHandler接受三个参数:error, vm, info。
error是错误对象,vm是出错时的 vue component 对象, info 是 Vue 特定的错误信息,比如错误所在的生命周期钩子。
errorHandler的返回值决定了是否将该错误传递给上级父组件,并触发父组件的errorCaptured钩子函数,
const template = `
<div>
<agora
:errorHandler="errorHandler"
:appid="appid" :channel="channel" :token="token">
<agora-video-sender/>
<agora-video-receiver/>
</agora>
</div>
`;
const data = {
/***
*
* Obviously we will catch an error that the appid is empty.
*
*/
// appid: localStorage.getItem("appid"),
appid: "",
channel: "agora_rtc_vue_special_channel",
token: null,
/*
*
* Define this method to handle our custom error handling behavior.
*/
errorHandler: (e, vm, info) => {
const message = `${e.message} , ${vm.$options.name} , ${info}`;
alert(message);
return false;
}
};
const demoObj = {
template,
data: () => data
};
const DEMO = Vue.component("AgoraDemo", demoObj);
new Vue({
el: "#agora-app",
components: { DEMO }
});
AudioSender
音频的类型
AudioSender 有三种类型:
microphone : 创建音源来自麦克风的音频
buffer : 创建音源来自音频文件或者 AudioBuffer 对象的音频
custom : 创建音源来自自定义的 MediaStreamTrack (opens new window)的音频
当不指定 AudioSender 的 type 属性时,默认为 type=“microphone”。
`microphone`
<agora>
<agora-audio-sender type="microphone" :config="config"/>
</agora>
import { MicrophoneAudioTrackInitConfig } from "agora-rtc-sdk-ng";
const config: MicrophoneAudioTrackInitConfig = {};
`buffer`
<agora>
<agora-audio-sender type="buffer" :config="config"/>
</agora>
import { BufferSourceAudioTrackInitConfig } from "agora-rtc-sdk-ng";
const config: BufferSourceAudioTrackInitConfig = {
source: new File()
};
`custom`
<agora>
<agora-audio-sender type="custom" :config="config"/>
</agora>
import { CustomAudioTrackInitConfig } from "agora-rtc-sdk-ng";
const config: CustomAudioTrackInitConfig = {
mediaStreamTrack: new MediaStream().getAudioTracks()[0]
};
本地播放
可以控制 prop monitor 的值来控制是否本地播放音频。 monitor 为 true,开启本地播放;为 false 关闭本地播放。
monitor 默认为 false, 即默认为本地不播放。
monitor 被组件监听,值改变时立即生效,组件将自动切换播放状态。
状态改变成功后将触发 audio-sender-track-play-status-change,并可接收到一个布尔值 data。
<agora :channel="channel">
<agora-audio-sender
:monitor="monitor"
@audio-sender-track-play-status-change="handleChange"/>
</agora>
<input type="button" value="switch monitor" @click="switchMonitor" />
export default {
data() {
return {
monitor: true
};
},
methods: {
handleChange(data: boolean): void {
if (data) {
console.log("start monitor success");
} else {
console.log("start monitor failure");
}
},
switchMonitor(): void {
this.monitor = !this.monitor;
}
}
};
音量
可以控制 prop volume 的值来控制音量的大小。 volume 接受 number 类型的值,范围为 [0, 1000]。
0 代表静音, 100 代表原始音量。
volume 被组件监听,值改变时立即生效,组件将自动切换音量的大小。
volume 默认值为 50。
volume 同时影响本地和远端听到的音量。例如设置 volume 为0,则本地和远端都听不到声音。
<agora :channel="channel">
<agora-audio-sender :volume="volume"/>
</agora>
<input type="button" value="switch volume" @click="switchVolume" />
export default {
data() {
return {
volume: 0
};
},
methods: {
switchMonitor(): void {
this.volume += 50;
}
}
};
向远端发送音频
音乐播放器Demo
const template = `
<div>
<agora :appid="appid" :channel="channel" :token="token">
<agora-audio-sender
ref="audio_sender"
type="buffer"
monitor
:config="config"
:volume="volume"
@track-created="handleTrackCreated">
<template>
<div class="player">
<div class="row source-control">
<span class="button select" @click="selectFile"></span>
<span class="button reload" @click="reload"></span>
<span class="button mute" @click="()=>{volume = 0;}"></span>
<span class="button sound" @click="() =>{volume = 100;}"></span>
</div>
<div class="row">
<progress
:value="bufferData.currentTime"
:max="bufferData.duration"
></progress>
<span class="time">
{{ bufferData.currentTime | timeFilter }} /
{{ bufferData.duration | timeFilter }}
</span>
</div>
<div class="row play-control">
<span class="button play" @click="resume"></span>
<span class="button left" @click="jump('left')"></span>
<span class="button pause" @click="pause"></span>
<span class="button right" @click="jump('right')"></span>
<span class="button stop" @click="stop"></span>
</div>
</div>
</template>
</agora-audio-sender>
</agora>
<input
ref="fileSelect"
type="file"
accept="audio/*"
style="opacity: 0; position: fixed; left: 200vw;"
@change="handleBufferFileSelect"
/>
</div>
`;
const data = {
appid: localStorage.getItem("appid"),
channel: "agora_rtc_vue_special_channel",
token: null,
volume: 100,
step: 15,
config: {
source: null
},
bufferData: {
currentTime: 0,
duration: 0
},
timer: null
};
const methods = {
selectFile() {
this.$refs.fileSelect.click();
},
handleBufferFileSelect(e) {
this.config.source = e.target.files[0];
this.$refs.audio_sender.start();
},
handleTrackCreated() {
this.clearTimer();
const bufferSender = this.$refs.audio_sender;
this.bufferData.duration = bufferSender.getDuration();
console.log("duration", this.bufferData.duration);
this.bufferData.currentTime = bufferSender.getCurrentTime();
const that = this;
that.$refs.audio_sender.$emit(
"hook:beforeDestroy",
that.clearTimer.call(that)
);
this.timer = setInterval(() => {
that.bufferData.currentTime = bufferSender.getCurrentTime();
}, 1000);
},
reload() {
this.$refs.audio_sender.start();
},
pause() {
this.$refs.audio_sender.pause();
},
resume() {
this.$refs.audio_sender.resume();
},
stop() {
this.$refs.audio_sender.stop();
},
clearTimer() {
if (this.timer !== null) {
clearInterval(this.timer);
}
},
jump(direction) {
if (direction === "left") {
this.$refs.audio_sender.seek(this.bufferData.currentTime - this.step);
} else if (direction === "right") {
this.$refs.audio_sender.seek(this.bufferData.currentTime + this.step);
}
}
};
const formatTime = function formatTime(second) {
return [
parseInt(second / 60 / 60),
parseInt((second / 60) % 60),
parseInt(second % 60)
]
.join(":")
.replace(/\b(\d)\b/g, "0$1");
};
const demoObj = {
template,
data: () => data,
methods,
filters: {
timeFilter(v) {
return formatTime(v);
}
}
};
const DEMO = Vue.component("AgoraDemo", demoObj);
new Vue({
el: "#agora-app",
components: { DEMO }
});
多条音频轨道的处理
<agora>
<agora-audio-sender type="microphone"/>
<agora-audio-sender type="source"/>
</agora>
音频的level
onst AudioLevelBarObj = {
template: `
<div class="audio-level-bar-wrapper">
<div class="tag">{{tag}}</div>
<div class="audio-level-bar" :style="styleObj"></div>
</div>
`,
props: {
tag: { type: String, default: "" },
level: { type: Number, default: 0 }
},
computed: {
styleObj() {
const level = this.level;
const coe = level < 0.1 ? 4 : level < 0.2 ? 3 : level < 0.4 ? 1.5 : 1;
return {
width: 10 + Math.floor(coe * level * 90) + "%"
};
}
}
};
const AudioLevelBar = Vue.component("AudioLevelbar", AudioLevelBarObj);
const template = `
<div class="agora-demo">
<agora :appid="appid" :channel="channel" :token="token" @user-published="handleUserPublished">
<agora-audio-sender ref="audioSender" @track-created="handleTrackCreated"/>
<agora-audio-receiver ref="audioReceiver"/>
</agora>
<audio-level-bar tag="you" :level="audioSenderLevel"/>
<audio-level-bar :tag="'remote '+ obj.uid" v-for="obj in audioReceiverLevelList" :key="obj.uid" :level="obj.result"/>
</div>
`;
const data = {
appid: localStorage.getItem("appid"),
channel: "agora_rtc_vue_special_channel",
token: null,
audioSenderLevel: 0,
audioReceiverLevelList: []
};
const methods = {
handleTrackCreated() {
let id = null;
const audioSender = this.$refs.audioSender;
const cb = () => {
const track = audioSender.getTrack();
this.audioSenderLevel =
track && track.getVolumeLevel ? track.getVolumeLevel() : 0;
id = window.requestAnimationFrame(cb);
};
id = window.requestAnimationFrame(cb);
this.$once("hook:beforeDestroy", () => {
window.cancelAnimationFrame(id);
});
},
handleUserPublished(user, mediaType) {
mediaType === "audio" && this.handleRemoteVolumeLevelList();
},
handleRemoteVolumeLevelList() {
let id = null;
const audioReceiver = this.$refs.audioReceiver;
const cb = () => {
this.audioReceiverLevelList = audioReceiver.getVolumeLevel();
id = window.requestAnimationFrame(cb);
};
id = window.requestAnimationFrame(cb);
this.$once("hook:beforeDestroy", () => {
window.cancelAnimationFrame(id);
});
}
};
const demoObj = {
template,
data: () => data,
components: { AudioLevelBar },
methods
};
const DEMO = Vue.component("AgoraDemo", demoObj);
new Vue({
el: "#agora-app",
components: { DEMO }
});
AudioReceiver
AudioReceiver 是 AgoraRTC 的子组件之一 ,它的主要功能是负责远端音频的接收和播放。
AudioReceiver 会自动处理远端用户发送的音频,开发者可以主动控制的音频播放的音量。
一个 AudioReceiver 组件可以处理所有(所在AgoraRTC组件内的)远端音频,所以无需多次声明。
基础 DEMO
const template = `
<div>
<agora :appid="appid" :channel="channel" :token="token">
<agora-audio-sender/>
<agora-audio-receiver/>
</agora>
</div>
`;
const data = {
appid: localStorage.getItem("appid"),
channel: "agora_rtc_vue_special_channel",
token: null
};
const demoObj = {
template,
data: () => data
};
const DEMO = Vue.component("AgoraDemo", demoObj);
new Vue({
el: "#agora-app",
components: { DEMO }
});
控制音量 DEMO
AudioReceiver可以控制远端音频在本地播放的音量。
AudioReceiver在默认插槽暴露方法,组件本身的方法也可以调用。
控制音量有两个方法:
1 setVolume
2 setVolumeForSomeRemote
区别:
1 setVolume 设置所有远端用户的音量,
2 setVolumeForSomeRemote设置部分远端用户的音量。
`作用域插槽`
<template>
<agora>
<agora-audio-receiver>
<template #default="scope">
<button @click="scope.controller.setVolume(100)">Button</button>
</template>
</agora-audio-receiver>
</agora>
</template>
`方法`
this.$refs.audio_receiver.setVolume(100);
Demo
const template = `
<div>
<agora :appid="appid" :channel="channel" :token="token">
<agora-audio-receiver ref="audio_receiver">
<template v-slot="{controller:{setVolume}}">
<input type="button" value="volume: 100 (slot)" @click="setVolume(100)" class="agora-button plain"/>
<input type="button" value="volume: 600 (slot)" @click="setVolume(600)" class="agora-button plain"/>
</template>
</agora-audio-receiver>
</agora>
<input type="button" value="volume: Mute" @click="$refs.audio_receiver.setVolume(0)" class="agora-button plain"/>
<input type="button" value="volume: Max" @click="$refs.audio_receiver.setVolume(1000)" class="agora-button plain"/>
</div>
`;
const data = {
appid: localStorage.getItem("appid"),
channel: "agora_rtc_vue_special_channel",
token: null
};
const demoObj = {
template,
data: () => data
};
const DEMO = Vue.component("AgoraDemo", demoObj);
new Vue({
el: "#agora-app",
components: { DEMO }
});
VideoSender
视频的类型
VideoSender 有三种类型:
camera : 创建来自摄像头的视频
screen : 创建来自屏幕共享的视频流
custom : 创建视频源来自自定义的 MediaStreamTrack (opens new window)的视频
当不指定 VideoSender 的 type 属性时,默认为 type=“camera”。
视频传输优化
视频传输编码参数
美颜
屏幕共享
自定义播放器
VideoSender提供两种方式设置自定义播放器:
插槽方式指定播放器窗口
指令方式指定播放器窗口
插槽方式指定播放窗口
const template = `
<div>
<agora :appid="appid" :channel="channel" :token="token">
<agora-video-sender>
<div class="player"></div>
</agora-video-sender>
</agora>
</div>
`;
const data = {
appid: localStorage.getItem("appid"),
channel: "agora_rtc_vue_special_channel",
token: null
};
const demoObj = {
template,
data: () => data
};
const DEMO = Vue.component("AgoraDemo", demoObj);
new Vue({
el: "#agora-app",
components: { DEMO }
});
.player{
width 300px
height 300px
border-radius 300px
overflow hidden
filter contrast(200%)
}
指令方式指定播放窗口
const template = `
<div>
<agora :appid="appid" :channel="channel" :token="token">
<agora-video-sender customizationPlayer @video-ready="videoReadyHandler"/>
</agora>
<div v-if="video" v-player="video" class="player"></div>
</div>
`;
const data = {
appid: localStorage.getItem("appid"),
channel: "agora_rtc_vue_special_channel",
token: null,
video: null
};
const methods = {
videoReadyHandler(video) {
this.video = video;
}
};
const demoObj = {
template,
data: () => data,
methods
};
const DEMO = Vue.component("AgoraDemo", demoObj);
new Vue({
el: "#agora-app",
components: { DEMO }
});
VideoReceiver
基础 DEMO
const template = `
<div>
<p>Run this demo in multiple tabs at the same time</p>
<agora :appid="appid" :channel="channel" :token="token">
<agora-video-sender/>
<agora-video-receiver/>
</agora>
</div>
`;
const data = {
appid: localStorage.getItem("appid"),
channel: "agora_rtc_vue_special_channel",
token: null
};
const demoObj = {
template,
data: () => data
};
const DEMO = Vue.component("AgoraDemo", demoObj);
new Vue({
el: "#agora-app",
components: { DEMO }
});
控制播放器的显示窗口
const template = `
<div>
<p>Run this demo in multiple tabs at the same time</p>
<agora :appid="appid" :channel="channel" :token="token">
<agora-video-sender>
<div style="width: 100px; height: 100px; outline: 5px solid blue"></div>
</agora-video-sender>
<agora-video-receiver>
<div class="player"></div>
</agora-video-receiver>
</agora>
</div>
`;
const data = {
appid: localStorage.getItem("appid"),
channel: "agora_rtc_vue_special_channel",
token: null
};
const demoObj = {
template,
data: () => data
};
const DEMO = Vue.component("AgoraDemo", demoObj);
new Vue({
el: "#agora-app",
components: { DEMO }
});
插槽指定 窗口播放
const template = `
<div>
<p>Run this demo in multiple tabs at the same time</p>
<agora :appid="appid" :channel="channel" :token="token">
<agora-video-sender>
<div style="width: 100px; height: 100px; outline: 5px solid blue"></div>
</agora-video-sender>
<agora-video-receiver>
<div class="player"></div>
</agora-video-receiver>
</agora>
</div>
`;
const data = {
appid: localStorage.getItem("appid"),
channel: "agora_rtc_vue_special_channel",
token: null
};
const demoObj = {
template,
data: () => data
};
const DEMO = Vue.component("AgoraDemo", demoObj);
new Vue({
el: "#agora-app",
components: { DEMO }
});
指令指定 窗口播放
const template = `
<div>
<p>Run this demo in multiple tabs at the same time</p>
<agora :appid="appid" :channel="channel" :token="token">
<agora-video-sender>
<div style="width: 100px; height: 100px; outline: 5px solid blue"></div>
</agora-video-sender>
<agora-video-receiver customizationPlayer @video-ready="videoReadyHandler"/>
</agora>
<div class="player-area" v-if="remoteVideoList.length">
<ul v-if="remoteVideoList.length - 1">
<li v-for="u in remoteVideoList.slice(1)" v-player="u" :key="u.uid"></li>
</ul>
<div class="main" v-player="remoteVideoList[0]"></div>
</div>
</div>
`;
const data = {
appid: localStorage.getItem("appid"),
channel: "agora_rtc_vue_special_channel",
token: null,
remoteVideoList: []
};
const methods = {
videoReadyHandler(list) {
this.remoteVideoList = list;
}
};
const demoObj = {
template,
data: () => data,
methods
};
const DEMO = Vue.component("AgoraDemo", demoObj);
new Vue({
el: "#agora-app",
components: { DEMO }
});