WebRTC Offers

Jeong Ha Seung·2021년 11월 7일

Peer-to-Peer

app.js

const frontendsocket = io();

const myface = document.getElementById("myface");
const mute = document.getElementById("mute");
const camera = document.getElementById("camera");
const camerasSelect = document.getElementById("cameras");

const call = document.getElementById("call");

call.hidden = true;

let myStream;
let muted = false;
let cameraOff = false;
let roomName;
let myPeerConnection;

async function getCamera() {
  try {
    const devices = await navigator.mediaDevices.enumerateDevices(); //장치 리스트 가져오기
    const cameras = devices.filter((device) => device.kind === "videoinput"); //videoinput만 필터링
    const CurrentCamera = myStream.getVideoTracks()[0];

cameras.forEach((camera) => {
  const option = document.createElement("option");
  option.value = camera.deviceId; //카메라의 고유 값을 value에 넣기
  option.innerText = camera.label; //사용자가 선택할 때는 label을 보고 선택 가능하게 하기
  if (CurrentCamera.lable === camera.label) {
    option.selected = true;
  }
  camerasSelect.appendChild(option); //카메라 정보를 option 항목에 넣어주기
 });
  } catch (e) {
    console.log(e);
  }
}

async function getMedia(deviceId) {
  const initialConstraints = {
    //deviceId가 없을 때 실행
    audio: true,
    video: { facingMode: "environment" }, //카메라가 전후면에 달려있을 >	경우 후면 카메라의 정보를 받음
  };
  const cameraConstraints = {
  //deviceId가 있을 때 실행
    audio: true,
    video: { deviceId: { exact: deviceId } },
  };
  try {
    myStream = await navigator.mediaDevices.getUserMedia(
      deviceId ? cameraConstraints : initialConstraints
    );
    myface.srcObject = myStream;
    if (!deviceId) {
  //처음 딱 1번만 실행(getMedia를 실행할 때만)
      await getCamera();
    }
  } catch (e) {
    console.log(e);
  }
}

function handleMuteButton() {
  myStream
    .getAudioTracks()
    .forEach((track) => (track.enabled = !track.enabled));
  if (!muted) {
    mute.innerText = "Unmute";
    muted = true;
  } else {
    mute.innerText = "Mute";
    muted = false;
  }
}
function handleCameraButton() {
  console.log(myStream.getVideoTracks());
  myStream
    .getVideoTracks()
    .forEach((track) => (track.enabled = !track.enabled));
  if (!cameraOff) {
    camera.innerText = "Turn Camera On";
    cameraOff = true;
  } else {
    camera.innerText = "Turn Camera Off";
    cameraOff = false;
  }
}

async function handleCameraChange() {
  await getMedia(camerasSelect.value);
}
mute.addEventListener("click", handleMuteButton);
camera.addEventListener("click", handleCameraButton);
camerasSelect.addEventListener("input", handleCameraChange); //카메라 변경 확인

//Welcome Form (choose a room)
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");
  frontendsocket.emit("join_room", input.value, startMedia);
  roomName = input.value;
  input.value = "";
}

welcomeForm.addEventListener("submit", handleWelcomeSubmit);

// Socket Code
frontendsocket.on("welcome", async () => {
  const offer = await myPeerConnection.createOffer(); //내가 누구인지를 알려주는 내용
  myPeerConnection.setLocalDescription(offer);// 내 위치정보를 연결
  console.log("sent the offer");
  frontendsocket.emit("offer", offer, roomName);
});

frontendsocket.on("offer", (offer) => {
  console.log(offer);
});

//RTC code

function makeConnection() {
  myPeerConnection = new RTCPeerConnection(); //RTCPeerConnection 인스턴스 생성
  myStream
    .getTracks()
    .forEach((track) => myPeerConnection.addTrack(track, myStream)); //영상,음성 트랙을 myPeerConnection에 추가해준다. ->P2P 연결
}

server.js

import http from "http";
import SocketIO from "socket.io";
import { instrument } from "@socket.io/admin-ui";
import express from "express";

const app = express();

const PORT = 3000;

app.set("view engine", "pug");
app.set("views", __dirname + "/views");
// 기본 path를 /public으로 설정
app.use("/public", express.static(__dirname + "/public"));
app.get("/", (_, res) => res.render("home"));
app.get("/*", (_, res) => res.redirect("/"));

const httpServer = http.createServer(app);
const wsServer = SocketIO(httpServer);

wsServer.on("connection", (backendsocket) => {
  backendsocket.on("join_room", (roomName, done) => {
    backendsocket.join(roomName);
    done();
    backendsocket.to(roomName).emit("welcome"); //특정 room에 이벤트 보내기
  });
  backendsocket.on("offer", (offer, roomName) => {
    backendsocket.to(roomName).emit("offer", offer);
  }); //offer 이벤트가 들어오면 roomName에 있는 모두에게 offer 이벤트를 전달하면서 offer를 뿌린다.
});

const handleListen = () => console.log(`Listening on >	http://localhost:${PORT}`);
httpServer.listen(PORT, handleListen);
profile
블로그 이전했습니다. https://morethan-haseung-log.vercel.app

0개의 댓글