warrior пре 4 месеци
родитељ
комит
c7f40b0a0d

BIN
projects/live-app/public/img/挂断.png


+ 21 - 3
projects/live-app/src/app/components/live/live.component.html

@@ -1,7 +1,25 @@
 <div class="video_box" id="video-box">
   <div class="camera_box">
-    <canvas id="canvas" width="100%" height="100%" style="display:none"></canvas>
-    <div class="video" id="video" width="100%" height="100%">
+    <!-- 主屏 -->
+    <div
+      class="{{ changeScreen ? 'vice-video' : 'video' }}"
+      id="video"
+      width="100%"
+      height="100%"
+      (click)="onChangeScreen('big')"
+    >
+      等待连接
     </div>
+    <!-- 副屏 -->
+    <div
+      class="{{ changeScreen ? 'video' : 'vice-video' }}"
+      id="vice-video"
+      width="100%"
+      height="100%"
+      (click)="onChangeScreen('small')"
+    >
+      网络不佳
+    </div>
+    <!-- <canvas id="canvas" width="100%" height="100%" style="display:none"></canvas> -->
   </div>
-</div>
+</div>

+ 21 - 2
projects/live-app/src/app/components/live/live.component.scss

@@ -4,14 +4,33 @@
   height: 100vh;
   // border-radius: 2px;
   // border: 0.5px solid #a1a1a1;
-  position: absolute;
+  position: relative;
   .camera_box {
     // margin-top: 10px;
-    position: relative;
+    // position: relative;
     .video {
       // border-radius: 8px;
       width: 100%;
       height: 100vh;
+      color: white;
+      font-size: 14px;
+      display: flex;
+      align-items: center;
+      justify-content: center;
+    }
+    .vice-video {
+      width: 80px;
+      height: 140px;
+      background: black;
+      position: absolute;
+      top: 100px;
+      right: 10px;
+      color: white;
+      font-size: 14px;
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      z-index: 1;
     }
   }
 }

+ 50 - 33
projects/live-app/src/app/components/live/live.component.ts

@@ -38,6 +38,7 @@ export class LiveComponent implements OnInit {
     audioTrack: null,
     videoTrack: null,
   };
+  changeScreen: boolean = false; //大小屏切换
   constructor(
     public toastController: ToastController,
     private loadingCtrl: LoadingController,
@@ -47,7 +48,7 @@ export class LiveComponent implements OnInit {
   ) {}
 
   ngOnInit() {
-    this.client = AgoraRTC.createClient({ mode: 'live', codec: 'h264' });
+    this.client = AgoraRTC.createClient({ mode: 'rtc', codec: 'h264' });
     AgoraRTC.enableLogUpload();
     this.getDevices();
     this.activateRoute.paramMap.subscribe(async (params) => {
@@ -69,9 +70,8 @@ export class LiveComponent implements OnInit {
         const videoDevices = devices.filter(function (device: any) {
           return device.kind === 'videoinput';
         });
-
-        var selectedMicrophoneId = audioDevices[0].deviceId;
-        var selectedCameraId = videoDevices[0].deviceId;
+        let selectedMicrophoneId = audioDevices[0].deviceId;
+        let selectedCameraId = videoDevices[0].deviceId;
         return Promise.all([
           AgoraRTC.createCameraVideoTrack({ cameraId: selectedCameraId }),
           AgoraRTC.createMicrophoneAudioTrack({
@@ -96,18 +96,18 @@ export class LiveComponent implements OnInit {
     queryProfile.equalTo('user', this.room?.get('user').id);
     queryProfile.notEqualTo('isDeleted', true);
     this.profile = await queryProfile.first();
-    this.getToken()
+    this.getToken();
   }
   async getToken() {
     let baseurl = 'https://server.fmode.cn/api/webrtc/build_token';
     let reqBody = {
-      company:'9aMy8gAuey',// this.aiSer.company,
+      company: '9aMy8gAuey', // this.aiSer.company,
       profile: this.profile?.id,
       channelName: this.profile?.id,
       // department: localStorage.getItem('department'),
       // exam: localStorage.getItem('exam'),
     };
-    let data: any = await this.http.httpRequst(baseurl, reqBody,'POST');
+    let data: any = await this.http.httpRequst(baseurl, reqBody, 'POST');
     console.log(data);
     if (data.code == 200) {
       (this.options.token = data.data.token),
@@ -120,41 +120,28 @@ export class LiveComponent implements OnInit {
   // 进入频道
   async join() {
     let data = await Promise.all([
-      // join the channel
       this.client.join(
         this.options.appid,
         this.options.channel,
         this.options.token,
         111111
       ),
-
-      // create local tracks, using microphone and camera
+      /* 创建音频和视频轨道 */
       AgoraRTC.createMicrophoneAudioTrack(),
       AgoraRTC.createCameraVideoTrack(),
     ]);
-    await this.client.setClientRole('host');
+    // await this.client.setClientRole('host');
     this.localTracks.audioTrack = data[1];
     this.localTracks.videoTrack = data[2];
-    this.localTracks.videoTrack.play('video');
+    let remoteEle = document.getElementById('vice-video');
+    if (remoteEle) {
+      remoteEle.textContent = '';
+    }
+    this.localTracks.videoTrack.play('vice-video'); //播放自己视频渲染
     let publish = await this.client.publish(Object.values(this.localTracks));
-
-    // getCurrentFrameData 获取当前渲染的视频帧数据。
-    // 订阅监考端音视频
-    this.client.on('user-published', async (user: any, mediaType: any) => {
-      console.log('user-published');
-      await this.client.subscribe(user, mediaType);
-      if (mediaType == 'audio' && user.uid != 333333) {
-        console.log(mediaType, user);
-        //远端老师发出语音对话提示
-        // this.createBasicNotification('请注意,监考老师已向你发出语音通话!', 'info', '语音通话提示')
-        const remoteAudioTrack = user.audioTrack;
-        remoteAudioTrack.setVolume(100);
-        remoteAudioTrack.play();
-      }
-    });
-    // 查询远端用户是否存在小程序端用户
     this.joinReady();
   }
+  /* 订阅远程视频 */
   async joinReady() {
     console.log(this.client.remoteUsers);
     let wxRemoteUsers = this.client.remoteUsers.find((item: any) => {
@@ -163,16 +150,46 @@ export class LiveComponent implements OnInit {
       }
     });
     console.log(wxRemoteUsers);
+    this.client.on('user-joined', (user: any) => {
+      console.log(user, `${user.uid} 加入频道`);
+    });
     this.client.on('user-published', async (user: any, mediaType: any) => {
-      if (user.uid == 333333) {
-        await this.client.subscribe(user, mediaType);
-        console.log('用户推流成功');
+      console.log('用户推流成功');
+      // if (user.uid == 333333) {
+      await this.client.subscribe(user, mediaType);
+      // }
+      let remoteEle = document.getElementById('video');
+      if (remoteEle) {
+        remoteEle.textContent = '';
+      }
+      if (mediaType === 'video') {
+        user.videoTrack.play(`video`);
+      }
+      if (mediaType === 'audio') {
+        user.audioTrack.play();
       }
     });
     this.client.on('user-unpublished', (user: any) => {
-      if (user.uid == 333333) {
-        console.log('用户取消推流');
+      let remoteEle = document.getElementById('video');
+      if (remoteEle) {
+        remoteEle.textContent = '对方离开直播间';
       }
+      // if (user.uid == 333333) {
+      console.log('用户取消推流');
+      // }
     });
   }
+  /* 监听屏幕切换 */
+  onChangeScreen(type: string) {
+    if (type == 'big' && this.changeScreen) {
+      this.changeScreen = !this.changeScreen;
+    } else if (type == 'small' && !this.changeScreen) {
+      this.changeScreen = !this.changeScreen;
+    }
+  }
+  ngOnDestroy(): void {
+    /* 离开房间 */
+    this.client.leave();
+    console.log(111);
+  }
 }

+ 55 - 7
projects/live-app/src/moduls/live/link-page/link-page.component.html

@@ -1,16 +1,20 @@
 <ion-content class="content">
   <div class="nav-data">
     <div class="room-data">
-          <img class="avatar" [src]="room?.get('user')?.get('avatar')" alt="avatar" />
+      <img
+        class="avatar"
+        [src]="room?.get('user')?.get('avatar')"
+        alt="avatar"
+      />
       <div class="profile-title">
-        <div class="profile-name">{{ room?.get('user')?.get('nickname') }}</div>
+        <div class="profile-name">{{ room?.get("user")?.get("nickname") }}</div>
         <div class="level">LV:33</div>
       </div>
       <ion-icon
-      (click)="onCollection()"
-      name="heart-circle-sharp"
-      [style.color]="isFollow ? '#fe454e' : '#fff'"
-    ></ion-icon>
+        (click)="onCollection()"
+        name="heart-circle-sharp"
+        [style.color]="isFollow ? '#fe454e' : '#fff'"
+      ></ion-icon>
     </div>
     <div class="report">
       <ion-icon name="warning-outline"></ion-icon>
@@ -20,4 +24,48 @@
     </div>
   </div>
   <app-live></app-live>
-</ion-content>
+  <div class="tools">
+    <div class="row">
+      <div class="row-li">
+        <div class="icon-box">
+          <ion-icon class="icon" name="mic-circle"></ion-icon>
+        </div>
+        <div class="label">麦克风已关</div>
+      </div>
+    </div>
+    <div class="row">
+      <div class="row-li">
+        <div class="icon-box">
+          <ion-icon class="icon" name="notifications"></ion-icon>
+        </div>
+        <div class="label">麦克风已关</div>
+      </div>
+      <div class="row-li">
+        <div class="icon-box">
+          <ion-icon class="icon" name="notifications-off"></ion-icon>
+        </div>
+        <div class="label">麦克风已关</div>
+      </div>
+    </div>
+    <div class="row">
+      <div class="row-li">
+        <div class="icon-box">
+          <ion-icon class="icon" name="keypad"></ion-icon>
+        </div>
+        <div class="label">聊天</div>
+      </div>
+      <div class="row-li">
+        <div class="icon-box">
+          <img class="icon" src="/img/挂断.png" alt="" class="icon-img" />
+        </div>
+        <div class="label">挂断</div>
+      </div>
+      <div class="row-li">
+        <div class="icon-box">
+          <ion-icon class="icon" name="gift"></ion-icon>
+        </div>
+        <div class="label">麦克风已关</div>
+      </div>
+    </div>
+  </div>
+</ion-content>

+ 43 - 0
projects/live-app/src/moduls/live/link-page/link-page.component.scss

@@ -62,4 +62,47 @@
       }
     }
   }
+  .tools{
+    position: fixed;
+    bottom: 0;
+    left: 0;
+    width: 100%;
+    height: 260px;
+    padding: 10px;
+    .row{
+      display: flex;
+      justify-content: space-between;
+      .row-li{
+        display: flex;
+        justify-content: center;
+        align-items: center;
+        justify-content: center;
+        flex-direction: column;
+        color: #fff;
+        width: 100px;
+        margin-bottom: 6px;
+        .label{
+          margin-top: 6px;
+          font-size: 14px;
+        }
+        .icon-box{
+          background-color: rgba(0, 0, 0, 0.4);
+          // border: 1px solid rgba(255, 255, 255, 0.3);
+          border-radius: 50%;
+          padding: 4px;
+          display: flex;
+          align-items: center;
+          justify-content: center;
+          ion-icon{
+            color: white;
+            font-size: 30px;
+          }
+          img{
+            width: 50px;
+            height: 50px;
+          }
+        }
+      }
+    }
+  }
 }

+ 1 - 1
projects/live-app/src/services/http.service.ts

@@ -59,7 +59,7 @@ export class HttpService {
       body: method !== 'GET' ? JSON.stringify(reqBody) : undefined,
     });
     let data = await result.json();
-    console.log(data);
+    // console.log(data);
     return data;
   }
 }