# 3.8 Senders & 3.9 STUN

이원규·2022년 6월 19일

Zoom clone coding

목록 보기
17/18

버그 수정(몇가지 문제점 수정)

Sender

Sender MDN

  • Sender: Sender는 우리의 peer로 보내는 media stream track을 컨트롤하게 해줌. 우리는 이걸 이용해 Stream을 음소거 할 수도 있고, peer-to-peer연결의 track을 변경할 수도 있음.

1. 화면이 연결된 상태에서 비디오 장치를 바꾸면 반영이 안됨

-> 우리가 peer연결을 만드는 동시에, track을 추가했었음. 이제 우리가 할 것은 그 track을 바꾸는 것임. 카메라를 바꿀 때마다 우리는 서로 다른 id로 new Stream을 만듦. 이제 우리가 해야하는 건 peer한테 줄 stream을 업데이트 하는 것임. 왜냐하면 우리가 peer-to-peer연결을 만들 때, 그 peer연결에 track도 추가하기 때문임.
-> 문제점: 우리가 비디오 장치를 바꿀 때마다 stream을 통째로 바꾸는데 user한테 보내는 track은 바꾸지 않고 있음. 그래서 우리는 Real time communication 연결의 track을 바꿔야함. replacTrack이용.

-> app.js
-> peer연결에서 보내는 track에서 video track부분을 새 Stream(비디오 장치를 바꿀 때마다 Stream
이 새로고침 됨.)의 video Track으로 보내주는 작업을 하는 것임.

//밑은 코드는 원래 잇던 handleCameraChange함수를 수정해주는 것임.(정확히는 코드 추가)
async function handleCameraChange(){
    await getMedia(camerasSelect.value);
    if(myPeerConnection){
        const videoTrack = myStream.getVideoTracks()[0];//이미 이 함수 첫째줄에서 새로운 stream으로 바뀌었기 떄문에 여기서 그냥 videoTrack을 가져와도 바뀐 track을 가져올 것임.
        //console.log(myPeerConnection.getSenders()); -> RTCRtpSender에 관한 data가 있음. 여기서 track에서 kind:video인 Sender를 보면 됨,
        const videoSender = myPeerConnection.getSenders().find((sender) => sender.track.kind === "video");//peerConnection에서 Send하고 있는 정보의 videoTrack부분을 가져옴.
        videoSender.replaceTrack(videoTrack);//가져온 Sender의 viedoTrack부분을 새로운 Stream의 비디오 트랙으로 변경해줌
    };
  
  
/*여기서 맨 마지막 줄을 보면 peer연결에 track과 stream을 보내주는 것을 볼 수 있음.
function makeConnection(){
    myPeerConnection = new RTCPeerConnection();// 1단계: 두 브라우저 사이에 peer connection 만듦
    myPeerConnection.addIceCandidate("icecandidate", handleIce);//12단계 : IceCandidate 생성
    myPeerConnection.addEventListener("addStream", handleAddStream);//15 단계: 상대방 stream add하기 및 media 불러오기
    //console.log(myStream.getTracks()); //-> video & Audio Tracks가 담겨있음. 즉 우리 stream의 데이터임.
    myStream.getTracks().forEach((track) => myPeerConnection.addTrack(track, myStream));//2단계 : 내 stream데이터를 peer연결에 넣어주는 것임 // 새로운 장치를 사용하면 Stream을 새로 바꾸는데, 여기서도 새로운 Stream을 보냄.
}*/

local tunnel

-> local tunnel: 서버를 전세계와 공유하게 해줌.(물론 영원히 무료는 아니고, 일시적으로 무료)
-> local tunnel을 사용하면 우리 서버의 url을 생성할 수 있음. 그러면 폰으로 그 url에 접속해서 우리걸 테스트해 볼 수 있음.

설치: npm i localtunnel -> npm i -g localtunnel(글로벌 버전: 전세계 공유)
사용법:
1. 터미널에 lt을 적으면 커맨드를 적을 수 있음.
2. lt --port 3000 -> 적으면 url을 생성해줄 것임. 즉, lt --port 우리가쓰는port
3. 여기서 url 그냥 들어가면 실행이 안됨.
-> vsc에서 터미널 - 분할 터미널로 한쪽은 node 서버 실행, 한쪽은 lt --port 3000
하면 잘 작동하네요.

2. 휴대폰으로 연결했을 때, 작동하지 않음.

-> 먼저 이 웹사이트를 public으로 만들어서 폰으로 테스트 할 수 있도록 하자
-> npm i localtunnel
-> npm i -g localtunnel
-> lt
-> lt --port 3000
-> 나온 url로 폰으로 접속해서 되는지 확인해보기
-> 에러 혹은 연결 미스가 뜰 거임.(Stun Service때문.)
-> 폰과 컴퓨터가 같은 wifi에 연결돼 있지 않으면 오류가 생김

STUN server

  • STUN server: 서버에 들어오는 장치에 공용 주소를 주어 연결되도록 하는 것임, 장치는 공용 주소를 알아야 되거든. 그래야 다른 네트워크에 있는 장치들이 연결될 수 있음.
    -> 따라서 STUN 서버가 필요함. STUN server: 컴퓨터가 공유 IP주소를 찾게해줌.
    -> STUN서버는 어떤 것을 req하면 인터넷에 요청한 사람이 누군지를 알려주는 서버. 서버는
    나의 공용 IP를 알려줄 것임.
    -> STUN서버를 만들기엔 우리가 아직 한참 모자라서(나중에 ㄹㅇ WebRTC 이용해 뭘 만들거나
    실제 서비스나 전문적인 뭔가를 가지고 싶다면 되고 싶으면 STUN서버 다루고 관리할 줄 알아
    야함. 내 애플리케이션은여기에 의존 ㄴ ㄴ)
    , 구글이 제공하는 무료 STUN서버 이용.
    -> 우린 비디오를 주고받기 위해 STUN서버 이용하는 것이 아니라, 공용주소를 알아내기 위해 이
    용.
    -> 또 다른 에러 뜨면 강의 들가서 댓글 찾아보삼.강의

-> 밑의 본문 덕분에 폰 화면에서 상대방 얼굴 안 나오던거 해결됨.

myPeerConnection.addEventListener("addstream", handleAddStream)
여기서 "appstream" 은 safari 기반 브라우저(최신 아이폰 등)에선 동작 안할 수도 있습니다.
참고: https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/addstream_event

저는 아래 내용으로 수정하여 아이폰에서도 상대방 영상 나오는거 확인하였습니다.

myPeerConnection.addEventListener("track", handleTrack)

function handleTrack(data) {
console.log("handle track")
const peerFace = document.querySelector("#peerFace")
peerFace.srcObject = data.streams[0]
}

참고: https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/track_event

-> 실제로 이렇게 해서 해결됨.

-> app.js: SUTN 서버 구글에서 가져와 이용하기,

//STUN서버 추가
function makeConnection(){
    myPeerConnection = new RTCPeerConnection({
        iceServers:[
            { urls: "stun:stun.stunprotocol.org:3478"},
            { urls: "stun:stun.l.google.com:19302"},
        ],
    });// STUN server추가
    myPeerConnection.addEventListener("icecandidate", handleIce);//12단계 : IceCandidate 생성
    myPeerConnection.addEventListener("track", handleTrack);//15 단계: 상대방 stream add하기 및 media 불러오기
    //console.log(myStream.getTracks()); //-> video & Audio Tracks가 담겨있음. 즉 우리 stream의 데이터임.
    myStream.getTracks().forEach((track) => myPeerConnection.addTrack(track, myStream));//2단계 : 내 stream데이터를 peer연결에 넣어주는 것임 // 새로운 장치를 사용하면 Stream을 새로 바꾸는데, 여기서도 새로운 Stream을 보냄.
}
//(바로 위 함수(makeConnection))addstream -> track / handleTrack
myPeerConnection.addEventListener("track", handleTrack);

//handleAddStream -> handleTrack
function handleTrack(data){//15 단계: 상대방 stream add하기 및 media 불러오기
    console.log(data.streams);// <- 상대 브라우저 stream
    //console.log(myStream);// <- 내 stream
    const peerFace = document.getElementById("peerFace");
    peerFace.srcObject = data.streams[0];
}
  • console.log(data.streams):

결과

profile
github: https://github.com/WKlee0607

0개의 댓글