실습 (webRTC offer)

3909 단어 socket.iosocket.io
const socket = io();

/*
 * DOM
 */
const myFace = document.getElementById('myFace');
const muteBtn = document.getElementById('mute');
const cameraBtn = document.getElementById('camera');
const camerasSelect = document.getElementById('cameras');
const call = document.getElementById('call');

call.hidden = true;

/*
 * State
 */
let myStream;
let muted = false;
let cameraOff = false;
let myPeerConnection;

/*
 * Media Functions
 */
async function getCameras() {
  try {
    const devices = await navigator.mediaDevices.enumerateDevices();
    const cameras = devices.filter((device) => device.kind === 'videoinput');
    cameras.forEach((camera) => {
      const option = document.createElement('option');
      option.value = camera.deviceId;
      option.innerText = camera.label;
      camerasSelect.appendChild(option);
    });
  } catch (e) {
    console.log(e);
  }
}

// ! Camera 정보 받기
async function getMedia(deviceId) {
  try {
    const initialConstrains = {
      audio: true,
      video: { facingMode: 'user' },
    };
    const cameraConstraints = {
      audio: true,
      video: { deviceId: { exact: deviceId } },
    };

    myStream = await navigator.mediaDevices.getUserMedia(
      deviceId ? cameraConstraints : initialConstrains
    );
    myFace.srcObject = myStream;

    if (!deviceId) {
      await getCameras();
    }
  } catch (e) {
    console.log(e);
  }
}

// ! Audio Toggle
function handleMuteClick() {
  myStream
    .getAudioTracks()
    .forEach((track) => (track.enabled = !track.enabled));
  if (!muted) {
    muteBtn.innerText = 'Unmute';
    muted = true;
  } else {
    muteBtn.innerText = 'Mute';
    muted = false;
  }
}

// ! Camera Toggle
function handleCameraClick() {
  myStream
    .getVideoTracks()
    .forEach((track) => (track.enabled = !track.enabled));
  if (cameraOff) {
    cameraBtn.innerText = 'Turn Camera Off';
    cameraOff = false;
  } else {
    cameraBtn.innerText = 'Turn Camera On';
    cameraOff = true;
  }
}

async function handleCameraChange() {
  await getMedia(camerasSelect.value);
}

/*
 * Welcome Form - 시작 컴포넌트는 분리!
 */
const welcome = document.getElementById('welcome');
const welcomeForm = welcome.querySelector('form');

async function startMedia() {
  welcome.hidden = true;
  call.hidden = false;
  await getMedia();
  makeConnection();
}

function handleWelcomeSubmit(event) {
  event.preventDefault();
  const input = welcomeForm.querySelector('input');
  socket.emit('join_room', input.value, startMedia);
  roomName = input.value;
  input.value = '';
}

welcomeForm.addEventListener('submit', handleWelcomeSubmit);

/*
 * Socket Code
 */
socket.on('welcome', async () => {
  const offer = await myPeerConnection.createOffer();
  myPeerConnection.setLocalDescription(offer);
  console.log('sent the offer');
  socket.emit('offer', offer, roomName);
});

socket.on('offer', (offer) => {
  console.log(offer);
});

/*
 * RTC Code
 */
function makeConnection() {
  myPeerConnection = new RTCPeerConnection();
  myStream
    .getTracks()
    .forEach((track) => myPeerConnection.addTrack(track, myStream));
}

/*
 * DOM Callback
 */
muteBtn.addEventListener('click', handleMuteClick);
cameraBtn.addEventListener('click', handleCameraClick);
camerasSelect.addEventListener('input', handleCameraChange);

=> https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/createOffer

offer는 P2P 커넥션에서 필요한 구성요소를 전달하기 위한 설정값들을 전달한다. 설정값이라 하면 브라우저 연결에 필요한 값들을 의미한다.

socket emit 정리
join_room: 초기 유저가 진입시 서버에 소켓 연결을 시작하고 클라이언트에서 영상 및 음향에 대한 정보를 세팅한다.
welcome: 클라이언트에 webRTC 커넥션을 만들고 로컬 정보를 만든 다음, 해당방의 소켓에 webRTC에 연결을 전달한다.

연결된 요소를 확인

좋은 웹페이지 즐겨찾기