ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [노마드코더] 줌 클론 코딩 - 7. 비디오 캠, 마이크 음성
    Dev/클론 코딩 2023. 2. 15. 20:20
    728x90

    이전 채팅 구현을 모두 지우고 다시 새로 기능을 구현한다.

     

    User Video 영상 가져오기

    home.pug

    doctype html
    html(lang="en")
        head
            meta(charset="UTF-8")
            meta(http-equiv="X-UA-Compatible", content="IE=edge")
            meta(name="viewport", content="width=device-width, initial-scale=1.0")
            title Noom
            link(rel="stylesheet", href="https://unpkg.com/mvp.css")
        body  
            header
                h1 Noom
            main
                div#myStream
                    video#myFace(autoplay, playsinline, width="400", height="400")
                    button#mute Mute
                    button#camera Turn Camera Off
            script(src="/socket.io/socket.io.js")
            script(src="/public/js/app.js")

    - 사용자 비디오 영상을 가져오기 위한 video 태그와 음소거, 카메라 온오프를 위한 버튼을 추가했다.

     

    server.js

    import http from "http"; // 기본 설치된 라이브러리
    import express from "express"; //npm i express 설치 후 import
    import SocketIO from "socket.io";
    import { instrument } from "@socket.io/admin-ui";
    import { Server } from "socket.io"
    // import WebSocket from "ws";
    
    const app = express(); // app이라는 변수에 express를 가져와 생성
    
    app.set("view engine", "pug"); // 뷰 엔진 pug 사용
    app.set("views", __dirname + "/views"); // pug의 디렉토리 경로 설정
    app.use("/public", express.static(__dirname + "/public")); // public 폴더 유저에게 공개
    // 라우트 핸들러
    app.get("/", (req, res) =>res.render("home")); // 홈페이지로 이동할 때 사용될 템플릿 렌더링
    app.get("/*", (req,res) => res.redirect("/")); // 홈페이지 내 어드 페이지에 접근해도 홈으로 연결되도록 리다이렉트
    
    // http 서버 위에 webSocket서버를 생성
    //http로 만든 server는 필수 X - 이렇게 하면 http / ws 서버 모두 같은 3000번 포트를 이용해서 돌릴 수 있다.
    const httpServer = http.createServer(app);// app은 requestlistener 경로 - express application으로부터 서버 생성
    const wsServer = SocketIO(httpServer);
    
    const handleListen = () => console.log('Listening on http://localhost:3000');
    httpServer.listen(3000, handleListen);

    - server.js는 앞서 채팅과 관련된 코드를 모두 지웠다.

     

    app.js

    const socket = io(); // socket io 이용 백엔드 서버와 연결
    // 각 요소 가져오기
    const myFace = document.getElementById("myFace"); // video 태그 요소
    const muteBtn = document.getElementById("mute");
    const cameraBtn = document.getElementById("camera");
    
    let myStream;
    let muted = false;
    let cameraOff = false;
    
    // 사용자 카메라 영상 가져오기 (비동기 처리)
    async function getMedia(){
        try{
            myStream = await navigator.mediaDevices.getUserMedia( // 캠 장치 연결
                {
                    audio: true, // 마이크, 캠 ON
                    video: true,
                }
            );
            myFace.srcObject = myStream; // video 태그 요소에 해당 캠 장치 연결
        } catch(e){
            console.log(e);
        }
    }
    
    // 카메라 온오프 버튼 이벤트 핸들러
    function handleCameraClick() {
        // 카메라 Track enabled를 토글시켜 온오프 제어
        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;
        }
    }
    // 음소거 버튼 이벤트 핸들러
    function handleMuteClick() {
        // 오디오 Track enabled를 토글시켜 음소거 제어
        myStream.getAudioTracks().forEach(track => track.enabled = !track.enabled);
        if(!muted) {
            muteBtn.innerText = "Unmute";
            muted = true;
        } else {
            muteBtn.innerText = "Mute";
            muted = false;
        }
    }
    
    // 카메라 영상 가져오기
    getMedia();
    
    // 음소거, 카메라 버튼 이벤트 리스너 연결
    muteBtn.addEventListener("click", handleMuteClick)
    cameraBtn.addEventListener("click", handleCameraClick)

    - getMedea()의 사용자 카메라 디바이스를 가져오는 함수와 각 버튼을 동작시킬 이벤트 핸들러 함수와 리스너 연결을 통해 구현했다.

     

     

     

    - 정상적으로 비디오 송출이 잘 되고 버튼 기능도 동작한다.

     

    사용자의 카메라 장치 목록 만들기

    home.pug

    - select 요소를 하나 만들었다.

     

    app.js

    - 사용자의 장치 목록을 받아오는 함수를 정의하고, 사용자 카메라 영상을 가져올 때 실행시켜 받아온다.

     

    카메라 장치 변경 기능 만들기

    앞서 만든 select 요소를 선택할 때, 선택된 새로운 카메라로 다시 실행되도록 stream을 강제로 재실행시킨다.

    getMedia()를 다시 한번 호출함으로써 재실행시킬 수 있다. 하지만 특정 브라우저에서 특정 카메라를 사용하도록 설정해야 한다. getUserMedia({constrain})에서 constrain 값을 수정하여 구현할 수 있다.

     

    ex)

    - video: {facingMode: } 를 통해 모바일 환경의 셀카를 사용하도록 설정할 수 있다.

     

    - 위의 방법을 통해 세부적인 해당 장치의 카메라를 선택할 수 있다.

     

    app.js

    - 결과적으로 카메라 select 목록에서 원하는 카메라를 선택하면 정상적으로 송출까지 된다.

     

    소스코드

     

    GitHub - pkd98/clonecoding

    Contribute to pkd98/clonecoding development by creating an account on GitHub.

    github.com

     

    728x90
    반응형

    댓글

Keydi's Tistory