问题描述
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 (将#修改为@)