MediaStreamTrack용 삽입 가능한 스트림

MediaStreamTrack의 콘텐츠는 조작되거나 새 콘텐츠를 생성하는 데 사용할 수 있는 스트림으로 노출됩니다.

배경

Media Capture and Streams API의 컨텍스트에서 MediaStreamTrack 인터페이스는 스트림 내의 단일 미디어 트랙을 나타냅니다. 일반적으로 오디오 또는 동영상 트랙이지만 다른 트랙 유형이 있을 수도 있습니다. MediaStream 객체는 다양한 오디오 또는 동영상 트랙을 나타내는 0개 이상의 MediaStreamTrack 객체로 구성됩니다. 각 MediaStreamTrack에는 하나 이상의 채널이 있을 수 있습니다. 채널은 스테레오 오디오 트랙의 왼쪽 또는 오른쪽과 같이 특정 스피커와 연결된 오디오 신호와 같이 미디어 스트림의 가장 작은 단위를 나타냅니다.

MediaStreamTrack의 삽입 가능한 스트림이란 무엇인가요?

MediaStreamTrack의 삽입 가능한 스트림의 핵심 아이디어는 MediaStreamTrack의 콘텐츠를 WHATWG Streams API에서 정의한 스트림 모음으로 노출하는 것입니다. 이러한 스트림을 조작하여 새 구성요소를 도입할 수 있습니다.

개발자에게 동영상 (또는 오디오) 스트림에 대한 직접 액세스 권한을 부여하면 개발자가 스트림에 수정사항을 직접 적용할 수 있습니다. 반면 기존 방법으로 동일한 동영상 조작 작업을 실행하려면 개발자가 <canvas> 요소와 같은 중개자를 사용해야 합니다. (이러한 유형의 프로세스에 관한 자세한 내용은 동영상 + 캔버스 = 매직 등을 참고하세요.)

브라우저 지원

MediaStreamTrack의 삽입 가능한 스트림은 Chrome 94부터 지원됩니다.

사용 사례

MediaStreamTrack의 삽입 가능한 스트림의 사용 사례에는 다음이 포함되나 이에 국한되지 않습니다.

  • '재미있는 모자' 또는 가상 배경과 같은 화상 회의 가젯
  • 소프트웨어 보코더와 같은 음성 처리

MediaStreamTrack에 삽입 가능한 스트림을 사용하는 방법

특성 감지

다음과 같이 MediaStreamTrack 지원을 위해 삽입 가능한 스트림을 기능 감지할 수 있습니다.

if ('MediaStreamTrackProcessor' in window && 'MediaStreamTrackGenerator' in window) {
  // Insertable streams for `MediaStreamTrack` is supported.
}

핵심 개념

MediaStreamTrack의 삽입 가능한 스트림은 이전에 WebCodecs에서 제안한 개념을 기반으로 하며 개념적으로 MediaStreamTrack를 다음 두 구성요소로 분할합니다.

  • MediaStreamTrackProcessor: MediaStreamTrack 객체의 소스를 사용하고 미디어 프레임 스트림(특히 VideoFrame 또는 AudioFrame) 객체를 생성합니다. 트랙의 인코딩되지 않은 프레임을 ReadableStream로 노출할 수 있는 트랙 싱크라고 생각하면 됩니다.
  • MediaStreamTrackGenerator: 미디어 프레임 스트림을 소비하고 MediaStreamTrack 인터페이스를 노출합니다. getUserMedia()의 트랙과 마찬가지로 모든 싱크에 제공할 수 있습니다. 미디어 프레임을 입력으로 사용합니다.

MediaStreamTrackProcessor

MediaStreamTrackProcessor 객체는 readable 속성 하나를 노출합니다. 이를 통해 MediaStreamTrack에서 프레임을 읽을 수 있습니다. 트랙이 동영상 트랙인 경우 readable에서 읽은 청크는 VideoFrame 객체가 됩니다. 트랙이 오디오 트랙인 경우 readable에서 읽은 청크는 AudioFrame 객체가 됩니다.

MediaStreamTrackGenerator

마찬가지로 MediaStreamTrackGenerator 객체는 하나의 속성 writable를 노출합니다. 이 속성은 자체적으로 MediaStreamTrackMediaStreamTrackGenerator에 미디어 프레임을 쓸 수 있는 WritableStream입니다. kind 속성이 "audio"이면 스트림은 AudioFrame 객체를 허용하고 다른 유형에서는 실패합니다. 종류가 "video"이면 스트림은 VideoFrame 객체를 허용하고 다른 유형에서는 실패합니다. 프레임이 writable에 쓰여지면 프레임의 close() 메서드가 자동으로 호출되므로 더 이상 JavaScript에서 미디어 리소스에 액세스할 수 없습니다.

MediaStreamTrackGenerator는 미디어 프레임을 writable 필드에 작성하여 맞춤 소스를 구현할 수 있는 트랙입니다.

총정리

핵심 아이디어는 다음과 같이 처리 체인을 만드는 것입니다.

플랫폼 트랙 → 프로세서 → 변환 → 생성기 → 플랫폼 싱크

아래 예는 실시간 동영상 스트림에서 감지된 바코드를 강조 표시하는 바코드 스캐너 애플리케이션의 이 체인을 보여줍니다.

const stream = await getUserMedia({ video: true });
const videoTrack = stream.getVideoTracks()[0];

const trackProcessor = new MediaStreamTrackProcessor({ track: videoTrack });
const trackGenerator = new MediaStreamTrackGenerator({ kind: 'video' });

const transformer = new TransformStream({
  async transform(videoFrame, controller) {
    const barcodes = await detectBarcodes(videoFrame);
    const newFrame = highlightBarcodes(videoFrame, barcodes);
    videoFrame.close();
    controller.enqueue(newFrame);
  },
});

trackProcessor.readable.pipeThrough(transformer).pipeTo(trackGenerator.writable);

const videoBefore = document.getElementById('video-before');
const videoAfter = document.getElementById('video-after');
videoBefore.srcObject = stream;
const streamAfter = new MediaStream([trackGenerator]);
videoAfter.srcObject = streamAfter;

데모

위 섹션의 QR 코드 스캐너 데모를 데스크톱 또는 모바일 브라우저에서 실행해 볼 수 있습니다. 카메라 앞에 QR 코드를 가져가면 앱에서 이를 감지하여 강조 표시합니다. Glitch에서 애플리케이션의 소스 코드를 확인할 수 있습니다.

데스크톱 브라우저 탭에서 실행 중인 QR 코드 스캐너입니다. 사용자가 노트북의 카메라 앞에 들고 있는 휴대전화에서 인식되고 강조표시된 QR 코드가 표시되어 있습니다.

보안 및 개인 정보 보호 고려사항

이 API의 보안은 웹 플랫폼의 기존 메커니즘을 사용합니다. 데이터가 VideoFrameAudioFrame 인터페이스를 사용하여 노출되므로 출처 오염된 데이터를 처리하는 이러한 인터페이스의 규칙이 적용됩니다. 예를 들어 교차 출처 리소스 액세스에 대한 기존 제한으로 인해 교차 출처 리소스의 데이터에 액세스할 수 없습니다 (예: 교차 출처 이미지 또는 동영상 요소의 픽셀에 액세스할 수 없음). 또한 카메라, 마이크 또는 화면의 미디어 데이터에 대한 액세스에는 사용자 승인이 필요합니다. 이 API가 노출하는 미디어 데이터는 이미 다른 API를 통해 사용할 수 있습니다.

의견

Chromium팀에서는 MediaStreamTrack용 삽입 가능한 스트림 사용 경험에 관한 의견을 듣고자 합니다.

API 설계에 대해 알려주세요.

API에 예상대로 작동하지 않는 부분이 있나요? 아니면 아이디어를 구현하는 데 필요한 메서드나 속성이 누락되어 있나요? 보안 모델에 대한 질문이나 의견이 있으신가요? 해당 GitHub 저장소에서 사양 문제를 제출하거나 기존 문제에 의견을 추가합니다.

구현 문제 신고

Chromium 구현에 버그가 있나요? 아니면 구현이 사양과 다른가요? new.crbug.com에서 버그를 신고합니다. 최대한 자세한 내용과 재현을 위한 간단한 안내를 포함하고 구성요소 상자에 Blink>MediaStream를 입력합니다. Glitch는 빠르고 간편한 재현을 공유하는 데 적합합니다.

API 지원 표시

MediaStreamTrack에 삽입 가능한 스트림을 사용할 계획인가요? 공개적으로 지원하면 Chromium팀에서 기능의 우선순위를 지정하는 데 도움이 되며 다른 브라우저 공급업체에 기능을 지원하는 것이 얼마나 중요한지 보여줍니다.

#InsertableStreams 해시태그를 사용하여 @ChromiumDev에 트윗을 보내고 사용 중인 위치와 사용 방법을 알려주세요.

감사의 말씀

MediaStreamTrack 사양의 삽입 가능한 스트림은 Harald AlvestrandGuido Urdaneta가 작성했습니다. 이 도움말은 Harald Alvestrand, Joe Medley, Ben Wagner, Huib Kleinhout, François Beaufort가 검토했습니다. Unsplash크리스 몽고메리님 제공 히어로 이미지