1. MediaDevices 란?
navigator.mediaDevices
를 통해 웹에서 카메라, 마이크, 화면 공유와 같은 미디어 입력 장치에 접근하여, 해당 장치에서 제공하는 미디어 스트림을 가져올 수 있습니다.
※ Navigator 객체는 웹 브라우저의 정보를 제공하는 인터페이스로
window.navigator
읽기 전용 속성으로 접근할 수 있습니다.
1.1 이벤트
■ devicechange
새로운 미디어 장치가 연결되거나 기존 장치가 제거될 때 발생하는 이벤트입니다. ondevicechange
속성으로도 사용할 수 있습니다.
// `addEventListener`를 사용하는 방식 (권장)
navigator.mediaDevices.addEventListener('devicechange', event => {
console.log('미디어 장치 구성이 변경되었습니다');
// 장치 목록 다시 가져오기 등의 작업 수행
});
// `ondevicechange` 속성을 사용하는 방식 (권장 x): `ondevicechange`는 이벤트 핸들러 한 개만 등록 가능
navigator.mediaDevices.ondevicechange = () => {
console.log("미디어 장치 변경 감지!");
};
1.2 메서드
■ getUserMedia()
사용자에게 권한을 요청한 후, 사용자의 카메라, 마이크 등 미디어 입력 장치에 접근하여 MediaStream 을 가져옵니다.
navigator.mediaDevices.getUserMedia(constraints)
.then(stream => {
// 스트림 사용하기
})
.catch(error => {
console.error("미디어 장치 접근 실패:", error);
});
constraints
객체는 요청할 미디어 유형과 각각의 요구사항을 명시합니다:
// simple
const constraints = {
audio: true, // 기본 오디오 설정
video: true // 기본 비디오 설정
};
or
// detail
const constraints = {
audio: {
echoCancellation: true,
noiseSuppression: true,
autoGainControl: true
},
video: {
width: { ideal: 1280 },
height: { ideal: 720 },
facingMode: "user" // 전면 카메라
}
};
■ enumerateDevices()
시스템에서 사용 가능한 모든 미디어 입력 및 출력 장치의 목록을 가져옵니다.
navigator.mediaDevices.enumerateDevices()
.then(devices => {
devices.forEach(device => {
console.log(`${device.kind}: ${device.label}, id = ${device.deviceId}`);
});
})
.catch(error => {
console.error("장치 열거 실패:", error);
});
■ getDisplayMedia()
사용자의 화면 콘텐츠(전체 화면, 애플리케이션 창, 또는 특정 탭)를 캡처할 수 있는 스트림을 제공합니다.
navigator.mediaDevices.getDisplayMedia({ video: true })
.then(stream => {
// 화면 공유 스트림 사용하기
})
.catch(error => {
console.error("화면 공유 실패:", error);
});
2. MediaStream
MediaStream 은 WebRTC 및 웹 미디어 API에서 사용되는 객체로, 오디오 및 비디오 스트림을 다룰 때 사용됩니다. 브라우저에서 마이크, 카메라, 화면 공유 등의 미디어 데이터를 실시간으로 처리할 수 있게 하며, 단일 또는 여러 미디어 트랙을 포함할 수 있습니다. 각 트랙은 특정 유형의 미디어 소스(예: 카메라, 마이크, 화면 콘텐츠)를 나타냅니다.
2.1 생성 및 접근 방법
■ MediaDevices.getUserMedia()
카메라/마이크 접근
■ MediaDevices.getDisplayMedia()
화면 공유
■ Canvas.captureStream()
캔버스 콘텐츠 스트리밍
const canvas = document.querySelector('canvas');
const stream = canvas.captureStream(30); // 30fps
■ 기존 트랙으로부터 새 스트림 생성
const newStream = new MediaStream([videoTrack, audioTrack]);
■ 다른 스트림 복제
const clonedStream = originalStream.clone();
2.2 이벤트
■ addtrack
새 트랙이 스트림에 추가될 때 발생합니다.
stream.addEventListener('addtrack', event => {
console.log('트랙이 추가됨:', event.track);
});
■ removetrack
트랙이 스트림에서 제거될 때 발생합니다.
stream.addEventListener('removetrack', event => {
console.log('트랙이 제거됨:', event.track);
});
2.3 속성
■ active
스트림이 활성 상태인지 여부를 나타내는 boolean 값입니다. 하나 이상의 트랙이 활성 상태면 true입니다.
console.log(stream.active); // true 또는 false
■ id
스트림의 고유 식별자입니다.
console.log(stream.id); // 예: "123e4567-e89b-12d3-a456-426614174000"
2.4 메서드
■ addTrack()
스트림에 새로운 트랙을 추가합니다.
stream.addTrack(track); // track은 MediaStreamTrack 객체
■ removeTrack()
스트림에서 트랙을 제거합니다.
stream.removeTrack(track);
■ getAudioTracks()
스트림 내의 모든 오디오 트랙을 배열로 반환합니다.
const audioTracks = stream.getAudioTracks();
■ getVideoTracks()
스트림 내의 모든 비디오 트랙을 배열로 반환합니다.
const videoTracks = stream.getVideoTracks();
■ getTracks()
스트림의 모든 트랙(오디오와 비디오)을 배열로 반환합니다.
const allTracks = stream.getTracks();
■ getTrackById()
지정된 ID를 가진 트랙을 반환합니다.
const track = stream.getTrackById(trackId);
■ clone()
스트림의 복제본을 생성합니다. 모든 트랙도 복제됩니다.
const clonedStream = stream.clone();
3. MediaStreamTrack
MediaStream은 트랙(MediaStreamTrack) 객체의 집합으로, 각 트랙은 오디오나 비디오 같은 특정 미디어 유형의 소스를 나타냅니다.
3.1 주요 속성
- kind: 트랙의 유형 ('audio' 또는 'video')
- id: 트랙의 고유 식별자
- label: 트랙의 설명(예: 카메라 또는 마이크 이름)
- enabled: 트랙의 활성화/비활성화 상태
- muted: 트랙이 현재 음소거 상태인지 여부
- readyState: 트랙의 현재 상태 ('live' 또는 'ended')
3.2 주요 메서드
- stop(): 트랙을 영구적으로 중지
- clone(): 트랙의 복제본 생성
- getCapabilities(): 트랙의 가능한 설정 범위 가져오기
- getConstraints(): 현재 적용된 제약 조건 가져오기
- getSettings(): 현재 적용된 설정 가져오기
- applyConstraints(): 새로운 제약 조건 적용하기
4, MediaStream 레코딩
MediaRecorder API를 사용하여 MediaStream을 녹화할 수 있습니다:
function recordStream(stream) {
const chunks = [];
const recorder = new MediaRecorder(stream);
recorder.ondataavailable = e => {
if (e.data.size > 0) {
chunks.push(e.data);
}
};
recorder.onstop = () => {
const blob = new Blob(chunks, { type: 'video/webm' });
const url = URL.createObjectURL(blob);
// 비디오 저장 링크 생성
const a = document.createElement('a');
a.href = url;
a.download = 'recording.webm';
a.textContent = '녹화 다운로드';
document.body.appendChild(a);
};
// 녹화 시작 (5초 동안)
recorder.start();
setTimeout(() => recorder.stop(), 5000);
}
5. 브라우저 호환성
- 대부분의 최신 브라우저(Chrome, Firefox, Safari, Edge)에서 지원됩니다.
- Safari는 일부 제한된 기능을 가질 수 있습니다.
- 모바일 브라우저에서는 기능과 성능에 차이가 있을 수 있습니다.
- 보안을 위해 HTTPS 환경에서만 완전히 작동합니다(localhost 제외).
6. 보안 고려사항
- MediaStream API는 카메라, 마이크 등의 민감한 장치에 접근하므로 사용자의 명시적 권한이 필요합니다.
- 대부분의 브라우저는 사용자가 허용하지 않은 미디어 장치에 접근할 수 없도록 차단합니다.
- 사용자가 허용한 후에도 브라우저 UI에 미디어 장치 사용 중임을 표시합니다.
- 백그라운드 탭에서는 미디어 캡처가 제한될 수 있습니다.
- 영상 처리 시 사용자 개인정보를 고려해야 합니다.
참고
Media Capture and Streams API (미디어 스트림) - MDN
MediaDevices - MDN
MediaStream Recording API - MDN
MediaRecorder - MDN
'기타 web 개발 지식' 카테고리의 다른 글
ESLint 9 버전 Flat config (0) | 2025.03.06 |
---|---|
cookie domain 으로 "vercel.app" 사용 시 생긴는 에러와 PSL,TLD,eTLD 이해 (0) | 2025.02.12 |
<a role="button"> 과 <button> 차이는 무엇일까? [접근성, SEO] (2) | 2024.11.28 |
줄 바꿈 형식 CR? LF? CRLF? (0) | 2023.06.08 |
SVG 의 이해 및 배치 관련 내용 (0) | 2023.04.18 |