离子5:Webrtc远程视频未显示

问题描述

import { Component,OnInit,ElementRef,ViewChild } from '@angular/core';
import { Socket } from 'ngx-socket-io';
import { ToastController } from '@ionic/angular';
import { AppointmentService } from 'src/app/services/appointment.service';

@Component({
  selector: 'app-videocall',templateUrl: './videocall.page.html',styleUrls: ['./videocall.page.scss'],})
export class VideocallPage implements OnInit {

  @ViewChild('localVideo',{ static: true }) localVideo: ElementRef;
  @ViewChild('remoteVideo',{ static: true }) remoteVideo: ElementRef;
  consultationRoomId: any;
  callBtn: any;
  muteBtn: any;
  localStream: MediaStream;
  remoteStream: MediaStream;
  rtcPeerConnection: RTCPeerConnection;



  constructor(public socket: Socket,private toastCtrl: ToastController,private appoint: AppointmentService,private elRef: ElementRef) { }


  ngOnInit() {
    this.callBtn = document.getElementById("call");
    this.muteBtn = document.getElementById("mute");
    var endBtn = document.getElementById("end");
    var divConsultingRoom = document.getElementById("consultingRoom");

    var iceServers = {
      'iceServers': [
        { urls: 'stun:stun.services.mozilla.com' },{ urls: 'stun:stun.l.google.com:19302' },{ urls: 'stun:stun01.sipphone.com' },{ urls: 'stun:stun.ekiga.net' },{ urls: 'stun:stun.fwdnet.net' },{ urls: 'stun:stun.ideasip.com' },{ urls: 'stun:stun.iptel.org' },{ urls: 'stun:stun.rixtelecom.se' },{ urls: 'stun:stun.schlund.de' },{ urls: 'stun:stun1.l.google.com:19302' },{ urls: 'stun:stun2.l.google.com:19302' },{ urls: 'stun:stun3.l.google.com:19302' },{ urls: 'stun:stun4.l.google.com:19302' },{ urls: 'stun:stunserver.org' },{ urls: 'stun:stun.softjoys.com' },{ urls: 'stun:stun.voiparound.com' },{ urls: 'stun:stun.voipbuster.com' },{ urls: 'stun:stun.voipstunt.com' },{ urls: 'stun:stun.voxgratia.org' },{ urls: 'stun:stun.xten.com' },{
          urls: 'turn:192.158.29.39:3478?transport=udp',credential: 'JZEOEt2V3Qb0y27GRntt2u2PAYA=',username: '28224511:1379330808'
        },{
          urls: 'turn:192.158.29.39:3478?transport=tcp',username: '28224511:1379330808'
        }
      ]
    }
    var streamConstraints = { audio: true,video: true };
    var isCaller;

    //this.consultationRoomId = this.appoint.getConsultationId();
    this.consultationRoomId = '1234';
    this.socket.connect();

    this.socket.on('created',(room) => {
      //debugger;
      alert('Starting consultation');
      navigator.mediaDevices.getUserMedia(streamConstraints).then((stream) => {
        this.localStream = stream;
        this.localVideo.nativeElement.srcObject = stream;
        isCaller = true;
      }).catch(function (err) {
        console.log('An error ocurred when accessing media devices',err);
      });
    });

    this.socket.on('joined',(room) => {
      alert('Joining consultation');
      navigator.mediaDevices.getUserMedia(streamConstraints).then((stream) => {
        this.localStream = stream;
        this.localVideo.nativeElement.srcObject = stream;
        this.socket.emit('ready',this.consultationRoomId);
      }).catch(function (err) {
        console.log('An error ocurred when accessing media devices',err);
      });
    });

    this.socket.on('disconnect',(room) => {
      console.log('Doctor has ended the consultation>>>' + room);
    });

    this.socket.on('candidate',(event) => {
      var candidate = new RTCIceCandidate({
        sdpMLineIndex: event.label,candidate: event.candidate
      });
      this.rtcPeerConnection.addIceCandidate(candidate);
    });

    this.socket.on('ready',() => {
      if (isCaller) {
        this.rtcPeerConnection = new RTCPeerConnection(iceServers);
        this.rtcPeerConnection.onicecandidate = this.onIceCandidate;
        this.rtcPeerConnection.ontrack = this.onAddStream;
        this.rtcPeerConnection.addTrack(this.localStream.getTracks()[0],this.localStream);
        this.rtcPeerConnection.addTrack(this.localStream.getTracks()[1],this.localStream);
        this.rtcPeerConnection.createOffer()
          .then(sessionDescription => {
            this.rtcPeerConnection.setLocalDescription(sessionDescription);
            this.socket.emit('offer',{
              type: 'offer',sdp: sessionDescription,room: this.consultationRoomId
            });
          })
          .catch(error => {
            console.log(error)
          })
      }
    });

    this.socket.on('offer',(event) => {
      if (!isCaller) {
        this.rtcPeerConnection = new RTCPeerConnection(iceServers);
        this.rtcPeerConnection.onicecandidate = this.onIceCandidate;
        this.rtcPeerConnection.ontrack = this.onAddStream;
        this.rtcPeerConnection.addTrack(this.localStream.getTracks()[0],this.localStream);
        this.rtcPeerConnection.setRemoteDescription(new RTCSessionDescription(event));
        this.rtcPeerConnection.createAnswer()
          .then(sessionDescription => {
            this.rtcPeerConnection.setLocalDescription(sessionDescription);
            this.socket.emit('answer',{
              type: 'answer',room: this.consultationRoomId
            });
          })
          .catch(error => {
            console.log(error)
          })
      }
    });

    this.socket.on('answer',(event) => {
      console.log("on answer>>>>" + event);
      this.rtcPeerConnection.setRemoteDescription(new RTCSessionDescription(event));
    })

  }

  call() {
    //this.divConsultingRoom.style = "display: block;";
    this.socket.emit('create or join',this.consultationRoomId);
  }

  mute() {
    if (this.muteBtn.innerHTML == "Mute") {
      this.localStream.getAudioTracks()[0].enabled = false;
      this.muteBtn.innerHTML = "Unmute";
    }
    else {
      this.localStream.getAudioTracks()[0].enabled = true;
      this.muteBtn.innerHTML = "Mute";
    }
  }

  end() {
    this.socket.emit('disconnect',this.consultationRoomId);
  }

  onIceCandidate = (event) => {
    if (event.candidate) {
      console.log('sending ice candidate');
      this.socket.emit('candidate',{
        type: 'candidate',label: event.candidate.sdpMLineIndex,id: event.candidate.sdpMid,candidate: event.candidate.candidate,room: this.consultationRoomId
      })
    }
  }

  onAddStream = (event) => {
    this.remoteVideo.nativeElement.srcObject = event.streams[0];
    this.remoteStream = event.streams[0];
  }

}

下面也是HTML页面

<ion-content>
    <div id="consultingRoom">
        <video id="localVideo" #localVideo inline autoplay></video>
        <video id="remoteVideo" #remoteVideo inline autoplay></video>
    </div>

    <ion-button id="call" color="primary" (click)="call()">Call</ion-button>
    <ion-button id="mute" color="secondary" (click)="mute()">Mute</ion-button>
    <ion-button id="end" color="tertiary" (click)="end()">End</ion-button>
</ion-content>

addStreamMethod中的event.streams [0]对象显示具有接收者ID的远程MediaStream,但前端的remoteVideo元素仍为空白。 信令服务器是在AWS EC2实例上运行的节点套接字服务器。

以下是远程媒体流的调试

RemoteMediaStream console debug

下面是来自Chrome的webrtc内部日志

9/3/2020,4:39:00 PM    
transceiverAdded
9/3/2020,4:39:00 PM    
createOffer
options: {offerToReceiveVideo: -1,offerToReceiveAudio: -1,voiceActivityDetection: true,iceRestart: false}
9/3/2020,4:39:00 PM    negotiationneeded
9/3/2020,4:39:00 PM    
createOfferOnSuccess
9/3/2020,4:39:00 PM    
setLocalDescription
9/3/2020,4:39:00 PM    
transceiverModified
9/3/2020,4:39:00 PM    
signalingstatechange
9/3/2020,4:39:00 PM    setLocalDescriptionOnSuccess
9/3/2020,4:39:00 PM    
icegatheringstatechange
9/3/2020,4:39:00 PM    
icecandidate (host)
9/3/2020,4:39:00 PM    
icecandidateerror
9/3/2020,4:39:00 PM    
icecandidate (srflx)
9/3/2020,4:39:00 PM    
setRemoteDescription
9/3/2020,4:41:38 PM    
signalingstatechange
9/3/2020,4:41:38 PM    setRemoteDescriptionOnSuccess
9/3/2020,4:41:39 PM    
icecandidate (srflx)
9/3/2020,4:41:39 PM    
icecandidateerror
9/3/2020,4:41:39 PM    
icegatheringstatechange
complete
9/3/2020,4:41:39 PM    
addIceCandidate (host)
9/3/2020,4:41:39 PM    
iceconnectionstatechange
checking
9/3/2020,4:41:39 PM    
iceconnectionstatechange (legacy)
checking
9/3/2020,4:41:39 PM    
connectionstatechange
connecting
9/3/2020,4:41:39 PM    
addIceCandidate (srflx)
9/3/2020,4:41:54 PM    
iceconnectionstatechange
disconnected
9/3/2020,4:41:54 PM    
iceconnectionstatechange (legacy)
Failed
9/3/2020,4:41:54 PM    
connectionstatechange
Failed

目前,我仅在浏览器上进行测试,尚未在Android和IOS上进行测试 请让我知道我在想什么?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)