[WebRTC 01] 사전작업, HTML에 비디오 스트림 표시하기, 웹캠 HTML에 표현 <video>
Tech/WebRTC

[WebRTC 01] 사전작업, HTML에 비디오 스트림 표시하기, 웹캠 HTML에 표현 <video>

반응형

 

개요

저는 HTML 화면에 비디오를 띄우는 방법 조차 몰랐기때문에, WebRTC에서 P2P 연결을 하기 이전에 비디오 스트림을 HTML 화면에 뿌리는 것부터 알아봤습니다

로컬 비디오 스트림을 html에 보이게 하는것은 JS로 구현이 가능하다. 여기 에서 미디어 스트림과 관련된 매서드들을 확인할 수 있습니다.

튜토리얼은 WebRTC 공식 가이드에 따라서 진행했으며, 중복된 코드가 있어서 일부 코드를 수정했습다.

 

Step1. HTML video 태그

html에서 작성할 내용은 아주 간단합니다.video 태그만 있으면 된다. JS에서 이 태그를 잡아서 비디오 스트림을 뿌려줄 것이기때문! select는 카메라 및 오디오가 여러개여서 선택이 가능한 경우를 위해 두었습니다.

<body>
    <video id="localVideo" autoplay playsinline controls="false"/>
    <select name="" id="availableCameras"></select>
    <script src="./basic01.js"></script>
</body>

 

Step 2. 사용(접근) 가능한 미디어 입출력 장치 가져오기

async function getConnectedDevices(type) {
    const devices = await navigator.mediaDevices.enumerateDevices();
    return devices.filter(device => device.kind === type) // 특정 타입의 미디어 장치 반환
}

// Get the initial set of cameras connected
const videoCameras = getConnectedDevices('videoinput'); // 여기서는 비디오
console.log(videoCameras)
  • navigator.mediaDevices : 읽기 전용 속성은 카메라, 마이크, 화면 공유와 같이 현재 연결된 미디어 입력 장치에 접근할 수 있는 MediaDevices 객체를 반환합니다. (참고: MDN)
  • MediaDevices.enumerateDevices() : 사용(또는 접근)이 가능한 미디어 입력장치나 출력장치들의 리스트를 가져옵니다. 예를 들면 마이크, 카메라, 헤드셋 등의 미디어 입/출력 장치 리스트를 불러오는 것 이죠. 이 메서드는 Promise를 반환하는데, 이 Promise가 resolve되면 장치(device)정보가 들어있는 MediaDeviceInfo 배열(array)을 확인할 수 있습니다.
  • 즉, 현재 사용 가능한 미디어 객체 전체를 가져오고, 이중에서 비디오만 가져와서 videoCameras에 할당합니다.

 

Step3. 장치 변경 수신

function updateCameraList(cameras) {
    const listElement = document.querySelector('select#availableCameras');
    listElement.innerHTML = '';
    cameras.map(camera => {
        const cameraOption = document.createElement('option');
        cameraOption.label = camera.label;
        cameraOption.value = camera.deviceId;
    }).forEach(cameraOption => listElement.add(cameraOption));
}

// Listen for changes to media devices and update the list accordingly
navigator.mediaDevices.addEventListener('devicechange', event => {
    const newCameraList = getConnectedDevices('video');
    updateCameraList(newCameraList);
});
  • 만약 미디어 객체중에서 디바이스가 바뀐 이벤트를 감지한 경우(여기선 카메라가 바뀔경우 ; 웹캠을 USB로 새로 연결 하는 등의 변경 사항), 연결할 카메라를 선택해서 카메라 객체를 변경하는 것

 

Step4. 미디어 제약

async function openCamera(cameraId, minWidth, minHeight) {
    const constraints = {
        'audio': {'echoCancellation': true},
        'video': {
            'deviceId': cameraId,
            'width': {'min': minWidth},
            'height': {'min': minHeight}
            }
        }

    return await navigator.mediaDevices.getUserMedia(constraints);
}

const cameras = getConnectedDevices('videoinput');
if (cameras && cameras.length > 0) {
    // Open first available video camera with a resolution of 1280x720 pixels
    const stream = openCamera(cameras[0].deviceId, 1280, 720);
}
  • MediaStreamConstraints 인터페이스를 구현해야하는 제약 조건 객체는 getUserMedia() 매개 변수로 전달하여 특정 요구 사항과 일치하는 미디어 장치를 열 수 있습니다.
  • 이 요구 사항은 매우 느슨하게 정의되거나 (오디오 및 / 또는 비디오) 매우 구체적 일 수 있습니다 (최소 카메라 해상도 또는 정확한 장치 ID).
  • getUserMedia() API를 사용하는 응용 프로그램은 먼저 기존 장치를 확인한 다음 deviceId 제약 조건을 사용하여 정확한 장치와 일치하는 제약 조건을 지정하는 것이 deviceId .
  • 가능한 경우 장치도 제약 조건에 따라 구성됩니다. 마이크에서 반향 제거를 활성화하거나 카메라에서 비디오의 특정 또는 최소 너비와 높이를 설정할 수 있습니다.

 

Step5. 로컬 재생

async function playVideoFromCamera() {
    try {
        const constraints = {'video': true, 'audio': true};
        const stream = await navigator.mediaDevices.getUserMedia(constraints);
        const videoElement = document.querySelector('video#localVideo');
        videoElement.srcObject = stream;
    } catch(error) {
        console.error('Error opening video camera.', error);
    }
}

playVideoFromCamera()
  • 5번만 있으면 화면에 비디오를 뿌릴 수 있습니다.
  • navigator.mediaDevices.getUserMedia(constraints) : 사용 가능한 객체를 가져오고 그 객체에 대한 엑세스 허용을 묻습니다
  • 엑세스 허용을 누르면 비디오 태그를 잡아서, src에 스트림을 넣어 재생합니다.
  • 만약 허용을 누르지 않으면 비디오가 없으므로, 에러가 발생하고 catch 코드로 이동합니다.

 

정리

  • 비디오 스트림을 지원하는 JS API가 너무 잘되어있다.
  • 실제 HTMl 비디오 태그와, Step 5의 JS 코드만 있으면 화면에 비디오 스트림을 뿌릴 수 있다.

 

코드(Git)

전체 코드

 

참고

반응형