원본 출처: https://curryyou.tistory.com/443
자바스크립트에서 미디어를 다루는 주요 API 4가지
1. Media Capture and Streams API (=Meida Stream API)
- 마이크, 카메라 등을 이용해 들어오는 (Media Stream: 오디오, 비디오, 화면 등) 데이터를 다룬다.
2. MediaStream Recording API
- 미디어 스트림(Media Stream: 오디오, 비디오, 화면 등) 데이터를 녹음/녹화 한다.
3. Web Audio API
- 오디오 데이터를 처리/분석하는 API이다.
- 오디오 데이터로 사용될 수 있는 음원은 MediaStream(마이크 소리 등), 오디오 파일(mp3 등), 컴퓨터로 직접 만든 소리(Oscillator) 등이 있다.
4. Web RTC
- Web Real-Time Communication의 약자로, 브라우저 간에 데이터를 주고 받을 수 있게 해준다.
Media Capture and Streams API(=MeidaStream API)란?
Meida Stream API란 스트림 형태로 입출력되는 미디어(오디오, 비디오, 화면 등)을 다루는 API이다.
1. 오디오 스트림
마이크로 입력되는 오디오 소리 스트림
<audio> 태그를 통해 재생중인 오디오 소리 스트림
2. 비디오 스트림
카메라로 입력되는 비디오 영상 스트림
<video> 태그를 통해 재생 중인 비디오 영상 스트림
3. 화면 스트림
브라우저 window 영역의 화면을 캡쳐하는 스트림
<canvas> 태그 영역의 화면을 캡처하는 스트림
위의 미디어 스트림들은 모두 MediaStream객체를 통해 입/출력된다.
먼저 MediaStream 객체에 대해 살펴보고, 각 스트림을 취득하여 다루는 방법을 정리해 보자.
MeidaStream이란?
MediaStream이란 오디오, 비디오 같은 미디어 스트림을 다루는 객체이다.
마이크나 카메라를 통해 입력되는 소리와 영상 스트림, 그리고 브라우저의 화면은 모두 MediaStream객체를 통해 취득할 수 있다.
예를 들어 마이크에서 소리가 발생하면 브라우저는 MediaStream객체를 통해 소리 데이터를 입력 받는다.
개발자는 MediaStream객체를 통해 마이크로 입력되는 소리 데이터를 다룰 수 있게 된다.
주의할 점은 MediaStream객체는 한번 생성되면 계속 열려(?)있다는 점이다.
즉, 한번 카메라 영상을 입력받는 스트림이 열리면, 별도로 닫아주지 않는 한 계속해서 영상 데이터를 입력 받는다.
마찬가지로 한번 영상 스트림을 출력하면, 별도로 닫아주지 않는 한 계속해서 영상 데이터를 출력 한다.
MeidaStream 생성 방법
MediaStream객체의 생성은 주로 아래의 2가지 방법이 사용된다.
주의할 점은 MediaStream 객체를 "여러 개" 생성하더라도 동일한 소스를 사용한다면
입력되는 "스트림은 동일"하다는 점이다.
즉, 동일한 소스(마이크, 카메라, 화면 등)를 바라보는 스트림 "객체"만 여러 개 생성될 뿐이다.
1. MediaStream 생성자
생성자로 MediaStream 객체를 생성하는 방법이다.
1) 비어있는 MediaStream 객체를 생성
new MediaStream()
2) 입력인자로 들어온 객체와 동일한 트랙을 갖는 MediaStream 객체 생성
두 MediaStrema객체는 동일한 스트림 source에 연결된다.
new MediaStream(MeidaStream객체)
3) 여러 개의 트랙을 조합한 MediaStream 객체 생성
new MediaStream([MeidaStreamTrack객체, ...])
그러나 생성자로 MediaStream객체를 생성할 일은 많치 않다.
MediaStream객체를 사용하는 이유는 마이크, 카메라, 화면에서 발생하는 스트림을 입력받기 위해서이다.
따라서 입력소스(마이크, 카메라, 화면 등)에서 바로 MediaStream을 받아서 사용하는 경우가 대부분이다.
2. 입력 소스에서 MediaStream 취득
입력 소스로 부터 MediaStream객체를 받아서 사용하는 방법이다.
1) 마이크, 카메라
navigator.mediaDevices.getUserMedia()
- 마이크, 카메라로 입력되는 오디오, 비디오 MediaStream 객체 생성
* MediaDevices 객체는 전역 객체 navigator.mediaDevices 로 참조할 수 있다.
* navigator.mediaDevices.getUserMedia는 실제 배포 환경에서는 https에서만 작동한다.(localhost는 정상 작동)
2) <audio>, <video> 태그
HTMLMediaElement.captureStream()
- <audio>, <video> 엘리먼트가 재생하는 오디오, 비디오의 MediaStream 객체 생성
* captureStream() 메서드는 브라우저별 지원여부를 확인 후 사용해야 한다.
3) <canvas> 태그
HTMLCanvasElement.captureStream()
- <canvas> 영역에서 발생하는 화면 MediaStream 객체 생성
* canvas에서 그려지는 그림을 영상으로 캡쳐한다고 보면 된다.
4) 브라우저 화면
navigator.mediaDevices.getDisplayMedia()
- 브라우저 winodw 일부 영역에 대한 화면 MediaStream 객체 생성
* 브라우저 화면에서 발생하는 내용을 영상으로 캡처한다고 보면 된다.
이 중에서 마이크, 카메라로부터 MediaStream을 취득하는
navigator.mediaDevice.getUserMedia을 사용하는 방법을 알아보자(나머지는 다른 글에서 다루어볼 예정)
MediaDevices.getUserMedia() 사용 방법
navigator.mediaDevices.getUserMedia(MediaStreamConstraints)
- 메서드가 호출되는 순간 사용자에게 마이크, 카메라 사용 권한(permission)을 요청 한다.
- 권한이 승인되면 마이크, 카메라에서 소리, 영상 스트림을 취득하여 Promise<MediaStream>을 반환한다.
- 입력인자(MediaTrackConstraints)로는 사용할 미디어 타입을 설정한다.
ㄴ audio(마이크) : true | false
ㄴ video(비디오) : true | false
예를 들어 마이크만 사용하는 MediaStream은 아래와 같이 생성한다.
navigator.mediaDevices.getUserMedia({
audio: true,
video: false
});
* 단, Promise를 반환하므로 then()으로 받아서 사용하거나, async/await 를 사용해야 한다.
MediaTrackConstraints는 이 외에도 다양한 audio, video 관련 옵션을 줄 수 있다.
아래 코드는 해상도를 1280X720으로 조정한 셀카 카메라의 영상 MediaStream을 생성한다.
navigator.mediaDevices.getUserMedia({
audio: true,
video: {
width: 1280,
height: 720,
facingMode: "user" // 셀카 카메라 사용. 바깥쪽 카메라는 "environment"
}
});
아래 예제 코드는 노트북 카메라로 촬영되는 영상을 입력 받아 그대로 실시간으로 재생한다.
[샘플 코드 전문]
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>실시간 영상재생</title>
</head>
<body>
<!-- vidoe 태그 생성 -->
<video controls></video>
</body>
<script>
// video 태그 취득
const $video = document.querySelector('video');
// MediaStream 생성(마이크+카메라)
navigator.mediaDevices.getUserMedia({
audio: true,
video: true
})
.then(function(mediaStream) {
// Promise이므로 then으로 받아서 처리
// 입력받은 MediaStream을 그대로 video태그에 적용
$video.srcObject = mediaStream;
// 재생 처리
$video.onloadedmetadata = function(e) {
$video.play();
};
})
.catch(function(err) { console.log(err.name + ": " + err.message); });
</script>
</html>
[실행 결과]
- 마이크, 카메라 사용 권한을 요청한다.
- 카메라로 촬영되는 영상이 실시간으로 재생된다
MediaStreamTrack이란?
MediaStream을 구성하는 각 미디어 요소를 말한다.
MeidaStream은 여러 개의 MeidaStreamTrack객체로 구성된다.
예를 들어 자막이 있는 비디오 MediaStream은 3개의 MediaStreamTrack(영상 트랙, 소리 트랙, 자막 트랙)으로 구성된다.
MediaStream을 구성하는 각 MediaStreamTrack은 아래의 메서드들로 추출할 수 있다.
1) MediaStream을 구성하는 모든 MediaStreamStrack 들을 배열로 반환한다.
MediaStream.getTracks()
2) MediaStream을 구성하는 오디오 MediaStream을 반환한다.
MediaStream.getAudioTrack()
3) MediaStream을 구성하는 비디오 MediaStream을 반환한다.
MediaStream.getVideoTrack()
추출된 MediaStreamTrack 들은
new MediaStream([MediaStreamTrack, ... ]) 생성자를 이용해 조합할 수 있다.
const newMeidaStream = new MediaStream([오디오MediaStreamTrack, 비디오MediaStreamTrack, ...]);
예를 들면,
카메라로 들어온 MediaStream은 비디오MediaStreamTrack과 오디오 비디오MediaStreamTrack으로 구성된다.
여기서 비디오MediaStreamTrack만 추출하여 새로운 MediaStream을 생성하면, 무음 영상 MediaStream을 만들 수 있다.
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>무음 영상재생</title>
</head>
<body>
<!-- vidoe 태그 생성 -->
<video controls></video>
</body>
<script>
// video 태그 취득
const $video = document.querySelector('video');
// MediaStream 생성(마이크+카메라)
navigator.mediaDevices.getUserMedia({
audio: true,
video: true
})
.then(function(mediaStream) {
// Promise이므로 then으로 받아서 처리
// MediaStream 에서 비디오, 오디오 MediaStreamTrack 각각 추출
const videoTracks = mediaStream.getVideoTracks()
const audioTracks = mediaStream.getAudioTracks()
// 비디오 MediaStreamTrack으로만 구성된 새로운 MediaStream 생성(무음 영상)
const mediaStreamAudioX = new MediaStream(videoTracks);
// 입력받은 MediaStream을 그대로 video태그에 적용
$video.srcObject = mediaStream;
// 재생 처리
$video.onloadedmetadata = function(e) {
$video.play();
};
})
.catch(function(err) { console.log(err.name + ": " + err.message); });
</script>
</html>
'STUDY > JavaScript' 카테고리의 다른 글
[JS] URL생성자 기초 정리 (0) | 2023.04.12 |
---|---|
[JS] Web Audio API (0) | 2023.04.03 |
[JS] audio 태그 제어하기 (0) | 2023.03.30 |
[JS] 정규표현식 공백 체크하기 (0) | 2023.03.24 |
[JS] entries()메서드로 FormData 객체 데이터 조회하기 (0) | 2023.03.22 |