Các luồng có thể chèn cho MediaStreamTrack

Nội dung của MediaStreamTrack được hiển thị dưới dạng một luồng có thể bị thao túng hoặc dùng để tạo nội dung mới

Thông tin khái quát

Trong bối cảnh của Media Capture and Streams API, giao diện MediaStreamTrack đại diện cho một bản ghi nội dung nghe nhìn duy nhất trong một luồng; thường thì đây là các bản ghi âm thanh hoặc video, nhưng có thể có các loại bản ghi khác. Các đối tượng MediaStream bao gồm từ 0 đối tượng MediaStreamTrack trở lên, đại diện cho nhiều bản âm thanh hoặc video. Mỗi MediaStreamTrack có thể có một hoặc nhiều kênh. Kênh là đơn vị nhỏ nhất của một luồng nội dung nghe nhìn, chẳng hạn như tín hiệu âm thanh liên kết với một loa nhất định, chẳng hạn như bên trái hoặc bên phải trong một bản âm thanh nổi.

Luồng có thể chèn cho MediaStreamTrack là gì?

Ý tưởng cốt lõi đằng sau các luồng có thể chèn cho MediaStreamTrack là hiển thị nội dung của MediaStreamTrack dưới dạng một tập hợp luồng (theo định nghĩa của Streams API WHATWG). Bạn có thể điều chỉnh các luồng này để thêm các thành phần mới.

Việc cấp cho nhà phát triển quyền truy cập trực tiếp vào luồng video (hoặc âm thanh) cho phép họ áp dụng các nội dung sửa đổi trực tiếp cho luồng. Ngược lại, để thực hiện cùng một tác vụ thao tác video bằng các phương pháp truyền thống, nhà phát triển cần sử dụng các thành phần trung gian như phần tử <canvas>. (Để biết thông tin chi tiết về loại quy trình này, hãy xem ví dụ: video + canvas = magic.)

Hỗ trợ trình duyệt

Chrome 94 trở lên có hỗ trợ luồng có thể chèn cho MediaStreamTrack.

Trường hợp sử dụng

Các trường hợp sử dụng luồng có thể chèn cho MediaStreamTrack bao gồm nhưng không giới hạn ở:

  • Các tiện ích hội nghị truyền hình như "mũ ngộ nghĩnh" hoặc phông nền ảo.
  • Xử lý giọng nói như bộ mã hoá giọng nói bằng phần mềm.

Cách sử dụng luồng có thể chèn cho MediaStreamTrack

Phát hiện đối tượng

Bạn có thể phát hiện tính năng luồng có thể chèn để hỗ trợ MediaStreamTrack như sau.

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

Các khái niệm cốt lõi

Luồng có thể chèn cho MediaStreamTrack dựa trên các khái niệm mà WebCodecs đề xuất trước đây và về cơ bản sẽ chia MediaStreamTrack thành 2 thành phần:

  • MediaStreamTrackProcessor, sử dụng nguồn của đối tượng MediaStreamTrack và tạo một luồng khung hình đa phương tiện, cụ thể là các đối tượng VideoFrame hoặc AudioFrame. Bạn có thể coi đây là một nguồn nhận dữ liệu của bản phụ đề có khả năng hiển thị các khung hình chưa mã hoá từ bản phụ đề dưới dạng một ReadableStream.
  • MediaStreamTrackGenerator, sử dụng một luồng khung hình nội dung nghe nhìn và hiển thị giao diện MediaStreamTrack. Bạn có thể cung cấp đối tượng này cho mọi đích nhận, giống như một bản nhạc từ getUserMedia(). Nó lấy các khung hình đa phương tiện làm dữ liệu đầu vào.

MediaStreamTrackProcessor

Đối tượng MediaStreamTrackProcessor hiển thị một thuộc tính là readable. Cho phép đọc các khung hình từ MediaStreamTrack. Nếu là một bản video, các đoạn được đọc từ readable sẽ là các đối tượng VideoFrame. Nếu là một bản âm thanh, các đoạn được đọc từ readable sẽ là các đối tượng AudioFrame.

MediaStreamTrackGenerator

Tương tự, đối tượng MediaStreamTrackGenerator cũng hiển thị một thuộc tính, writable, là một WritableStream cho phép ghi các khung hình đa phương tiện vào MediaStreamTrackGenerator, bản thân nó là một MediaStreamTrack. Nếu thuộc tính kind"audio", thì luồng sẽ chấp nhận các đối tượng AudioFrame và không thành công với bất kỳ loại nào khác. Nếu loại là "video", luồng sẽ chấp nhận các đối tượng VideoFrame và không thành công với bất kỳ loại nào khác. Khi một khung được ghi vào writable, phương thức close() của khung sẽ tự động được gọi, do đó, các tài nguyên đa phương tiện của khung sẽ không còn truy cập được từ JavaScript nữa.

MediaStreamTrackGenerator là một bản nhạc mà nguồn tuỳ chỉnh có thể được triển khai bằng cách ghi các khung hình đa phương tiện vào trường writable của bản nhạc đó.

Tổng hợp kiến thức đã học

Ý tưởng cốt lõi là tạo một chuỗi xử lý như sau:

Platform Track → Processor → Transform → Generator → Platform Sinks

Ví dụ dưới đây minh hoạ chuỗi này cho một ứng dụng máy quét mã vạch, trong đó làm nổi bật mã vạch được phát hiện trong luồng video trực tiếp.

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;

Bản minh hoạ

Bạn có thể xem bản minh hoạ trình quét mã QR trong phần trên khi hoạt động trên trình duyệt dành cho máy tính hoặc thiết bị di động. Giữ mã QR trước camera và ứng dụng sẽ phát hiện cũng như làm nổi bật mã đó. Bạn có thể xem mã nguồn của ứng dụng trên GitHub.

Trình quét mã QR đang chạy trong thẻ trình duyệt trên máy tính cho thấy một mã QR đã được phát hiện và làm nổi bật trên điện thoại mà người dùng cầm trước camera của máy tính xách tay.

Những điểm cần cân nhắc về quyền riêng tư và bảo mật

Tính bảo mật của API này dựa trên các cơ chế hiện có trong nền tảng web. Khi dữ liệu được hiển thị bằng các giao diện VideoFrameAudioFrame, các quy tắc của những giao diện đó để xử lý dữ liệu bị nhiễm nguồn gốc sẽ được áp dụng. Ví dụ: không thể truy cập dữ liệu từ các tài nguyên trên nhiều nguồn gốc do các quy định hạn chế hiện có đối với việc truy cập vào các tài nguyên đó (ví dụ: không thể truy cập vào các pixel của một phần tử hình ảnh hoặc video trên nhiều nguồn gốc). Ngoài ra, quyền truy cập vào dữ liệu đa phương tiện từ camera, micrô hoặc màn hình phải được người dùng cho phép. Dữ liệu đa phương tiện mà API này hiển thị đã có sẵn thông qua các API khác.

Phản hồi

Nhóm Chromium muốn biết ý kiến của bạn về trải nghiệm với luồng có thể chèn cho MediaStreamTrack.

Hãy cho chúng tôi biết về thiết kế API

Có điều gì về API không hoạt động như bạn mong đợi không? Hoặc có phương thức hay thuộc tính nào bị thiếu mà bạn cần triển khai ý tưởng của mình không? Bạn có câu hỏi hoặc nhận xét về mô hình bảo mật không? Báo cáo vấn đề về thông số kỹ thuật trên kho lưu trữ GitHub tương ứng hoặc thêm ý kiến của bạn vào một vấn đề hiện có.

Báo cáo vấn đề về việc triển khai

Bạn có phát hiện thấy lỗi trong quá trình triển khai Chromium không? Hoặc việc triển khai có khác với quy cách không? Báo cáo lỗi tại new.crbug.com. Nhớ cung cấp càng nhiều thông tin chi tiết càng tốt, hướng dẫn đơn giản để tái hiện và nhập Blink>MediaStream vào hộp Thành phần.

Thể hiện sự ủng hộ đối với API

Bạn có định dùng luồng có thể chèn cho MediaStreamTrack không? Sự ủng hộ công khai của bạn giúp nhóm Chromium ưu tiên các tính năng và cho các nhà cung cấp trình duyệt khác thấy tầm quan trọng của việc hỗ trợ các tính năng này.

Gửi một tweet đến @ChromiumDev bằng thẻ bắt đầu bằng #InsertableStreams và cho chúng tôi biết bạn đang sử dụng ở đâu và như thế nào.

Lời cảm ơn

Quy cách về luồng có thể chèn cho MediaStreamTrack được viết bởi Harald AlvestrandGuido Urdaneta. Bài viết này được Harald Alvestrand, Joe Medley, Ben Wagner, Huib KleinhoutFrançois Beaufort xem xét. Hình ảnh chính của Chris Montgomery trên Unsplash.