|
@@ -1,4 +1,5 @@
|
|
|
import { Injectable } from '@angular/core';
|
|
|
+import { AlertController } from '@ionic/angular';
|
|
|
import * as Parse from 'parse';
|
|
|
import { AiChatService } from './aichart.service';
|
|
|
import { HttpService } from './http.service';
|
|
@@ -22,31 +23,55 @@ export class LiveService {
|
|
|
videoTrack: null,
|
|
|
};
|
|
|
rid?: string; //房间id(channel)
|
|
|
- profile?:any = localStorage.getItem('profile');
|
|
|
+ profile?: any = localStorage.getItem('profile');
|
|
|
client: any; //客户端
|
|
|
company: string = '';
|
|
|
- UID:any
|
|
|
+ UID: any;
|
|
|
tools: any = {
|
|
|
- audio:false, //是否关闭音频
|
|
|
+ audio: false, //是否关闭音频
|
|
|
camera: false, //是否切换摄像头
|
|
|
mute: false, //是否静音
|
|
|
};
|
|
|
- constructor(private http: HttpService, private aiServ: AiChatService) {
|
|
|
+ user_published_list = new Set(); //已发布列表
|
|
|
+ timer: any; //轮询获取频道token的定时
|
|
|
+ alert: any; //提示框
|
|
|
+ media_devices: {
|
|
|
+ //音视频设备列表
|
|
|
+ audioDevices: Array<any>;
|
|
|
+ videoDevices: Array<any>;
|
|
|
+ } = {
|
|
|
+ audioDevices: [],
|
|
|
+ videoDevices: [],
|
|
|
+ };
|
|
|
+ currentUsedDevice: { audioDevice: string; videoDevice: string } = {
|
|
|
+ //当前使用的设备
|
|
|
+ audioDevice: '',
|
|
|
+ videoDevice: '',
|
|
|
+ };
|
|
|
+ constructor(
|
|
|
+ private http: HttpService,
|
|
|
+ private aiServ: AiChatService,
|
|
|
+ private alertController: AlertController
|
|
|
+ ) {
|
|
|
this.client?.leave();
|
|
|
this.company = this.aiServ.company;
|
|
|
this.getProfile();
|
|
|
}
|
|
|
async getProfile() {
|
|
|
- if(this.profile) return
|
|
|
+ if (this.profile) return;
|
|
|
let queryProfile = new Parse.Query('Profile');
|
|
|
queryProfile.equalTo('user', Parse.User.current()?.id);
|
|
|
queryProfile.notEqualTo('isDeleted', true);
|
|
|
queryProfile.equalTo('isCross', true);
|
|
|
let r = await queryProfile.first();
|
|
|
- this.profile = r?.id
|
|
|
+ this.profile = r?.id;
|
|
|
}
|
|
|
/* 初始化Agora */
|
|
|
initAgora() {
|
|
|
+ this.timer && clearTimeout(this.timer);
|
|
|
+ this.options['token'] = '';
|
|
|
+ this.options['channel'] = '';
|
|
|
+ this.client?.leave();
|
|
|
this.client = AgoraRTC.createClient({ mode: 'rtc', codec: 'h264' });
|
|
|
AgoraRTC.enableLogUpload();
|
|
|
}
|
|
@@ -54,34 +79,45 @@ export class LiveService {
|
|
|
getDevices() {
|
|
|
AgoraRTC.getDevices()
|
|
|
.then((devices: any) => {
|
|
|
- const audioDevices = devices.filter(function (device: any) {
|
|
|
+ this.media_devices.audioDevices = devices.filter(function (
|
|
|
+ device: any
|
|
|
+ ) {
|
|
|
return device.kind === 'audioinput';
|
|
|
});
|
|
|
- const videoDevices = devices.filter(function (device: any) {
|
|
|
+ this.media_devices.videoDevices = devices.filter(function (
|
|
|
+ device: any
|
|
|
+ ) {
|
|
|
return device.kind === 'videoinput';
|
|
|
});
|
|
|
- let selectedMicrophoneId = audioDevices[0].deviceId;
|
|
|
- let selectedCameraId = videoDevices[0].deviceId;
|
|
|
+ console.log(this.media_devices);
|
|
|
+ this.currentUsedDevice = {
|
|
|
+ audioDevice: this.media_devices.audioDevices[0].deviceId,
|
|
|
+ videoDevice: this.media_devices.videoDevices[0].deviceId,
|
|
|
+ };
|
|
|
return Promise.all([
|
|
|
- AgoraRTC.createCameraVideoTrack({ cameraId: selectedCameraId }),
|
|
|
- AgoraRTC.createMicrophoneAudioTrack({
|
|
|
- microphoneId: selectedMicrophoneId,
|
|
|
- }),
|
|
|
+ AgoraRTC.createCameraVideoTrack(),
|
|
|
+ AgoraRTC.createMicrophoneAudioTrack(),
|
|
|
]);
|
|
|
})
|
|
|
.then((tracks: any) => {
|
|
|
- console.log('createCameraVideoTrack', tracks);
|
|
|
+ console.log(tracks);
|
|
|
})
|
|
|
.catch((err: any) => {
|
|
|
- console.log(err);
|
|
|
+ console.warn('获取媒体权限失败', err);
|
|
|
+ this.alertTips('获取媒体权限失败');
|
|
|
});
|
|
|
}
|
|
|
+
|
|
|
async getToken(room: Parse.Object) {
|
|
|
+ this.timer && clearTimeout(this.timer);
|
|
|
//获取频道token记录
|
|
|
if (room?.get('profile').id == this.profile) {
|
|
|
- this.UID = 111111
|
|
|
+ this.UID = 111111;
|
|
|
let uid = Parse.User.current()?.id;
|
|
|
if (!uid) {
|
|
|
+ this.timer = setTimeout(() => {
|
|
|
+ this.getToken(room);
|
|
|
+ }, 2000);
|
|
|
return;
|
|
|
}
|
|
|
let baseurl = 'https://server.fmode.cn/api/webrtc/build_token';
|
|
@@ -95,14 +131,21 @@ export class LiveService {
|
|
|
if (data.code == 200) {
|
|
|
this.options.token = data.data.token;
|
|
|
this.options.appid = data.data.appid;
|
|
|
- this.options.channel = room?.get('profile').id
|
|
|
+ this.options.channel = room?.get('profile').id;
|
|
|
}
|
|
|
} else {
|
|
|
let data = await this.updateToken(room?.get('profile').id);
|
|
|
+ console.log(data);
|
|
|
+ if (!data?.token) {
|
|
|
+ this.timer = setTimeout(() => {
|
|
|
+ this.getToken(room);
|
|
|
+ }, 2000);
|
|
|
+ return;
|
|
|
+ }
|
|
|
this.options.token = data.token;
|
|
|
this.options.channel = data.channel;
|
|
|
- console.log(data);
|
|
|
}
|
|
|
+ this.join();
|
|
|
}
|
|
|
/* 获取token */
|
|
|
async updateToken(pid: string) {
|
|
@@ -121,9 +164,16 @@ export class LiveService {
|
|
|
}
|
|
|
// 进入频道
|
|
|
async join() {
|
|
|
- console.log('频道:',this.options.channel);
|
|
|
+ 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.options.appid, this.options.channel, this.options.token, this.UID),
|
|
|
+ this.client.join(
|
|
|
+ this.options.appid,
|
|
|
+ this.options.channel,
|
|
|
+ this.options.token,
|
|
|
+ this.UID
|
|
|
+ ),
|
|
|
/* 创建音频和视频轨道 */
|
|
|
AgoraRTC.createMicrophoneAudioTrack(),
|
|
|
AgoraRTC.createCameraVideoTrack(),
|
|
@@ -131,14 +181,15 @@ export class LiveService {
|
|
|
// await this.client.setClientRole('host');
|
|
|
this.localTracks.audioTrack = data[1];
|
|
|
this.localTracks.videoTrack = data[2];
|
|
|
+ console.log(this.localTracks);
|
|
|
let remoteEle = document.getElementById('vice-video');
|
|
|
if (remoteEle) {
|
|
|
remoteEle.textContent = '';
|
|
|
}
|
|
|
this.localTracks.videoTrack.play('vice-video'); //播放自己视频渲染
|
|
|
- if(this.tools['audio']){
|
|
|
+ if (this.tools['audio']) {
|
|
|
this.localTracks.audioTrack.setEnabled(false);
|
|
|
- }else{
|
|
|
+ } else {
|
|
|
this.localTracks.audioTrack.setEnabled(true);
|
|
|
}
|
|
|
await this.client.publish(Object.values(this.localTracks));
|
|
@@ -146,18 +197,19 @@ export class LiveService {
|
|
|
}
|
|
|
/* 订阅远程视频 */
|
|
|
async joinReady() {
|
|
|
- console.log(this.client.remoteUsers);
|
|
|
- let wxRemoteUsers = this.client.remoteUsers.find((item: any) => {
|
|
|
- if (item.uid && item._video_added_) {
|
|
|
- return item;
|
|
|
- }
|
|
|
- });
|
|
|
- console.log(wxRemoteUsers);
|
|
|
+ await Promise.all(
|
|
|
+ this.client.remoteUsers.map((item: any) => {
|
|
|
+ if (item.uid && item._video_added_ && item._videoTrack) {
|
|
|
+ console.log('已存在用户:', item);
|
|
|
+ this.client.subscribe(item);
|
|
|
+ }
|
|
|
+ })
|
|
|
+ );
|
|
|
this.client.on('user-joined', (user: any) => {
|
|
|
console.log(user, `${user.uid} 加入频道`);
|
|
|
});
|
|
|
- this.client.on('user-published', async (user: any, mediaType: any) => {
|
|
|
- console.log('用户推流成功');
|
|
|
+ this.client.on('user-published', async (user: any, mediaType: string) => {
|
|
|
+ console.log('用户推流成功', user);
|
|
|
// if (user.uid == 333333) {
|
|
|
await this.client.subscribe(user, mediaType);
|
|
|
// }
|
|
@@ -166,34 +218,72 @@ export class LiveService {
|
|
|
remoteEle.textContent = '';
|
|
|
}
|
|
|
if (mediaType === 'video') {
|
|
|
- user.videoTrack.play(`video`);
|
|
|
+ user.videoTrack.play('video');
|
|
|
+ this.alert?.dismiss();
|
|
|
}
|
|
|
if (mediaType === 'audio') {
|
|
|
user.audioTrack.play();
|
|
|
+ this.user_published_list.add(user);
|
|
|
}
|
|
|
});
|
|
|
- this.client.on('user-unpublished', (user: any) => {
|
|
|
- let remoteEle = document.getElementById('video');
|
|
|
- if (remoteEle) {
|
|
|
- remoteEle.textContent = '对方离开直播间';
|
|
|
+ this.client.on('user-unpublished', async (user: any, mediaType: string) => {
|
|
|
+ if (mediaType === 'audio') {
|
|
|
+ console.log('对方已静音');
|
|
|
+ this.user_published_list.delete(user);
|
|
|
+ }
|
|
|
+ if (mediaType === 'video') {
|
|
|
+ console.log('用户取消推流');
|
|
|
+ let remoteEle = document.getElementById('video');
|
|
|
+ if (remoteEle) {
|
|
|
+ remoteEle.textContent = '对方离开直播间';
|
|
|
+ }
|
|
|
+ this.alertTips('对方已离开直播间');
|
|
|
}
|
|
|
- // if (user.uid == 333333) {
|
|
|
- console.log('用户取消推流');
|
|
|
- // }
|
|
|
});
|
|
|
}
|
|
|
/* 停止音频推流 */
|
|
|
- async updatePublishedAudioTrack(){
|
|
|
+ async updatePublishedAudioTrack() {
|
|
|
this.tools['audio'] = !this.tools['audio'];
|
|
|
- if(this.tools['audio'] && this.localTracks.audioTrack){
|
|
|
+ if (this.tools['audio'] && this.localTracks.audioTrack) {
|
|
|
await this.localTracks.audioTrack.setEnabled(false);
|
|
|
console.log('停止推送音频');
|
|
|
- }else{
|
|
|
- await this.localTracks.audioTrack.setEnabled(true)
|
|
|
+ } else {
|
|
|
+ await this.localTracks.audioTrack.setEnabled(true);
|
|
|
console.log('恢复推送音频');
|
|
|
}
|
|
|
// await this.client.unpublish(this.localTracks.audioTrack);
|
|
|
- return true
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ /* 静音 */
|
|
|
+ async muteAudio() {
|
|
|
+ this.tools['mute'] = !this.tools['mute'];
|
|
|
+ let list = Array.from(this.user_published_list);
|
|
|
+ for (let index = 0; index < list.length; index++) {
|
|
|
+ const user = list[index];
|
|
|
+ if (this.tools['mute']) {
|
|
|
+ console.log('静音');
|
|
|
+ await this.client.unsubscribe(user, 'audio');
|
|
|
+ } else {
|
|
|
+ await this.client.subscribe(user, 'audio');
|
|
|
+ console.log('恢复');
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
+ async alertTips(message: string, title?: string, callBack?: Function) {
|
|
|
+ this.alert = await this.alertController.create({
|
|
|
+ header: title || '提示',
|
|
|
+ message: message,
|
|
|
+ buttons: [
|
|
|
+ {
|
|
|
+ text: '确认',
|
|
|
+ handler: () => {
|
|
|
+ console.log('Confirm Cancel: blah');
|
|
|
+ callBack && callBack();
|
|
|
+ },
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ });
|
|
|
+ await this.alert.present();
|
|
|
+ }
|
|
|
}
|