AgoraView直播组件

### AgoraView直播组件 #### 使用方法 1、在uniapp插件市场中直接下载插件后解压 2、把解压后的zywork-agora目录拷贝到uniapp项目的nativeplugins目录中 3、打开项目的manifest.json文件,在App原生插件中选择本地插件,勾选zywork声网直播插件 4、在nvue页面中直接使用组件 *主播:* ```js <AgoraView ref="agoraView1" :style="`position: absolute; left: ${(screenWidth - hostWidth) / 2}px; top: 0px;width: ${hostWidth}px; height: ${hostHeight}px;`" @onJoinChannelSuccess="onJoinChannelSuccess" @onLeaveChannel="onLeaveChannel" @onRemoteVideoStateChanged="onRemoteVideoStateChanged" @onUserJoined="onUserJoined" @onUserOffline="onUserOffline"></AgoraView> ``` *上麦嘉宾:* ```js <AgoraView ref="agoraView2" :style="`position: absolute; left: 0px; top: ${hostHeight + 2}px; width: ${guestWidth}px; height: ${guestHeight}px;`" @onJoinChannelSuccess="onJoinChannelSuccess" @onLeaveChannel="onLeaveChannel" @onRemoteVideoStateChanged="onRemoteVideoStateChanged"></AgoraView> ``` 5、相关接口调用示例 ```js /** * 主播开启直播间 */ export const openLive = (self) => { self.isHost1 = true let agoraView = self.$refs.agoraView1 agoraView.create({appid: AGORA_APPID}) if (self.houseType.onlyAudio) { // 如果只要语音,则关闭视频模块 agoraView.disableVideo(res => {}) } else { agoraView.enableVideo(res => {}) } agoraView.setEnableSpeakerphone({enableSpeaker: true}, res => {}) if (self.houseType.onlyAudio) { // 声音检测 agoraView.enableAudioVolumeIndication({interval: 300, smooth: 3, reportVad: true}) } agoraView.setVideoEncoderConfiguration({width: self.houseType.width, height: self.houseType.height}, res => {}) agoraView.setClientRole(1, res => {}) if (!self.houseType.onlyAudio) { // 是否启用视频 agoraView.setupLocalVideo({channelName: self.liveChannelId, uid: self.hostInfo.userId}, res => {}) agoraView.setBeautyEffectOptions({ enabled: true, contrastLevel: CONTRAST_LEVEL, lightening: LIGHTENING, smoothness: SMOOTHNESS, redness: REDNESS }) agoraView.startPreview(res => {}) } // 获取rtc token后加入直播频道 doGet('/agora-token/rtc/' + self.liveChannelId + '/' + self.hostInfo.userId, {}, {}, true).then(response => { let [err, res] = response if (res.data.code === ResponseStatus.OK) { agoraView.joinChannel({ token: res.data.data, channelName: self.liveChannelId, uid: self.hostInfo.userId, }, res => {}) } }).catch(error => { }) } ``` 6、所有接口都可以参考声网官方的API文档[Agora Android V3.1.2](https://docs.agora.io/cn/Interactive%20Broadcast/API%20Reference/java/index.html) #### 注意事项 1、在同一个nvue页面中可以使用多个AgoraView组件,每一个AgoraView表示一个主播(上麦嘉宾)端,如直播5人间,则有5个AgoraView组件。 2、每个AgoraView都需要指定不同的ref属性; 3、每个AgoraView都使用`absolute`或`fixed`定位方式,具体的定位值,宽高等可自定义; 4、在开启房间的主播端需要监听更多的事件,而在上麦嘉宾端有些事件并不需要监听; 5、在AgoraView组件中,不要使用`v-if`的方式来动态渲染组件,可以使用图片遮盖或动态修改定位值的方式来显示与隐藏AgoraView组件; 6、AgoraView的宽高比需要与视频采集分享率的宽高比一致(后面会有详细说明)。 #### 接口说明 **create,创建RtcEngine实例** ```js create({ appid: AGORA_APPID }, res => {}) ``` 返回结果: ```js { code: 0 | 1, message: 'RtcEngine create成功' | 'RtcEngine create失败' } ``` **enableVideo,开启视频模块** ```js enableVideo(res => {}) ``` 返回结果: ```js { code: 0 | 负数, message: 'enableVideo成功' | 'enableVideo失败' } ``` **disableVideo,关闭视频模块** ```js disableVideo(res => {}) ``` 返回结果: ```js { code: 0 | 负数, message: 'disableVideo成功' | 'disableVideo失败' } ``` **enableAudio,开启音频模块** ```js enableAudio(res => {}) ``` 返回结果: ```js { code: 0 | 负数, message: 'enableAudio成功' | 'enableAudio失败' } ``` **disableAudio,关闭音频模块** ```js disableAudio(res => {}) ``` 返回结果: ```js { code: 0 | 负数, message: 'disableAudio成功' | 'disableAudio失败' } ``` **setEnableSpeakerphone,设置是否启用扬声器** ```js setEnableSpeakerphone({ enableSpeaker: true | false // 是否启用扬声器 }, res => {}) ``` 返回结果: ```js { code: 0 | 负数, message: 'setEnableSpeakerphone成功' | 'setEnableSpeakerphone失败' } ``` **setVideoEncoderConfiguration,设置视频编码配置,主要设置视频采集分辨率的宽高** ```js setVideoEncoderConfiguration({ width: 360, // 视频采集分辨率的宽 height: 640 // 视频采集分辨率的高 }, res => {}) ``` 返回结果: ```js { code: 0 | 负数, message: 'setVideoEncoderConfiguration成功' | 'setVideoEncoderConfiguration失败' } ``` *注意:视频采集分辨率的宽高比与单个直播视频窗口的宽高比要保持一致,否则会出现视频拉伸的情况。* **setClientRole,设置加入频道的用户类型** ```js setClientRole(1 | 2, res => {}) // 1表示主播,2表示观众 ``` 返回结果: ```js { code: 0 | 负数, message: 'setClientRole成功' | 'setClientRole失败' } ``` **setupLocalVideo,设置本地视频** ```js setupLocalVideo({ channelName: 'demoChannel1', // 频道名称 uid: 1001 // 用户编号,int型 }, res => {}) ``` 返回结果: ```js { code: 0 | 负数, message: 'setupLocalVideo成功' | 'setupLocalVideo失败' } ``` **setLocalRenderMode,设置本地视频渲染模式** ```js setLocalRenderMode({ renderMode: 2, // 本地视图渲染模式 mirrorMode: 0 // 本地视图的镜像模式 }, res => {}) ``` 返回结果: ```js { code: 0 | 负数, message: 'setLocalRenderMode成功' | 'setLocalRenderMode失败' } ``` *注意:详细参数说明请参考声网官方API文档[setLocalRenderMode](https://docs.agora.io/cn/Interactive%20Broadcast/API%20Reference/java/classio_1_1agora_1_1rtc_1_1_rtc_engine.html#a8978be2e06307e632abee88c4824b8f6)* **setupRemoteVideo,设置远端视频** ```js setupRemoteVideo({ channelName: 'demoChannel1', // 频道名称 uid: 1001 // 用户编号,int型 }, res => {}) ``` 返回结果: ```js { code: 0 | 负数, message: 'setupRemoteVideo成功' | 'setupRemoteVideo失败' } ``` **setRemoteRenderMode,设置远端视频渲染模式** ```js setRemoteRenderMode({ renderMode: 2, // 远端用户视图渲染模式 mirrorMode: 0 // 远端用户视图的镜像模式 }, res => {}) ``` 返回结果: ```js { code: 0 | 负数, message: 'setRemoteRenderMode成功' | 'setRemoteRenderMode失败' } ``` *注意:详细参数说明请参考声网官方API文档[setRemoteRenderMode](https://docs.agora.io/cn/Interactive%20Broadcast/API%20Reference/java/classio_1_1agora_1_1rtc_1_1_rtc_engine.html#ad3e02c615451858e16f50c05b294307c)* **startPreview,开始视频预览** ```js startPreview(res => {}) ``` 返回结果: ```js { code: 0 | 负数, message: 'startPreview成功' | 'startPreview失败' } ``` **stopPreview,停止视频预览** ```js stopPreview(res => {}) ``` 返回结果: ```js { code: 0 | 负数, message: 'stopPreview成功' | 'stopPreview失败' } ``` **setBeautyEffectOptions,设置是否启用美颜和美颜参数** ```js setBeautyEffectOptions({ enabled: true | false, // 是否启用美颜功能 contrastLevel: 1, // 亮度明暗对比度 lightening: 0.7, // 亮度,取值范围为 [0.0, 1.0],其中 0.0 表示原始亮度,默认值为 0.7。可用来实现美白等视觉效果 smoothness: 0.5, // 平滑度,取值范围为 [0.0, 1.0],其中 0.0 表示原始平滑等级,默认值为 0.5。可用来实现祛痘、磨皮等视觉效果 redness: 0.1 // 红色度,取值范围为 [0.0, 1.0],其中 0.0 表示原始红色度,默认值为 0.1。可用来实现红润肤色等视觉效果 }, res => {}) ``` 返回结果: ```js { code: 0 | 负数, message: 'setBeautyEffectOptions成功' | 'setBeautyEffectOptions失败' } ``` **joinChannel,加入直播频道** ```js setBeautyEffectOptions({ token: 'token value', // Agora鉴权token,需要在后台生成并返回 channelName: 'demoChannel1', // 频道名 uid: 1001 // 用户编号,int型 }, res => {}) ``` 返回结果: ```js { code: 0 | 负数, message: 'joinChannel成功' | 'joinChannel失败' } ``` joinChannel执行成功将会触发以下回调事件: 1)onJoinChannelSuccess,本地用户成功加入频道回调事件 ```js onJoinChannelSuccess = (e) => { let res = e.detail console.log(res.channelName) // 频道名 console.log(res.uid) // 加入频道的本地用户编号 } ``` *注意:本地用户加入直播频道成功会触发此回调事件* 2)onUserJoined,远端用户成功加入频道回调事件 ```js onUserJoined = (e) => { let res = e.detail console.log(res.uid) // 加入频道的远端用户编号 } ``` *注意:远端用户加入直播频道成功,则在麦上的所有主播(嘉宾)都会触发此回调事件。如A和B已经上麦,C加入成功,则A和B都会触发C加入频道的回调事件,C会触发A加入频道的回调事件,C还会触发B加入频道的回调事件。* 3)onRemoteVideoStateChanged,远端视频状态改变回调事件 ```js onRemoteVideoStateChanged = (e) => { let res = e.detail console.log(res.uid) // 发生视频状态改变的远端用户 ID console.log(res.state) // 远端视频流状态 console.log(res.reason) // 远端视频流状态改变的具体原因 } ``` `e.detail.state === 1`时表示本地用户已接收远端视频首包,此时可以在本地用户端调用`setupRemoteVideo`显示远端用户视频。 *注意:详细的返回结果说明请参考声网官方的API文档[onRemoteVideoStateChanged](https://docs.agora.io/cn/Interactive%20Broadcast/API%20Reference/java/classio_1_1agora_1_1rtc_1_1_i_rtc_engine_event_handler.html#a93ebe88d2544253bf4b13faf34873131)* 4)onRemoteAudioStateChanged,远端音频状态改变回调事件 ```js onRemoteAudioStateChanged = (e) => { let res = e.detail console.log(res.uid) // 发生音频状态改变的远端用户 ID console.log(res.state) // 远端音频流状态 console.log(res.reason) // 远端音频流状态改变的具体原因 } ``` `e.detail.state === 1`时表示本地用户已接收远端音频首包,但此时由于只需要音频,而不需要视频,则不需要本地用户端调用`setupRemoteVideo`显示远端用户视频。 *注意:详细的返回结果说明请参考声网官方的API文档[onRemoteVideoStateChanged](https://docs.agora.io/cn/Interactive%20Broadcast/API%20Reference/java/classio_1_1agora_1_1rtc_1_1_i_rtc_engine_event_handler.html#a24fd6b0d12214f6bc6fa7a9b6235aeff)* **leaveChannel,离开直播频道** ```js leaveChannel(res => {}) ``` 返回结果: ```js { code: 0 | 负数, message: 'leaveChannel成功' | 'leaveChannel失败' } ``` leaveChannel执行成功会触发以下回调事件: 1)onLeaveChannel,本地用户离开直播频道回调事件 ```js onLeaveChannel = (e) => { let res = e.detail console.log(res.totalDuration) // 通话时长 console.log(res.users) // 直播频道内的用户数 } ``` 2)onUserOffline,远端用户离开直播频道回调事件 ```js onUserOffline = (e) => { let res = e.detail console.log(res.uid) // 主播ID console.log(res.reason) // 离线原因 } ``` *注意:离线原因请参考声网官方API文档[onUserOffline](https://docs.agora.io/cn/Interactive%20Broadcast/API%20Reference/java/classio_1_1agora_1_1rtc_1_1_i_rtc_engine_event_handler.html#a9fbb08177fbc8f74d64044a78aea0dda)* **adjustPlaybackSignalVolume,调节本地播放的所有远端用户音量** ```js adjustPlaybackSignalVolume({ volume: 100 // 播放音量,取值范围为 [0, 400] }, res => {}) ``` 返回结果: ```js { code: 0 | 负数, message: 'adjustPlaybackSignalVolume成功' | 'adjustPlaybackSignalVolume失败' } ``` **setLiveTranscoding,设置视频合流参数(多个直播视频流合成一个视频流)** ```js setLiveTranscoding({ audioChannels: 2, audioBitrate: 96, width: self.videoWidth, height: self.videoHeight, videoBitrate: 1200, videoFramerate: 30, backgroundImageUrl: PLAYER_BG, backgroundImageX: 0, backgroundImageY: 0, backgroundImageWidth: self.videoWidth, backgroundImageHeight: self.videoHeight, users: [ { uid: self.hostInfo.userId, x: (self.videoWidth - self.videoHostWidth) / 2, y: 0, width: self.videoHostWidth, height: self.videoHostHeight, zOrder: 1, audioChannel: 0 } ...... ] }, res => {}) ``` 返回结果: ```js { code: 0 | 负数, message: 'setLiveTranscoding成功' | 'setLiveTranscoding失败' } ``` *注意:上面示例代码中的`self.`引用的数据是在nvue页面的data中定义的数据或根据屏幕大小等计算的值。详情请参考[setLiveTranscoding](https://docs.agora.io/cn/Interactive%20Broadcast/API%20Reference/java/classio_1_1agora_1_1rtc_1_1_rtc_engine.html#a3cb9804ae71819038022d7575834b88c), [LiveTranscoding]( https://docs.agora.io/cn/Interactive%20Broadcast/API%20Reference/java/classio_1_1agora_1_1rtc_1_1live_1_1_live_transcoding.html)和[TranscodingUser](https://docs.agora.io/cn/Interactive%20Broadcast/API%20Reference/java/classio_1_1agora_1_1rtc_1_1live_1_1_live_transcoding_1_1_transcoding_user.html)* setLiveTranscoding执行成功会触发以下回调事件: 1)onTranscodingUpdated,合图转码更新回调事件 ```js onTranscodingUpdated= (e) => { let res = e.detail console.log(res.update) // true,表示transcoding已更新 } ``` **addPublishStreamUrl,添加视频推流地址** ```js addPublishStreamUrl({ url: 'push_address_url', // 推流地址URL,可以使用腾讯云直播生成推流地址 transcodingEnabled: true // 是否开启直播转码,如果是单个主播,不需要开启直播转码 }, res => {}) ``` 返回结果: ```js { code: 0 | 负数, message: 'addPublishStreamUrl成功' | 'addPublishStreamUrl失败' } ``` *注意:如果需要推流到多个地址,可多次调用。* **removePublishStreamUrl,删除视频推流地址** ```js removePublishStreamUrl({ url: 'push_address_url', // 推流地址URL,请替换成实际的推流地址 }, res => {}) ``` 返回结果: ```js { code: 0 | 负数, message: 'removePublishStreamUrl成功' | 'removePublishStreamUrl失败' } ``` *注意:如果删除多个推流地址,可多次调用。* **enableAudioVolumeIndication,启用说话者音量提示** ```js enableAudioVolumeIndication({ interval: 300, // 指定音量提示的时间间隔 smooth: 3, // 平滑系数,指定音量提示的灵敏度。取值范围为 [0, 10],建议值为 3 reportVad: true // 是否开启人声检测 }, res => {}) ``` 返回结果: ```js { code: 0 | 负数, message: 'enableAudioVolumeIndication成功' | 'enableAudioVolumeIndication失败' } ``` 后续触发的回调事件: 1)onAudioVolumeIndication,提示频道内谁正在说话及说话者音量的回调事件 ```js onAudioVolumeIndication= (e) => { let res = e.detail console.log(res) // 每个说话者的用户 ID 和音量信息 } ``` 本地用户: ```js res = { '0': 1, // 本地用户在说话 } ``` 远端用户: ```js res = { '1001': 0, '1002': 0 } ``` 注意:详情请参考声网官方API文档[onAudioVolumeIndication](https://docs.agora.io/cn/Interactive%20Broadcast/API%20Reference/java/classio_1_1agora_1_1rtc_1_1_i_rtc_engine_event_handler.html#a4d37f2b4d569fa787bb8c0e3ae8cd424) 2)onActiveSpeaker,监测到最活跃用户回调事件 ```js onActiveSpeaker= (e) => { let res = e.detail console.log(res.uid) // 远端最活跃用户的编号 } ``` **renewToken,更新Token** ```js renewToken({ token: 'new rtc token' // 声网鉴权Token,后台动态生成 }, res => {}) ``` 返回结果: ```js { code: 0 | 负数, message: 'renewToken成功' | 'renewToken失败' } ``` **getConnectionState,获取网络连接状态** ```js getConnectionState(res => {}) ``` 返回结果: ```js { connectionState: 1 | 2 | 3 | 4 | 5 } ``` 注意:返回结果详情请参考声网官方API文档[getConnectionState](https://docs.agora.io/cn/Interactive%20Broadcast/API%20Reference/java/classio_1_1agora_1_1rtc_1_1_rtc_engine.html#a8635e3c9e26ffe95e7ab9a518af533b9) **startAudioMixing,开始混音** ```js startAudioMixing({ filePath: '/storage/test.mp3', // 指定需要混音的本地或在线音频文件的绝对路径(包含文件名后缀) loopback: false, replace: false, cycle: 1 // 音频文件循环播放的次数 }, res => {}) ``` 返回结果: ```js { code: 0 | 负数, message: 'startAudioMixing成功' | 'startAudioMixing失败' } ``` 注意:详细参数请参考声网官方API文档[startAudioMixing](https://docs.agora.io/cn/Interactive%20Broadcast/API%20Reference/java/classio_1_1agora_1_1rtc_1_1_rtc_engine.html#ac56ceea1a143a4898382bce10b04df09) **setDefaultAudioRoutetoSpeakerphone,设置是否默认使用扬声器** ```js setDefaultAudioRoutetoSpeakerphone({ defaultSpeaker: true // 是否默认从扬声器播放音频 }, res => {}) ``` 返回结果: ```js { code: 0 | 负数, message: 'setDefaultAudioRoutetoSpeakerphone成功' | 'setDefaultAudioRoutetoSpeakerphone失败' } ``` **isSpeakerphoneEnabled,判断扬声器是否启用** ```js isSpeakerphoneEnabled(res => {}) ``` 返回结果: ```js { code: 0 | -1, message: '扬声器已启用' | '扬声器已禁用' } ``` **startChannelMediaRelay,开始跨频道媒体流转发,可用于跨频道主播PK** ```js startChannelMediaRelay({ srcChannelName: 'demoChannel1', // 源频道名 srcToken: 'rtc token', // 源频道使用的声网鉴权Token destChannelName: 'demoChannel2', // 目标频道 destToken: 'rtc token', // 目标频道使用的声网鉴权Token uid: 1002 // 用户编号 }, res => {}) ``` 返回结果: ```js { code: 0 | 负数, message: 'startChannelMediaRelay成功' | 'startChannelMediaRelay失败' } ``` **跨频道PK,两个频道的主播都需要调用此接口。** *注意:更多详情请参考声网官方API文档[startChannelMediaRelay](https://docs.agora.io/cn/Interactive%20Broadcast/API%20Reference/java/classio_1_1agora_1_1rtc_1_1video_1_1_channel_media_relay_configuration.html)* 成功调用后会触发以下回调事件: 1)onChannelMediaRelayStateChanged,跨频道媒体流状态改变回调事件 ```js onChannelMediaRelayStateChanged= (e) => { let res = e.detail console.log(res.code) // 跨频道媒体流转发出错的错误码 console.log(res.state) // 跨频道媒体流转发状态 } ``` *注意:详情请参考声网官方API文档[onChannelMediaRelayStateChanged](https://docs.agora.io/cn/Interactive%20Broadcast/API%20Reference/java/classio_1_1agora_1_1rtc_1_1_i_rtc_engine_event_handler.html#a89fd95b3536e8e6afd5f001926162f66)* 2)onChannelMediaRelayEvent,跨频道媒体流转发事件 ```js onChannelMediaRelayEvent= (e) => { let res = e.detail console.log(res.code) // 跨频道媒体流转发事件码 } ``` *注意:详情请参考声网官方API文档[onChannelMediaRelayEvent](https://docs.agora.io/cn/Interactive%20Broadcast/API%20Reference/java/classio_1_1agora_1_1rtc_1_1_i_rtc_engine_event_handler.html#a6fe2367e9ea61e48a4cc3b373d198b54)* **stopChannelMediaRelay,停止跨频道视频直播** ```js stopChannelMediaRelay(res => {}) ``` 返回结果: ```js { code: 0 | 负数, message: 'stopChannelMediaRelay成功' | 'stopChannelMediaRelay失败' } ``` **destroy,销毁RtcEngine实例** ```js destroy() ``` 其他事件: **onTokenPrivilegeWillExpire,Token即将过期回调事件** ```js onTokenPrivilegeWillExpire= (e) => { let res = e.detail console.log(res.token) // 即将过期的Token值 } ``` **onConnectionStateChanged,连接状态改变回调事件** ```js onConnectionStateChanged= (e) => { let res = e.detail console.log(res.state) // console.log(res.reason) // } ``` 注意:详情请参考声网官方API[onConnectionStateChanged](https://docs.agora.io/cn/Interactive%20Broadcast/API%20Reference/java/classio_1_1agora_1_1rtc_1_1_i_rtc_engine_event_handler.html#a31b2974a574ec45e62bb768e17d1f49e) **onConnectionLost,连接丢失回调事件** ```js onConnectionLost= (e) => { let res = e.detail console.log(res.connectionLost) // 是否丢失连接 } ```