MediaStreamTrack용 삽입 가능한 스트림

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

배경

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

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

MediaStreamTrack용 삽입 가능한 스트림의 핵심 아이디어는 MediaStreamTrack의 콘텐츠를 스트림 컬렉션으로 노출하는 것입니다 (WHATWG 스트림 API에 의해 정의됨). 이러한 스트림을 조작하여 새로운 구성요소를 도입할 수 있습니다.

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

브라우저 지원

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

사용 사례

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

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

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

기능 감지

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

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

핵심 개념

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

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

MediaStreamTrackProcessor

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

MediaStreamTrackGenerator

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

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

총정리

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

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

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

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 코드를 대면 앱에서 이를 감지하고 강조 표시합니다. 애플리케이션의 소스 코드는 GitHub에서 확인할 수 있습니다.

데스크톱 브라우저 탭에서 실행되는 QR 코드 스캐너가 사용자가 노트북 카메라 앞에 들고 있는 휴대전화에서 감지되어 강조 표시된 QR 코드를 보여줍니다.

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

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

의견

Chromium팀은 MediaStreamTrack의 삽입 가능한 스트림에 관한 여러분의 경험을 듣고 싶습니다.

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

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

구현 문제 신고

Chromium 구현에서 버그를 발견하셨나요? 아니면 구현이 사양과 다른가요? new.crbug.com에서 버그를 신고합니다. 최대한 많은 세부정보와 재현을 위한 간단한 안내를 포함하고 구성요소 상자에 Blink>MediaStream를 입력합니다.

API 지원 표시

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

#InsertableStreams 해시태그를 사용하여 @ChromiumDev에 트윗을 보내 어디에서 어떻게 사용하고 있는지 알려주세요.

감사의 말씀

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