|
@@ -6,7 +6,7 @@ import { AiChatService } from './aichart.service';
|
|
|
import { HttpService } from './http.service';
|
|
|
import { MessageService } from './message.service';
|
|
|
declare const AgoraRTC: any;
|
|
|
-
|
|
|
+import BeautyExtension from 'agora-extension-beauty-effect'; // 引入美颜扩展
|
|
|
@Injectable({
|
|
|
providedIn: 'root',
|
|
|
})
|
|
@@ -33,9 +33,10 @@ export class LiveService {
|
|
|
tools: any = {
|
|
|
audio: false, //是否关闭音频
|
|
|
camera: false, //是否切换摄像头
|
|
|
+ glorify: false, //是否开启美颜
|
|
|
mute: false, //是否静音
|
|
|
};
|
|
|
- user_published_list = new Set(); //已发布列表
|
|
|
+ user_published_list: Array<any> = []; //已发布列表
|
|
|
timer: any; //轮询获取频道token的定时
|
|
|
alert: any; //提示框
|
|
|
media_devices: {
|
|
@@ -59,7 +60,8 @@ export class LiveService {
|
|
|
liveLog?: Parse.Object; //直播记录
|
|
|
|
|
|
isOpenEvaluate: boolean = false; //是否开启评价
|
|
|
-
|
|
|
+ isBeautyExtensionRegistered: boolean = false; //是否注册美颜扩展
|
|
|
+ processor: any; //音视频处理
|
|
|
constructor(
|
|
|
private http: HttpService,
|
|
|
private router: Router,
|
|
@@ -83,13 +85,30 @@ export class LiveService {
|
|
|
}
|
|
|
/* 初始化Agora */
|
|
|
initAgora() {
|
|
|
+ this.tools = {
|
|
|
+ audio: false, //是否关闭音频
|
|
|
+ camera: false, //是否切换摄像头
|
|
|
+ glorify: false, //是否开启美颜
|
|
|
+ mute: false, //是否静音
|
|
|
+ };
|
|
|
this.timer && clearTimeout(this.timer);
|
|
|
this.timer_countdown && clearInterval(this.timer_countdown);
|
|
|
this.options['token'] = '';
|
|
|
this.options['channel'] = '';
|
|
|
+ this.user_published_list = [];
|
|
|
this.client?.leave();
|
|
|
this.client = AgoraRTC.createClient({ mode: 'rtc', codec: 'h264' });
|
|
|
AgoraRTC.enableLogUpload();
|
|
|
+
|
|
|
+ if (!this.isBeautyExtensionRegistered) {
|
|
|
+ // 创建 BeautyExtension 实例
|
|
|
+ const extension: any = new BeautyExtension();
|
|
|
+ // 注册插件
|
|
|
+ AgoraRTC.registerExtensions([extension]);
|
|
|
+ // 创建 BeautyProcessor 实例
|
|
|
+ this.processor = extension.createProcessor();
|
|
|
+ }
|
|
|
+ this.setBeautyOptions();
|
|
|
}
|
|
|
// 获取所有音视频设备
|
|
|
getDevices() {
|
|
@@ -226,6 +245,15 @@ export class LiveService {
|
|
|
} else {
|
|
|
this.localTracks.audioTrack.setEnabled(true);
|
|
|
}
|
|
|
+
|
|
|
+ if (this.processor && this.localTracks.videoTrack) {
|
|
|
+ // 将插件注入 SDK 内的视频处理管道
|
|
|
+ this.localTracks.videoTrack
|
|
|
+ .pipe(this.processor)
|
|
|
+ .pipe(this.localTracks.videoTrack.processorDestination);
|
|
|
+ // 开启美颜
|
|
|
+ await this.processor.enable();
|
|
|
+ }
|
|
|
await this.client.publish(Object.values(this.localTracks));
|
|
|
} catch (err) {
|
|
|
console.log('发布本地视频失败:', err);
|
|
@@ -234,12 +262,27 @@ export class LiveService {
|
|
|
this.client.leave();
|
|
|
}
|
|
|
}
|
|
|
+ /* 设置各项美颜参数 */
|
|
|
+ async setBeautyOptions() {
|
|
|
+ this.processor.setOptions({
|
|
|
+ lighteningContrastLevel: 2, // 对比度
|
|
|
+ lighteningLevel: 0.8, // 亮度
|
|
|
+ smoothnessLevel: 0.8, // 平滑度
|
|
|
+ sharpnessLevel: 0.5, // 锐化程度
|
|
|
+ rednessLevel: 0.5, // 红润度
|
|
|
+ });
|
|
|
+ this.tools['glorify'] = true;
|
|
|
+ }
|
|
|
+
|
|
|
/* 订阅远程视频 */
|
|
|
async joinReady() {
|
|
|
this.client.remoteUsers.forEach((user: any) => {
|
|
|
console.log('remoteUsers', user.uid);
|
|
|
this.client.subscribe(user, 'audio').then((audioTrack: any) => {
|
|
|
- this.user_published_list.add(user);
|
|
|
+ // this.user_published_list.add(user);
|
|
|
+ if (!this.user_published_list.find((item) => item.uid === user.uid)) {
|
|
|
+ this.user_published_list.push(user);
|
|
|
+ }
|
|
|
audioTrack.setVolume(100);
|
|
|
audioTrack.play();
|
|
|
});
|
|
@@ -267,28 +310,40 @@ export class LiveService {
|
|
|
}
|
|
|
if (mediaType === 'audio') {
|
|
|
user.audioTrack.play();
|
|
|
- this.user_published_list.add(user);
|
|
|
+ // this.user_published_list.add(user);
|
|
|
+ if (!this.user_published_list.find((item) => item.uid === user.uid)) {
|
|
|
+ this.user_published_list.push(user);
|
|
|
+ }
|
|
|
}
|
|
|
});
|
|
|
this.client.on('user-unpublished', async (user: any, mediaType: string) => {
|
|
|
if (mediaType === 'audio') {
|
|
|
console.log('对方已静音');
|
|
|
- this.user_published_list.delete(user);
|
|
|
+ // this.user_published_list.delete(user);
|
|
|
+ let idx = this.user_published_list.findIndex(
|
|
|
+ (item) => item.uid === user.uid
|
|
|
+ );
|
|
|
+ if (idx >= 0) {
|
|
|
+ this.user_published_list.splice(idx, 1);
|
|
|
+ }
|
|
|
}
|
|
|
if (mediaType === 'video') {
|
|
|
console.log('用户取消推流');
|
|
|
- let remoteEle = document.getElementById('video');
|
|
|
- if (remoteEle) {
|
|
|
- remoteEle.textContent = '对方离开直播间';
|
|
|
- }
|
|
|
- //主播离开,停止计时计费
|
|
|
- // if (!this.isAnchor) {
|
|
|
- this.client.leave();
|
|
|
+ // let remoteEle = document.getElementById('video');
|
|
|
+ // if (remoteEle) {
|
|
|
+ // remoteEle.textContent = '对方已离开直播间';
|
|
|
// }
|
|
|
- // history.back()
|
|
|
- this.alertTips('对方已离开直播间');
|
|
|
+ // // this.client.leave();
|
|
|
+ // this.alertTips('对方已离开直播间');
|
|
|
}
|
|
|
});
|
|
|
+ // 注册用户离开事件处理函数
|
|
|
+ this.client.on('user-left', (user: any) => {
|
|
|
+ console.log(`用户 ${user.uid} 离开了频道`);
|
|
|
+ //主播离开,停止计时计费
|
|
|
+ if (user.uid !== 100001) this.client.leave();
|
|
|
+ this.alertTips('对方已离开直播间');
|
|
|
+ });
|
|
|
this.client.on(
|
|
|
'connection-state-change',
|
|
|
(curState: any, prevState: any) => {
|
|
@@ -306,8 +361,8 @@ export class LiveService {
|
|
|
this.isOpenEvaluate = true;
|
|
|
}
|
|
|
console.log(this.router.url);
|
|
|
- if(this.router.url.indexOf('/live/link-room/') == 0)
|
|
|
- curState == 'DISCONNECTED' && history.back();
|
|
|
+ if (this.router.url.indexOf('/live/link-room/') == 0)
|
|
|
+ curState == 'DISCONNECTED' && history.back();
|
|
|
}
|
|
|
console.log('live状态变更:', this.connection_state);
|
|
|
}
|
|
@@ -532,24 +587,43 @@ export class LiveService {
|
|
|
/* 切换摄像头 */
|
|
|
async changeCamera() {
|
|
|
const oldCameras = await AgoraRTC.getCameras(true);
|
|
|
+ console.log('oldCameras:', oldCameras);
|
|
|
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('切换摄像头失败');
|
|
|
- });
|
|
|
+ (await 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.tools['camera'] = !this.tools['camera'];
|
|
|
+ // this.currentUsedDevice.videoDevice = newCamers.deviceId;
|
|
|
+ // this.alertTips('切换摄像头失败');
|
|
|
+ // });
|
|
|
+ this.tools['camera'] = !this.tools['camera'];
|
|
|
+ this.currentUsedDevice.videoDevice = newCamers.deviceId;
|
|
|
return true;
|
|
|
}
|
|
|
-
|
|
|
+ /* 切换美颜 */
|
|
|
+ changeBeauty() {
|
|
|
+ if (!this.tools['glorify']) {
|
|
|
+ this.setBeautyOptions();
|
|
|
+ } else {
|
|
|
+ // 关闭美颜
|
|
|
+ this.processor.setOptions({
|
|
|
+ lighteningContrastLevel: 0,
|
|
|
+ lighteningLevel: 0,
|
|
|
+ smoothnessLevel: 0,
|
|
|
+ sharpnessLevel: 0,
|
|
|
+ rednessLevel: 0,
|
|
|
+ });
|
|
|
+ this.tools['glorify'] = false;
|
|
|
+ }
|
|
|
+ }
|
|
|
/* 提示 */
|
|
|
async alertTips(message: string, title?: string, callBack?: Function) {
|
|
|
this.alert = await this.alertController.create({
|