|
@@ -49,6 +49,9 @@ export class LiveService {
|
|
|
videoDevice: '',
|
|
|
};
|
|
|
room?: Parse.Object; //直播间
|
|
|
+ connection_state?: string; //连接状态
|
|
|
+ surplusNumber: number = 0; //剩余可通话时长(单位:秒s)
|
|
|
+
|
|
|
constructor(
|
|
|
private http: HttpService,
|
|
|
private aiServ: AiChatService,
|
|
@@ -109,14 +112,14 @@ export class LiveService {
|
|
|
this.alertTips('获取媒体权限失败');
|
|
|
});
|
|
|
}
|
|
|
-
|
|
|
+ /* 获取token */
|
|
|
async getToken(room: Parse.Object) {
|
|
|
this.room = room;
|
|
|
this.timer && clearTimeout(this.timer);
|
|
|
let remoteEle = document.getElementById('vice-video');
|
|
|
(remoteEle as any).style.display = 'none';
|
|
|
//获取频道token记录
|
|
|
- if (room?.get('profile').id == this.profile) {
|
|
|
+ if (room?.get('user')?.id === Parse.User.current()?.id) {
|
|
|
this.UID = 111111;
|
|
|
let uid = Parse.User.current()?.id;
|
|
|
if (!uid) {
|
|
@@ -128,8 +131,8 @@ export class LiveService {
|
|
|
let baseurl = 'https://server.fmode.cn/api/webrtc/build_token';
|
|
|
let reqBody = {
|
|
|
company: this.company, // this.aiSer.company,
|
|
|
- profile: this.profile,
|
|
|
- channelName: this.profile,
|
|
|
+ profile: room?.get('profile').id,
|
|
|
+ channelName: room?.get('profile').id,
|
|
|
};
|
|
|
let data: any = await this.http.httpRequst(baseurl, reqBody, 'POST');
|
|
|
console.log(data);
|
|
@@ -152,7 +155,6 @@ export class LiveService {
|
|
|
}
|
|
|
this.join();
|
|
|
}
|
|
|
- /* 获取token */
|
|
|
async updateToken(pid: string) {
|
|
|
let sql = `select "rtc"."objectId" as "rid","rtc"."channel", "rtc"."token", "rtc"."expiraTime" from "RtcToken" as "rtc" where "rtc"."profile" = '${pid}' and "rtc"."expiraTime" >= now() order by "createdAt" desc limit 1`;
|
|
|
let tokenData: any = await this.http.customSQL(sql);
|
|
@@ -167,25 +169,40 @@ export class LiveService {
|
|
|
return null;
|
|
|
}
|
|
|
}
|
|
|
- // 进入频道
|
|
|
+ /* 进入频道 */
|
|
|
async join() {
|
|
|
let path = location.pathname;
|
|
|
if (path.indexOf('/live/link-room/') == -1) return;
|
|
|
console.log('频道:', this.options.channel);
|
|
|
- let data = await Promise.all([
|
|
|
- this.client.join(
|
|
|
+ this.client
|
|
|
+ .join(
|
|
|
this.options.appid,
|
|
|
this.options.channel,
|
|
|
this.options.token,
|
|
|
this.UID
|
|
|
- ),
|
|
|
+ )
|
|
|
+ .then(async (uid: any) => {
|
|
|
+ // await this.client.setClientRole('host');
|
|
|
+ console.log('进入频道当前uid:', uid);
|
|
|
+ this.client.connectionState;
|
|
|
+ this.connection_state = this.client.connectionState;
|
|
|
+ await this.publishSelf();
|
|
|
+ await this.joinReady();
|
|
|
+ this.monitorDevices();
|
|
|
+ })
|
|
|
+ .catch((err: any) => {
|
|
|
+ console.log('进入频道失败:', err);
|
|
|
+ });
|
|
|
+ }
|
|
|
+ /* 发布本地视频 */
|
|
|
+ async publishSelf() {
|
|
|
+ let data = await Promise.all([
|
|
|
/* 创建音频和视频轨道 */
|
|
|
- AgoraRTC.createMicrophoneAudioTrack(),
|
|
|
- AgoraRTC.createCameraVideoTrack(),
|
|
|
+ AgoraRTC.createMicrophoneAudioTrack(this.currentUsedDevice.audioDevice),
|
|
|
+ AgoraRTC.createCameraVideoTrack(this.currentUsedDevice.videoDevice),
|
|
|
]);
|
|
|
- // await this.client.setClientRole('host');
|
|
|
- this.localTracks.audioTrack = data[1];
|
|
|
- this.localTracks.videoTrack = data[2];
|
|
|
+ this.localTracks.audioTrack = data[0];
|
|
|
+ this.localTracks.videoTrack = data[1];
|
|
|
// console.log(this.localTracks);
|
|
|
let remoteEle = document.getElementById('vice-video');
|
|
|
if (remoteEle) {
|
|
@@ -198,15 +215,10 @@ export class LiveService {
|
|
|
} else {
|
|
|
this.localTracks.audioTrack.setEnabled(true);
|
|
|
}
|
|
|
- await this.joinReady();
|
|
|
- }
|
|
|
- /* 发布本地视频 */
|
|
|
- async publishSelf() {
|
|
|
await this.client.publish(Object.values(this.localTracks));
|
|
|
}
|
|
|
/* 订阅远程视频 */
|
|
|
async joinReady() {
|
|
|
- await this.publishSelf();
|
|
|
this.client.remoteUsers.forEach((user: any) => {
|
|
|
console.log('remoteUsers', user.uid);
|
|
|
this.client.subscribe(user, 'audio').then((audioTrack: any) => {
|
|
@@ -222,37 +234,10 @@ export class LiveService {
|
|
|
videoTrack.play('video');
|
|
|
});
|
|
|
});
|
|
|
- // this.timer && clearInterval(this.timer);
|
|
|
- // console.log(this.client.remoteUsers);
|
|
|
- // const isAnchor = this.room?.get('user')?.id === Parse.User.current()?.id
|
|
|
- // if(isAnchor){
|
|
|
- // console.log('当前用户身份:房主');
|
|
|
- // // this.localTracks.audioTrack.setEnabled(false);
|
|
|
- // // this.localTracks.videoTrack.setEnabled(false);
|
|
|
- // await this.publishSelf()
|
|
|
- // }else{
|
|
|
- // console.log('当前用户身份:用户');
|
|
|
- // console.log('主播在线状态',this.client.remoteUsers.length);
|
|
|
- // if (location.pathname.indexOf('/live/link-room/') == -1) return;
|
|
|
- // /* 如果主播还没有上线,等待主播上线后发布 */
|
|
|
- // if(this.client.remoteUsers.length == 0){
|
|
|
- // setTimeout(() => {
|
|
|
- // this.joinReady()
|
|
|
- // }, 1000);
|
|
|
- // return
|
|
|
- // }
|
|
|
- // }
|
|
|
this.client.on('user-joined', (user: any) => {
|
|
|
console.log(user, `${user.uid} 加入频道`);
|
|
|
});
|
|
|
this.client.on('user-published', async (user: any, mediaType: string) => {
|
|
|
- /* 当用户进入直播间,主播重新推流视频:解决订阅者remoteUsers无法渲染问题 */
|
|
|
- // if(isAnchor){
|
|
|
- // // await this.client.unpublish(Object.values(this.localTracks));
|
|
|
- // // await this.client.publish(Object.values(this.localTracks));
|
|
|
- // // this.localTracks.videoTrack.setEnabled(true);
|
|
|
- // // this.localTracks.audioTrack.setEnabled(true);
|
|
|
- // }
|
|
|
console.log('用户推流成功', user);
|
|
|
await this.client.subscribe(user, mediaType);
|
|
|
let remoteEle = document.getElementById('video');
|
|
@@ -282,11 +267,70 @@ export class LiveService {
|
|
|
this.alertTips('对方已离开直播间');
|
|
|
}
|
|
|
});
|
|
|
- // if(!isAnchor){
|
|
|
- // this.publishSelf()
|
|
|
- // }
|
|
|
+ this.client.on(
|
|
|
+ 'connection-state-change',
|
|
|
+ (curState: any, prevState: any) => {
|
|
|
+ this.connection_state = curState;
|
|
|
+ console.log(this.connection_state);
|
|
|
+ console.log(prevState);
|
|
|
+ }
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ /* 开始计时 */
|
|
|
+ computeDuration() {
|
|
|
+ //每10秒保存一次数据
|
|
|
+ this.timer && clearInterval(this.timer);
|
|
|
+ this.timer = setInterval(() => {
|
|
|
+ let url = 'http://test.fmode.cn/api/ailiao/count/duration';
|
|
|
+ let params = {
|
|
|
+ company: this.company,
|
|
|
+ profile:this.profile?.id,
|
|
|
+ rid: this.room?.id,
|
|
|
+ uid: Parse.User.current()?.id,
|
|
|
+ };
|
|
|
+ this.http.httpRequst(url, params,'POST');
|
|
|
+ }, 10000);
|
|
|
+ }
|
|
|
+
|
|
|
+ /* 监听音视频设备插拔 */
|
|
|
+ monitorDevices() {
|
|
|
+ AgoraRTC.onMicrophoneChanged = async (changedDevice: any) => {
|
|
|
+ // 插入麦克风设备时,切换到新插入的设备
|
|
|
+ if (changedDevice.state === 'ACTIVE') {
|
|
|
+ this.localTracks.audioTrack.setDevice(changedDevice.device.deviceId);
|
|
|
+ this.currentUsedDevice.audioDevice = changedDevice.device.deviceId;
|
|
|
+
|
|
|
+ // 拔出设备为当前设备时,切换到一个已有的设备
|
|
|
+ } else if (
|
|
|
+ changedDevice.device.label ===
|
|
|
+ this.localTracks.audioTrack.getTrackLabel()
|
|
|
+ ) {
|
|
|
+ const oldMicrophones = await AgoraRTC.getMicrophones();
|
|
|
+ oldMicrophones[0] &&
|
|
|
+ this.localTracks.audioTrack.setDevice(oldMicrophones[0].deviceId);
|
|
|
+ this.currentUsedDevice.audioDevice = oldMicrophones[0].deviceId;
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ AgoraRTC.onCameraChanged = async (changedDevice: any) => {
|
|
|
+ // 插入相机设备时,切换到新插入的设备
|
|
|
+ if (changedDevice.state === 'ACTIVE') {
|
|
|
+ this.localTracks.videoTrack.setDevice(changedDevice.device.deviceId);
|
|
|
+ this.currentUsedDevice.videoDevice = changedDevice.device.deviceId;
|
|
|
+ // 拔出设备为当前设备时,切换到一个已有的设备
|
|
|
+ } else if (
|
|
|
+ changedDevice.device.label ===
|
|
|
+ this.localTracks.videoTrack.getTrackLabel()
|
|
|
+ ) {
|
|
|
+ const oldCameras = await AgoraRTC.getCameras();
|
|
|
+ oldCameras[0] &&
|
|
|
+ this.localTracks.videoTrack.setDevice(oldCameras[0].deviceId);
|
|
|
+ this.currentUsedDevice.videoDevice = oldCameras[0].deviceId;
|
|
|
+ }
|
|
|
+ };
|
|
|
}
|
|
|
- /* 停止音频推流 */
|
|
|
+ /* 关开麦 */
|
|
|
async updatePublishedAudioTrack() {
|
|
|
this.tools['audio'] = !this.tools['audio'];
|
|
|
if (this.tools['audio'] && this.localTracks.audioTrack) {
|
|
@@ -315,6 +359,28 @@ export class LiveService {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ /* 切换摄像头 */
|
|
|
+ async changeCamera() {
|
|
|
+ const oldCameras = await AgoraRTC.getCameras(true);
|
|
|
+ let newCamers = oldCameras.find(
|
|
|
+ (item: any) => item.deviceId !== this.currentUsedDevice.videoDevice
|
|
|
+ );
|
|
|
+ console.log(newCamers);
|
|
|
+ newCamers &&
|
|
|
+ this.localTracks.videoTrack
|
|
|
+ .setDevice(newCamers.deviceId)
|
|
|
+ .then(() => {
|
|
|
+ this.tools['camera'] = !this.tools['camera'];
|
|
|
+ this.currentUsedDevice.videoDevice = newCamers.deviceId;
|
|
|
+ })
|
|
|
+ .catch((err: any) => {
|
|
|
+ console.log('set device error', err);
|
|
|
+ this.alertTips('切换摄像头失败');
|
|
|
+ });
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* 提示 */
|
|
|
async alertTips(message: string, title?: string, callBack?: Function) {
|
|
|
this.alert = await this.alertController.create({
|
|
|
header: title || '提示',
|