navigator.mediaDevices.getUserMedia(mediaStreamConstraints)
.then(gotLocalMediaStream).catch(handleLocalMediaStreamError);
}
function gotLocalMediaStream(mediaStream) {
localVideo.srcObject = mediaStream;
}
// constraints 를 사용하면 가져올 미디어 저장 가
const mediaStreamConstraints = {
video: true,
audio: true
};
localStream
전달된 객체는 전역 getUserMedia()
범위에 있으므로 브라우저 콘솔에서 검사할 수 있음. 콘솔을 열고 stream을 입력 하고 Return 키 입력해보면 알 수 있음
통화가 끝날 때마다 RTCPeerConnection을 생성하고 각 끝에 로컬 스트림을 추가합니다 getUserMedia()
네트워크 정보 가져오기 및 공유: 잠재적인 연결 끝점을 ICE 후보 라고 함
로컬 및 원격 설명을 가져오고 공유하는데, [SDP]형식의 로컬 미디어에 대한 메타데이터임.
하온 과 춘식이가 RTCPeerConnection 사용 하여 영상 채팅 한다고 가정.
하온과 춘식은 네트워크 정보 교환.
하온은 핸들러를 사용하여 RTCPeerConnection 객체 생성. onicecandidate (addEventListener('icecandidate')).
localPeerConnection = new RTCPeerConnection(servers);
localPeerConnection.addEventListener('icecandidate', handleConnection);
localPeerConnection.addEventListener(
'iceconnectionstatechange', handleConnectionChange);
getUserMedia() 전달된 스트림을 호출하고 추가.
navigator.mediaDevices.getUserMedia(mediaStreamConstraints).
then(gotLocalMediaStream).
catch(handleLocalMediaStreamError);
function gotLocalMediaStream(mediaStream) {
localVideo.srcObject = mediaStream;
localStream = mediaStream;
trace('Received local stream.');
callButton.disabled = false; // Enable call button.
}
localPeerConnection.addStream(localStream);
trace('Added local stream to localPeerConnection.');
1단계의 핸들러 onicecandidate
는 네트워크 후보가 사용 가능해지면 호출 됨
하온은 직렬화된 후보 데이터를 춘식에게 보냄. 실제 앱에선 시그널링(socket.io)을 사용하여 메시징 서비스 수행.
춘식은 하온에게 후보 메시지를 받으면 addIceCandidate()를 호출하여 원격 피어 설명에 후보를 추가
function handleConnection(event) {
const peerConnection = event.target;
const iceCandidate = event.candidate;
if (iceCandidate) {
const newIceCandidate = new RTCIceCandidate(iceCandidate);
const otherPeer = getOtherPeer(peerConnection);
otherPeer.addIceCandidate(newIceCandidate)
.then(() => {
handleConnectionSuccess(peerConnection);
}).catch((error) => {
handleConnectionFailure(peerConnection, error);
});
trace(`${getPeerName(peerConnection)} ICE candidate:\n` +
`${event.candidate.candidate}.`);
}
}