第一次提交
This commit is contained in:
550
pagesLive/live/live-part/liveRoom.nvue
Normal file
550
pagesLive/live/live-part/liveRoom.nvue
Normal file
@ -0,0 +1,550 @@
|
||||
<template>
|
||||
<view>
|
||||
<block v-if="is_replay">
|
||||
<view class="video-detail">
|
||||
<video id="myVideo" :src="replay_url" :autoplay="true" :loop="true" :controls="false" :show-fullscreen-btn="false"
|
||||
:show-play-btn="false" :show-center-play-btn="false" object-fit="cover" :style="{height: winHeight, width: winWidth}"
|
||||
@error="videoErrorCallback"></video>
|
||||
</view>
|
||||
</block>
|
||||
<!-- #ifdef APP-PLUS -->
|
||||
<block v-if="role == 'audience' && player_url != ''">
|
||||
<video
|
||||
id="myVideo"
|
||||
:src="player_url"
|
||||
:autoplay="true"
|
||||
:loop="true"
|
||||
:controls="false"
|
||||
:show-fullscreen-btn="false"
|
||||
:show-play-btn="false"
|
||||
:show-center-play-btn="false"
|
||||
:auto-pause-if-navigate="false"
|
||||
:auto-pause-if-open-native="false"
|
||||
object-fit="cover"
|
||||
:style="{height: winHeight, width: winWidth}"
|
||||
></video>
|
||||
</block>
|
||||
<!-- #endif -->
|
||||
<!-- #ifndef APP-PLUS -->
|
||||
<block v-if="role == 'audience' && player_url != ''">
|
||||
<live-player id="livePlayer" :picture-in-picture-mode="picture_mode" :src="player_url" autoplay="true" mode="RTC" object-fit="fillCrop" :style="{height: winHeight, width: winWidth}"
|
||||
></live-player>
|
||||
</block>
|
||||
<!-- #endif -->
|
||||
<block v-if="role == 'broadcaster'">
|
||||
<live-pusher id="livePusher1" ref="livePusher1" class="livePusher" :url="mainPusherInfo_url" mode="RTC"
|
||||
enable-camera="true" enable-mic="true" auto-focus="true" aspect="9:16" objectFit="fill"
|
||||
max-bitrate="500" min-bitrate="200" waiting-image="../../../static/temporarily.jpg" :beauty="beauty" :whiteness="whiteness"
|
||||
:style="{height: winHeight, width: winWidth}" @statechange="recorderStateChange" @netstatus="recorderNetChange"></live-pusher>
|
||||
</block>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
const AgoraMiniappSDK = require("../../lib/mini-app-sdk-production.js");
|
||||
const RTMClient = require('../../lib/agora-rtm.js');
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
RTMClient: null,
|
||||
/*加载中*/
|
||||
loading_login: false,
|
||||
/*推流对象*/
|
||||
pusherContext: null,
|
||||
/*拉流对象*/
|
||||
playerContext: null,
|
||||
player_url: '',
|
||||
mainPusherInfo_url: '',
|
||||
room_id: '',
|
||||
/*发送消息*/
|
||||
TextMsg: '',
|
||||
/*是否打开礼物*/
|
||||
open_gift: false,
|
||||
/*评论*/
|
||||
commentsList: [],
|
||||
/*礼物*/
|
||||
giftList: [],
|
||||
/*是否打开商品列表*/
|
||||
open_products: false,
|
||||
/*当前讲解商品ID*/
|
||||
explain_product_id: '',
|
||||
/*当前讲解商品*/
|
||||
explain_product: null,
|
||||
/*是否显示更多功能*/
|
||||
open_more: false,
|
||||
/*是否美颜*/
|
||||
beauty: 5,
|
||||
/*美白*/
|
||||
whiteness: 5,
|
||||
/*前置后置*/
|
||||
device_position: 'front',
|
||||
/*打开分享*/
|
||||
open_share: false,
|
||||
/*分享参数*/
|
||||
param_share: {},
|
||||
/*分享图片*/
|
||||
qrcode: null,
|
||||
/*获取观看人数*/
|
||||
showNumTimer: null,
|
||||
/*是否点赞*/
|
||||
is_click_digg: false,
|
||||
// 房间详情
|
||||
roomDetail: {},
|
||||
// 用户信息
|
||||
userInfo: {},
|
||||
// RTC房间频道
|
||||
channel: '',
|
||||
// 应用appid
|
||||
appId: '',
|
||||
// rtm客户端
|
||||
rtm_client: null,
|
||||
reconnectTimer: null,
|
||||
// 0 - loading, 1 - ok, 2 - error
|
||||
push_status: 'loading',
|
||||
picture_mode: ["push", "pop"],
|
||||
isCaster: false
|
||||
};
|
||||
},
|
||||
props: ['winHeight', 'winWidth', 'role', 'is_replay', 'replay_url'],
|
||||
methods: {
|
||||
show(){
|
||||
if(this.playerContext!=null){
|
||||
this.playerContext.play();
|
||||
}
|
||||
if(this.pusherContext){
|
||||
this.reconnect();
|
||||
}
|
||||
},
|
||||
/*请求对象*/
|
||||
getRequest(){
|
||||
let self = this;
|
||||
// #ifdef APP-PLUS
|
||||
return getApp().globalData.vueObj;
|
||||
// #endif
|
||||
// #ifndef APP-PLUS
|
||||
return self;
|
||||
// #endif
|
||||
},
|
||||
start(roomDetail, userInfo) {
|
||||
let self = this;
|
||||
self.roomDetail = roomDetail;
|
||||
self.userInfo = userInfo;
|
||||
self.channel = 'channel_' + roomDetail.shop_supplier_id;
|
||||
self.isCaster = self.role == 'broadcaster';
|
||||
if (self.isCaster) {
|
||||
let whiteness = uni.getStorageSync('whiteness');
|
||||
if (whiteness) {
|
||||
self.whiteness = whiteness;
|
||||
}
|
||||
let beauty = uni.getStorageSync('beauty');
|
||||
if (beauty) {
|
||||
self.beauty = beauty;
|
||||
}
|
||||
} else {
|
||||
//观众
|
||||
console.log('观众进入');
|
||||
}
|
||||
self.loginRoom();
|
||||
},
|
||||
/*直播间登录*/
|
||||
loginRoom() {
|
||||
let self = this;
|
||||
uni.showLoading({
|
||||
title: '正在进入'
|
||||
});
|
||||
self.getRequest()._get('plus.live.agora.api/login', {
|
||||
room_id: self.roomDetail.room_id,
|
||||
channel: self.channel,
|
||||
isCaster: self.isCaster
|
||||
}, function(res) {
|
||||
self.appId = res.data.appId;
|
||||
self.initAgoraChannel(res.data.userSign).then(url => {
|
||||
console.log(`pushing ${url}`);
|
||||
let ts = new Date().getTime();
|
||||
self.mainPusherInfo_url = url;
|
||||
if (self.isCaster) {
|
||||
self.pusherContext = uni.createLivePusherContext('livePusher1', self);
|
||||
setTimeout(function() {
|
||||
console.log('创建 pusherContext app:', self.pusherContext);
|
||||
self.pusherContext.start();
|
||||
self.loginIM();
|
||||
}, 500);
|
||||
// 同步数据
|
||||
self.showNumTimer = setInterval(() => {
|
||||
self.synRoomInfo();
|
||||
}, 15000)
|
||||
}
|
||||
}).catch(e => {
|
||||
console.log(`init agora client failed: ${e}`);
|
||||
console.log(JSON.stringify(e));
|
||||
uni.showToast({
|
||||
title: `客户端初始化失败`,
|
||||
icon: 'none',
|
||||
duration: 5000
|
||||
});
|
||||
});
|
||||
});
|
||||
},
|
||||
/**
|
||||
* 初始化sdk推流
|
||||
*/
|
||||
initAgoraChannel: function(token) {
|
||||
let self = this;
|
||||
return new Promise((resolve, reject) => {
|
||||
let client = new AgoraMiniappSDK.Client();
|
||||
//subscribe stream events
|
||||
self.subscribeEvents(client);
|
||||
AgoraMiniappSDK.LOG.onLog = (text) => {
|
||||
// callback to expose sdk logs
|
||||
console.log(text);
|
||||
};
|
||||
// info:1 WARNING:2 ERROR:3 DEBUG:0
|
||||
AgoraMiniappSDK.LOG.setLogLevel(1);
|
||||
self.client = client;
|
||||
client.setRole(self.role);
|
||||
client.init(self.appId, () => {
|
||||
console.log(`client init success`);
|
||||
// pass key instead of undefined if certificate is enabled
|
||||
client.join(token, self.channel, self.getRequest().getUserId(), () => {
|
||||
console.log(`client join channel success`);
|
||||
//and get my stream publish url
|
||||
if (self.isCaster) {
|
||||
client.publish(url => {
|
||||
console.log(`client publish success`);
|
||||
console.log('url=' + url);
|
||||
resolve(url);
|
||||
}, e => {
|
||||
console.log(`client publish failed: ${e.code} ${e.reason}`);
|
||||
reject(e)
|
||||
});
|
||||
} else {
|
||||
resolve();
|
||||
}
|
||||
}, e => {
|
||||
console.log(`: ${e.code} ${e.reason}`);
|
||||
reject(e)
|
||||
})
|
||||
}, e => {
|
||||
console.log(`client init failed: ${e} ${e.code} ${e.reason}`);
|
||||
reject(e);
|
||||
});
|
||||
});
|
||||
},
|
||||
loginIM() {
|
||||
let self = this;
|
||||
self.getRequest()._get('plus.live.agora.api/rtmToken', {
|
||||
channel: self.channel
|
||||
}, function(res) {
|
||||
self.rtm_client = new RTMClient(self.appId);
|
||||
self.onChannelEvent();
|
||||
// sdk连接状态
|
||||
self.rtm_client.on('ConnectionStateChanged', (newState, reason) => {
|
||||
console.log('The connection status', newState)
|
||||
console.log('The reason for the state change', reason)
|
||||
});
|
||||
// 登录 RTM 系统
|
||||
self.rtm_client.login(res.data.userSign, '' + self.getRequest().getUserId()).then(() => {
|
||||
console.log('AgoraRTM client login success');
|
||||
self.rtm_client.joinChannel(self.channel).then(() => {
|
||||
console.log('join channel success');
|
||||
// 发送通知
|
||||
let msg = {
|
||||
type: 'enter',
|
||||
nickName: self.userInfo.nickName
|
||||
};
|
||||
self.sendMsg(JSON.stringify(msg));
|
||||
if(self.isCaster){
|
||||
// 直播开始
|
||||
self.getRequest()._post(
|
||||
'plus.live.room/set_status', {
|
||||
room_id: self.roomDetail.room_id,
|
||||
status: 101
|
||||
},
|
||||
function(res) {
|
||||
// 开始录制
|
||||
self.startRecord();
|
||||
}
|
||||
);
|
||||
}
|
||||
}).catch((err) => {
|
||||
console.log('join channel failed', err)
|
||||
});
|
||||
}).catch(err => {
|
||||
console.log('AgoraRTM client login failure', err);
|
||||
});
|
||||
});
|
||||
},
|
||||
/*获取直播间信息*/
|
||||
synRoomInfo(e){
|
||||
let self = this;
|
||||
self.getRequest()._post(
|
||||
'plus.live.room/syn_room',
|
||||
{
|
||||
room_id: self.roomDetail.room_id,
|
||||
},
|
||||
function(res) {
|
||||
// 发送通知
|
||||
let msg = {
|
||||
type: 'views',
|
||||
views: res.data.model.views,
|
||||
digg_num: res.data.model.digg_num,
|
||||
};
|
||||
self.sendMsg(JSON.stringify(msg));
|
||||
}
|
||||
);
|
||||
},
|
||||
/**
|
||||
* 注册stream事件
|
||||
*/
|
||||
subscribeEvents: function(client) {
|
||||
let self = this;
|
||||
/**
|
||||
* sometimes the video could be rotated
|
||||
* this event will be fired with ratotion
|
||||
* angle so that we can rotate the video
|
||||
* NOTE video only supportes vertical or horizontal
|
||||
* in case of 270 degrees, the video could be
|
||||
* up side down
|
||||
*/
|
||||
client.on("video-rotation", (e) => {
|
||||
console.log(`video rotated: ${e.rotation} ${e.uid}`);
|
||||
});
|
||||
/**
|
||||
* fired when new stream join the channel
|
||||
*/
|
||||
client.on("stream-added", e => {
|
||||
let uid = e.uid;
|
||||
console.log(`stream ${uid} added`);
|
||||
/**
|
||||
* subscribe to get corresponding url
|
||||
*/
|
||||
client.subscribe(uid, (url, rotation) => {
|
||||
console.log(`stream ${uid} subscribed successful`);
|
||||
console.log(url);
|
||||
self.player_url = url;
|
||||
self.loginIM();
|
||||
}, e => {
|
||||
console.log(`stream subscribed failed ${e} ${e.code} ${e.reason}`);
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* remove stream when it leaves the channel
|
||||
*/
|
||||
client.on("stream-removed", e => {
|
||||
let uid = e.uid;
|
||||
console.log(`stream ${uid} removed`);
|
||||
});
|
||||
|
||||
/**
|
||||
* when bad thing happens - we recommend you to do a
|
||||
* full reconnect when meeting such error
|
||||
* it's also recommended to wait for few seconds before
|
||||
* reconnect attempt
|
||||
*/
|
||||
client.on("error", err => {
|
||||
let errObj = err || {};
|
||||
let code = errObj.code || 0;
|
||||
let reason = errObj.reason || "";
|
||||
console.log(`error: ${code}, reason: ${reason}`);
|
||||
if (code === 501 || code === 904) {
|
||||
self.reconnect();
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* there are cases when server require you to update
|
||||
* player url, when receiving such event, update url into
|
||||
* corresponding live-player, REMEMBER to update key property
|
||||
* so that live-player is properly refreshed
|
||||
* NOTE you can ignore such event if it's for pusher or happens before
|
||||
* stream-added
|
||||
*/
|
||||
client.on('update-url', e => {
|
||||
console.log(`update-url: ${JSON.stringify(e)}`);
|
||||
});
|
||||
},
|
||||
onChannelEvent: function() {
|
||||
let self = this;
|
||||
// 频道消息
|
||||
self.rtm_client.on('ChannelMessage', (message, memberId) => {
|
||||
let object = {
|
||||
uid: memberId,
|
||||
message: message.text
|
||||
}
|
||||
console.log('message -----');
|
||||
console.log(message);
|
||||
if (memberId != self.getRequest().getUserId()) {
|
||||
self.$emit('showMsg', message.text);
|
||||
}
|
||||
})
|
||||
//频道成员进出通知
|
||||
self.rtm_client.on('MemberJoined', (memberId) => {
|
||||
console.log('memberId: ', memberId);
|
||||
})
|
||||
self.rtm_client.on('MemberLeft', (memberId) => {
|
||||
console.log('memberId: ', memberId);
|
||||
})
|
||||
},
|
||||
/** type消息类型 文本:text,礼物:gift,进入房间:enter 观看人数:views 点赞: digg
|
||||
结束:over 讲解: explain
|
||||
*/
|
||||
sendMsg(msg) {
|
||||
let self = this;
|
||||
self.rtm_client.sendChannel(msg).then(() => {
|
||||
self.$emit('showMsg', msg);
|
||||
}).catch(error => {
|
||||
// 频道消息发送失败的处理逻辑
|
||||
console.log('频道消息发送失败的处理逻辑');
|
||||
console.log(error);
|
||||
});
|
||||
},
|
||||
/*直播设置*/
|
||||
liveSet(e) {
|
||||
switch (e.type) {
|
||||
case 'beauty':
|
||||
this.beauty = e.value;
|
||||
break;
|
||||
case 'whiteness':
|
||||
this.whiteness = e.value;
|
||||
break;
|
||||
case 'device_position':
|
||||
this.device_position = e.value;
|
||||
if (this.pusherContext != null) {
|
||||
this.pusherContext.switchCamera({
|
||||
type: e.value,
|
||||
success: function(res) {
|
||||
console.log('切换成功');
|
||||
},
|
||||
fail: function(err) {
|
||||
console.log(err);
|
||||
}
|
||||
});
|
||||
}
|
||||
break;
|
||||
}
|
||||
},
|
||||
/**
|
||||
* reconnect when bad things happens...
|
||||
*/
|
||||
reconnect: function() {
|
||||
let self = this;
|
||||
uni.showToast({
|
||||
title: '尝试恢复链接...',
|
||||
icon: 'none',
|
||||
duration: 5000
|
||||
});
|
||||
// always destroy client first
|
||||
// *important* miniapp supports 2 websockets maximum at same time
|
||||
// do remember to destroy old client first before creating new ones
|
||||
self.client && self.client.destroy();
|
||||
self.reconnectTimer = setTimeout(() => {
|
||||
self.loginRoom();
|
||||
}, 1 * 1000);
|
||||
},
|
||||
/**
|
||||
* 推流状态更新回调
|
||||
*/
|
||||
recorderStateChange: function (e) {
|
||||
console.log('live-pusher code: ' , e)
|
||||
if (e.detail.code === -1307) {
|
||||
//re-push
|
||||
console.log('live-pusher stopped ---- error');
|
||||
this.push_status = 'error';
|
||||
}
|
||||
if (e.detail.code === 1008) {
|
||||
//started
|
||||
console.log('live-pusher started');
|
||||
if(this.push_status === "loading") {
|
||||
this.push_status = 'ok';
|
||||
}
|
||||
}
|
||||
},
|
||||
recorderNetChange: function(e) {
|
||||
//console.log('netstatus:' + JSON.stringify(e));
|
||||
},
|
||||
onMainError: function(e) {
|
||||
var self = this;
|
||||
console.log('onMainError called: ', e);
|
||||
},
|
||||
/*退出 type: auto:主动 over:结束*/
|
||||
exit: function(type) {
|
||||
let self = this;
|
||||
let url = '/pagesLive/live/index';
|
||||
if (self.role == 'broadcaster') {
|
||||
type = 'over';
|
||||
// 通知其他人
|
||||
let msg = {
|
||||
type: 'over'
|
||||
};
|
||||
self.sendMsg(JSON.stringify(msg));
|
||||
}
|
||||
if(type == 'over'){
|
||||
//直播结束页
|
||||
url = '/pagesLive/live/live-over?room_id=' + self.roomDetail.room_id;
|
||||
}
|
||||
self.clear();
|
||||
uni.redirectTo({
|
||||
url: url
|
||||
});
|
||||
},
|
||||
startRecord:function(){
|
||||
let self = this;
|
||||
// 请求开始录制
|
||||
if(self.isCaster){
|
||||
self.getRequest()._post('plus.live.agora.api/record_acquire', {
|
||||
room_id: self.roomDetail.room_id
|
||||
}, function(res) {
|
||||
self.getRequest()._post('plus.live.agora.api/record_start', {
|
||||
room_id: self.roomDetail.room_id
|
||||
}, function(res) {
|
||||
self.getRequest()._post('plus.live.agora.api/record_query', {
|
||||
room_id: self.roomDetail.room_id
|
||||
}, function(res) {
|
||||
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
},
|
||||
/*销毁*/
|
||||
clear: function() {
|
||||
let self = this;
|
||||
try {
|
||||
if (self.showNumTimer) {
|
||||
clearInterval(self.showNumTimer);
|
||||
self.showNumTimer = null;
|
||||
}
|
||||
if (self.playerContext) {
|
||||
self.playerContext.stop();
|
||||
self.playerContext = null;
|
||||
}
|
||||
if (self.pusherContext) {
|
||||
self.pusherContext.stop();
|
||||
self.pusherContext = null;
|
||||
}
|
||||
clearTimeout(this.reconnectTimer);
|
||||
self.reconnectTimer = null;
|
||||
if (self.isCaster) {
|
||||
try {
|
||||
self.client && self.client.unpublish();
|
||||
} catch (e) {
|
||||
console.log(`unpublish failed`);
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
// rtm退出
|
||||
self.client && self.client.leave();
|
||||
// rtm退出
|
||||
self.rtm_client && self.rtm_client.logout();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
Reference in New Issue
Block a user