Step-by-Step

[5] Video 및 Audio 출력하기 본문

프로젝트/Zoom (WebRTC)

[5] Video 및 Audio 출력하기

희주(KHJ) 2023. 4. 10. 21:08

전부 App.js 내용이다. 나의 UI 정보이기 때문!

 

전역변수 Stream 설정

 

let myStream;

 

 

들어가고 싶은 Room 이름을 추가하고 클릭

 

/* Enter Room 클릭 */
welcomeForm.addEventListener("submit", handleWelcomeSubmit);

/* Enter Room 클릭 이벤트 처리 */
async function handleWelcomeSubmit(event){
    event.preventDefault();
    const input = welcomeForm.querySelector("input");
    
    /* emit으로 보내지 않고, join 전에 실행 */
    await initCall();

	/* UI Header 변경해줌 */
    const header = document.querySelector("header");
    const h1 = header.querySelector("h1");
    h1.textContent = "ROOM - "+input.value;

    socket.emit("join_room", input.value);
    roomName = input.value;
    input.value = "";
}

 

 

 

UI 변경되는 모습

 

앱 완성 후에 작성한 거라 CSS 및 채팅 기능이 있는 모습입니다

 

 

 

룸 입력 후 초기 호출

 

/* Media 정보 등록, 타 소켓에 연결, UI 숨김 */
async function initCall(){
    welcome.hidden = true;
    await getMedia();
    makeConnection();
}

 

 

 

미디어 정보 가져오기 - getMedia

 

async function getMedia(deviceId){
	/* 특정 디바이스 선택 전 (초기 설정 부분) */
    const initalConstraints = {
        audio:true,  				// audio 나오게 설정
        video: { 
            facingMode : "user"     // 후면카메라 - facingMode : "environment"
        }
    }

	/* 특정 디바이스 선택 후 */
    const cameraConstraints = {
        audio:true,  	
        deviceId: {
            exact : deviceId        // 특정 deviceId로 카메라 설정
        }
    }
    
    try {
        /* 스트림 사용 */
        myStream = await navigator.mediaDevices.getUserMedia({
            audio : true,
            video : deviceId ? cameraConstraints : initalConstraints
        });

	/* 디바이스 아이디 (카메라 정보) 없이 호출 */
        if(!deviceId){
            await getCameras();
        }

        /* 화면에 비디오 화면 띄우기 */
        myFace.srcObject = myStream;
    } catch(e) {
        /* 오류 처리 */
        console.log(e);
    }
}

공식문서 참조 : https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia

 

 

 

카메라 설정 - getCameras

 

우선 카메라 정보 추출 방법을 알아보아야 한다 

Mozilla 공식 문서를 보면 이런 방식으로 디바이스 정보 추출이 가능하다.

실제로 콘솔로 출력하면 이렇게 오디오와 비디오 정보를 가져올 수 있다.!

 

 

카메라 초기설정

 

async function getCameras() {
    try{
    	/* 비디오 정보만 가져옴 - 가장 첫 번째 비디오를 기본값으로 설정 */
        const devices = await navigator.mediaDevices.enumerateDevices();
        const cameras = devices.filter(device => device.kind === "videoinput");
        const currentCamera = myStream.getVideoTracks()[0];

        /* 카메라 선택 옵션 UI 생성 코드 */
        cameras.forEach(camera => {
            const option = document.createElement("option");
            option.value = camera.deviceId;     // 선택 후 카메라 출력 변경을 위함
            option.innerText = camera.label;
            if(currentCamera.labe === camera.label){
                option.selected = true;
            }
            camerasSelect.appendChild(option);
        });
    }catch(e){
        console.log(e);
    }
}

현재 카메라 포함 카메라 선택 옵션 UI 도 함께 생성해준다. 현재 카메라는 currentCamera 변수에 넣어줌

 


이런 식으로 선택 가능함

 

카메라 변경

 

camerasSelect.addEventListener("input", handleCameraChange);

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

    /* 다른 Peer에 있는 my track 바꾸기 */
    if(myPeerConnection){
        const videoTrack = myStream.getVideoTracks()[0];
        const videoSender = myPeerConnection.getSenders().find((sender) => sender.track.kind === "video");
        videoSender.replaceTrack(videoTrack);
    }
}

아까 사용했던 getMedia에 바꿀 카메라 값을 넣어주며 내 UI를 변경한다.

룸에 다른 사람이 입장해 있을 수도 있으니 socket 통신으로 카메라 스트림 정보를 전송해주어야 하는데,

이건 다음 글에서 계속 ..!

 

 

 

비디오 UI에 띄우기

 

/* home.pug */
div#myStream
	video#myFace(autoplay, playsinline, width="400", height="400")

우선 PUG에 비디오 선언해주고 (또는 HTML로 해도 됨)

 

/* 화면에 비디오 화면 띄우기 */
myFace.srcObject = myStream;

넣어주면 됨 - nodemon 사용중이라 바로 반영되는 거 같습니다

 

 

카메라 및 오디오 ON/OFF 처리
muteBtn.addEventListener("click", handleMuteClick);
cameraBtn.addEventListener("click", handleCameraClick);

function handleMuteClick(){
    /* 오디오 트랙 정보 getAudioTracks() - enable 필드로 활성화 여부 변경 */
    myStream.getAudioTracks().forEach(track => (track.enabled = !track.enabled));
    if(!muted){
        muteBtn.innerText = "UnMute";
        muted = true;
    }else {
        muteBtn.innerText = "Mute";
        muted = false;
    }
    console.log("click Mute BTN");
}

function handleCameraClick(){
    /* 비디오 트랙 정보 getVideoTracks() - enable 필드로 활성화 여부 변경 */
    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;
    }
    console.log("click Camera BTN");
}

myStream 에 있는 비디오 및 오디오 트랙의 사용(enabled 변수)를 반대로 바꿔주면 된다.

바꾼 김에 버튼 text도 바꿔주면 보기에도 편하다!

 

Comments