|
@@ -9,6 +9,7 @@ declare const AgoraRTC: any;
|
|
|
providedIn: 'root',
|
|
|
})
|
|
|
export class LiveService {
|
|
|
+ isAnchor: boolean = false; //是否是主播
|
|
|
options: {
|
|
|
appid: string;
|
|
|
channel: string;
|
|
@@ -51,6 +52,8 @@ export class LiveService {
|
|
|
room?: Parse.Object; //直播间
|
|
|
connection_state?: string; //连接状态
|
|
|
surplusNumber: number = 0; //剩余可通话时长(单位:秒s)
|
|
|
+ countdown: number = 0; // 新增倒计时变量
|
|
|
+ timer_countdown: any;
|
|
|
liveLog?: Parse.Object; //直播记录
|
|
|
constructor(
|
|
|
private http: HttpService,
|
|
@@ -74,6 +77,7 @@ export class LiveService {
|
|
|
/* 初始化Agora */
|
|
|
initAgora() {
|
|
|
this.timer && clearTimeout(this.timer);
|
|
|
+ this.timer_countdown && clearInterval(this.timer_countdown);
|
|
|
this.options['token'] = '';
|
|
|
this.options['channel'] = '';
|
|
|
this.client?.leave();
|
|
@@ -99,10 +103,10 @@ export class LiveService {
|
|
|
audioDevice: this.media_devices.audioDevices[0].deviceId,
|
|
|
videoDevice: this.media_devices.videoDevices[0].deviceId,
|
|
|
};
|
|
|
- return Promise.all([
|
|
|
- AgoraRTC.createCameraVideoTrack(),
|
|
|
- AgoraRTC.createMicrophoneAudioTrack(),
|
|
|
- ]);
|
|
|
+ // return Promise.all([
|
|
|
+ // AgoraRTC.createCameraVideoTrack(),
|
|
|
+ // AgoraRTC.createMicrophoneAudioTrack(),
|
|
|
+ // ]);
|
|
|
})
|
|
|
.then((tracks: any) => {
|
|
|
console.log(tracks);
|
|
@@ -115,11 +119,12 @@ export class LiveService {
|
|
|
/* 获取token */
|
|
|
async getToken(room: Parse.Object) {
|
|
|
this.room = room;
|
|
|
+ this.isAnchor = room?.get('user')?.id === Parse.User.current()?.id;
|
|
|
this.timer && clearTimeout(this.timer);
|
|
|
let remoteEle = document.getElementById('vice-video');
|
|
|
(remoteEle as any).style.display = 'none';
|
|
|
//获取频道token记录
|
|
|
- if (room?.get('user')?.id === Parse.User.current()?.id) {
|
|
|
+ if (this.isAnchor) {
|
|
|
this.UID = 111111;
|
|
|
let uid = Parse.User.current()?.id;
|
|
|
if (!uid) {
|
|
@@ -185,11 +190,13 @@ export class LiveService {
|
|
|
// await this.client.setClientRole('host');
|
|
|
console.log('进入频道当前uid:', uid);
|
|
|
this.connection_state = this.client.connectionState;
|
|
|
- if (this.room?.get('user')?.id !== Parse.User.current()?.id) {
|
|
|
+ if (!this.isAnchor) {
|
|
|
// 观众进入直播间,创建直播记录
|
|
|
await this.createLiveLog(uid);
|
|
|
+ } else {
|
|
|
+ //主播进入直播间直接发送自己推流
|
|
|
+ await this.publishSelf();
|
|
|
}
|
|
|
- await this.publishSelf();
|
|
|
await this.joinReady();
|
|
|
this.afterJoin();
|
|
|
})
|
|
@@ -199,26 +206,31 @@ export class LiveService {
|
|
|
}
|
|
|
/* 发布本地视频 */
|
|
|
async publishSelf() {
|
|
|
- let data = await Promise.all([
|
|
|
- /* 创建音频和视频轨道 */
|
|
|
- AgoraRTC.createMicrophoneAudioTrack(this.currentUsedDevice.audioDevice),
|
|
|
- AgoraRTC.createCameraVideoTrack(this.currentUsedDevice.videoDevice),
|
|
|
- ]);
|
|
|
- this.localTracks.audioTrack = data[0];
|
|
|
- this.localTracks.videoTrack = data[1];
|
|
|
- // console.log(this.localTracks);
|
|
|
- let remoteEle = document.getElementById('vice-video');
|
|
|
- if (remoteEle) {
|
|
|
- remoteEle.textContent = '';
|
|
|
- remoteEle.style.display = 'block';
|
|
|
- }
|
|
|
- this.localTracks.videoTrack.play('vice-video'); //播放自己视频渲染
|
|
|
- if (this.tools['audio']) {
|
|
|
- this.localTracks.audioTrack.setEnabled(false);
|
|
|
- } else {
|
|
|
- this.localTracks.audioTrack.setEnabled(true);
|
|
|
+ try {
|
|
|
+ let data = await Promise.all([
|
|
|
+ /* 创建音频和视频轨道 */
|
|
|
+ AgoraRTC.createMicrophoneAudioTrack(this.currentUsedDevice.audioDevice),
|
|
|
+ AgoraRTC.createCameraVideoTrack(this.currentUsedDevice.videoDevice),
|
|
|
+ ]);
|
|
|
+ this.localTracks.audioTrack = data[0];
|
|
|
+ this.localTracks.videoTrack = data[1];
|
|
|
+ // console.log(this.localTracks);
|
|
|
+ let remoteEle = document.getElementById('vice-video');
|
|
|
+ if (remoteEle) {
|
|
|
+ remoteEle.textContent = '';
|
|
|
+ remoteEle.style.display = 'block';
|
|
|
+ }
|
|
|
+ this.localTracks.videoTrack.play('vice-video'); //播放自己视频渲染
|
|
|
+ if (this.tools['audio']) {
|
|
|
+ this.localTracks.audioTrack.setEnabled(false);
|
|
|
+ } else {
|
|
|
+ this.localTracks.audioTrack.setEnabled(true);
|
|
|
+ }
|
|
|
+ await this.client.publish(Object.values(this.localTracks));
|
|
|
+ } catch (err) {
|
|
|
+ console.log('发布本地视频失败:', err);
|
|
|
+ this.alertTips('发布本地视频失败:');
|
|
|
}
|
|
|
- await this.client.publish(Object.values(this.localTracks));
|
|
|
}
|
|
|
/* 订阅远程视频 */
|
|
|
async joinReady() {
|
|
@@ -268,8 +280,8 @@ export class LiveService {
|
|
|
remoteEle.textContent = '对方离开直播间';
|
|
|
}
|
|
|
//主播离开,停止计时计费
|
|
|
- if(this.room?.get('user').id !== Parse.User.current()?.id){
|
|
|
- this.client.leave()
|
|
|
+ if (!this.isAnchor) {
|
|
|
+ this.client.leave();
|
|
|
}
|
|
|
this.alertTips('对方已离开直播间');
|
|
|
}
|
|
@@ -278,10 +290,15 @@ export class LiveService {
|
|
|
'connection-state-change',
|
|
|
(curState: any, prevState: any) => {
|
|
|
this.connection_state = curState;
|
|
|
- if(curState == 'RECONNECTING' || curState == 'DISCONNECTED' || curState == 'DISCONNECTING'){
|
|
|
- this.timer && clearInterval(this.timer);
|
|
|
+ if (
|
|
|
+ curState == 'RECONNECTING' ||
|
|
|
+ curState == 'DISCONNECTED' ||
|
|
|
+ curState == 'DISCONNECTING'
|
|
|
+ ) {
|
|
|
+ this.timer && clearTimeout(this.timer);
|
|
|
+ this.timer_countdown && clearInterval(this.timer_countdown);
|
|
|
}
|
|
|
- console.log(this.connection_state);
|
|
|
+ console.log('状态变更:', this.connection_state);
|
|
|
console.log(prevState);
|
|
|
}
|
|
|
);
|
|
@@ -318,14 +335,29 @@ export class LiveService {
|
|
|
/* 连线成功立即创建直播记录,同步获取剩余可通话时长,并且开始计时 */
|
|
|
async afterJoin() {
|
|
|
this.timer && clearTimeout(this.timer);
|
|
|
+ this.timer_countdown && clearInterval(this.timer_countdown);
|
|
|
if (this.client.remoteUsers.length > 0) {
|
|
|
- if (this.room?.get('user')?.id === Parse.User.current()?.id) {
|
|
|
+ if (this.isAnchor) {
|
|
|
//如果是主播,进入获取remoteUsers.user获取livelog再获取对方剩余通话时长
|
|
|
- this.getLiveLog()
|
|
|
+ this.getLiveLog();
|
|
|
} else {
|
|
|
- //首次进入至少计时2分钟,不足2分钟按2分钟计算扣时
|
|
|
- await this.get_duration();
|
|
|
- this.computeDuration(60000 * 2);
|
|
|
+ let query = new Parse.Query('LiveLog');
|
|
|
+ query.equalTo('objectId', this.liveLog?.id);
|
|
|
+ query.equalTo('isLive', true);
|
|
|
+ query.select('objectId');
|
|
|
+ const resultData = await query.first();
|
|
|
+ if (resultData?.id) {
|
|
|
+ //首次进入至少计时2分钟,不足2分钟按2分钟计算扣时
|
|
|
+ await this.publishSelf();
|
|
|
+ await this.get_duration();
|
|
|
+ this.countdown = this.surplusNumber; // 初始化倒计时
|
|
|
+ this.startCountdown();
|
|
|
+ this.computeDuration(60000 * 2);
|
|
|
+ } else {
|
|
|
+ this.timer = setTimeout(() => {
|
|
|
+ this.afterJoin();
|
|
|
+ }, 1000);
|
|
|
+ }
|
|
|
}
|
|
|
} else {
|
|
|
this.timer = setTimeout(() => {
|
|
@@ -333,48 +365,62 @@ export class LiveService {
|
|
|
}, 1000);
|
|
|
}
|
|
|
}
|
|
|
- async getLiveLog(){
|
|
|
- let uid = this.client.remoteUsers[0].uid
|
|
|
- this.timer && clearInterval(this.timer);
|
|
|
- let query = new Parse.Query('LiveLog')
|
|
|
- query.equalTo('uid',String(uid))
|
|
|
- query.equalTo('room',this.room?.id)
|
|
|
- query.notEqualTo('isDeleted',true)
|
|
|
- query.notEqualTo('isLive',true)
|
|
|
- query.descending('createdAt')
|
|
|
- this.liveLog = await query.first()
|
|
|
- if(this.liveLog?.id){
|
|
|
- this.liveLog?.set('isLive',true)
|
|
|
- await this.liveLog?.save()
|
|
|
- this.get_duration()
|
|
|
- return
|
|
|
+ async getLiveLog() {
|
|
|
+ let uid = this.client.remoteUsers[0].uid;
|
|
|
+ this.timer && clearTimeout(this.timer);
|
|
|
+ let query = new Parse.Query('LiveLog');
|
|
|
+ query.equalTo('uid', String(uid));
|
|
|
+ query.equalTo('room', this.room?.id);
|
|
|
+ query.notEqualTo('isDeleted', true);
|
|
|
+ query.notEqualTo('isLive', true);
|
|
|
+ query.descending('createdAt');
|
|
|
+ this.liveLog = await query.first();
|
|
|
+ if (this.liveLog?.id) {
|
|
|
+ this.liveLog?.set('isLive', true);
|
|
|
+ await this.liveLog?.save();
|
|
|
+ this.get_duration();
|
|
|
+ return;
|
|
|
}
|
|
|
this.timer = setTimeout(() => {
|
|
|
this.getLiveLog();
|
|
|
}, 1000);
|
|
|
}
|
|
|
async get_duration() {
|
|
|
- let url = 'http://localhost:7337/api/ailiao/remain_second';
|
|
|
+ let url = 'https://server.fmode.cn/api/ailiao/remain_second';
|
|
|
let params = {
|
|
|
rid: this.room?.id,
|
|
|
uid: this.liveLog?.get('user')?.id || this.liveLog?.get('user')?.objectId,
|
|
|
};
|
|
|
let data = await this.http.httpRequst(url, params, 'POST');
|
|
|
console.log(data);
|
|
|
- this.surplusNumber = data.data.secoud ?? 0;
|
|
|
+ this.surplusNumber = data.data ?? 0;
|
|
|
+ }
|
|
|
+ startCountdown() {
|
|
|
+ this.timer_countdown = setInterval(() => {
|
|
|
+ if (this.countdown > 0) {
|
|
|
+ this.countdown--;
|
|
|
+ console.log(this.countdown);
|
|
|
+ } else {
|
|
|
+ clearInterval(this.timer_countdown);
|
|
|
+ this.alertTips('通话时间结束');
|
|
|
+ this.client.leave(); // 结束通话
|
|
|
+ }
|
|
|
+ }, 1000);
|
|
|
}
|
|
|
-
|
|
|
/* 开始计时 */
|
|
|
async computeDuration(num?: number) {
|
|
|
//每10秒保存一次数据
|
|
|
- this.timer && clearInterval(this.timer);
|
|
|
- let url = 'http://localhost:7337/api/ailiao/count/duration';
|
|
|
+ this.timer && clearTimeout(this.timer);
|
|
|
+ let p = JSON.parse(this.profile);
|
|
|
+ console.log(p);
|
|
|
+ let url = 'https://server.fmode.cn/api/ailiao/count/duration';
|
|
|
let params = {
|
|
|
company: this.company,
|
|
|
- profile: this.profile?.id,
|
|
|
+ profile: p?.objectId,
|
|
|
rid: this.room?.id,
|
|
|
uid: Parse.User.current()?.id,
|
|
|
- duration: num ? num/1000 : 10,
|
|
|
+ duration: num ? num / 1000 : 10,
|
|
|
+ logid: this.liveLog?.id,
|
|
|
};
|
|
|
let data = await this.http.httpRequst(url, params, 'POST');
|
|
|
console.log(data);
|
|
@@ -478,7 +524,6 @@ export class LiveService {
|
|
|
{
|
|
|
text: '确认',
|
|
|
handler: () => {
|
|
|
- console.log('Confirm Cancel: blah');
|
|
|
callBack && callBack();
|
|
|
},
|
|
|
},
|