สตรีมที่แทรกได้สำหรับ MediaStreamTrack

เนื้อหาของ MediaStreamTrack จะแสดงเป็นสตรีมที่สามารถดัดแปลงหรือใช้เพื่อสร้างเนื้อหาใหม่ได้

ฉากหลัง

ในบริบทของ Media Capture and Streams API อินเทอร์เฟซ MediaStreamTrack แสดงแทร็กสื่อเดียวภายในสตรีม โดยปกติแล้วจะเป็นแทร็กเสียงหรือวิดีโอ แต่ก็อาจมีแทร็กประเภทอื่นๆ ด้วย ออบเจ็กต์ MediaStream ประกอบด้วย ออบเจ็กต์ MediaStreamTrack ตั้งแต่ 0 รายการขึ้นไป ซึ่งแสดงแทร็กเสียงหรือวิดีโอต่างๆ แต่ละMediaStreamTrackอาจมีช่องอย่างน้อย 1 ช่อง แชแนลแสดงหน่วยที่เล็กที่สุดของสตรีมสื่อ เช่น สัญญาณเสียงที่เชื่อมโยงกับลำโพงที่กำหนด เช่น ซ้ายหรือขวาในแทร็กเสียงสเตอริโอ

สตรีมที่แทรกได้สำหรับ MediaStreamTrack คืออะไร

แนวคิดหลักเบื้องหลังสตรีมที่แทรกได้สำหรับ MediaStreamTrack คือการแสดงเนื้อหาของ MediaStreamTrack เป็นคอลเล็กชันของสตรีม (ตามที่กำหนดโดย WHATWG Streams API) คุณสามารถจัดการสตรีมเหล่านี้เพื่อเพิ่มคอมโพเนนต์ใหม่ๆ ได้

การให้สิทธิ์นักพัฒนาแอปเข้าถึงสตรีมวิดีโอ (หรือเสียง) โดยตรงจะช่วยให้นักพัฒนาแอปสามารถใช้การแก้ไขกับสตรีมได้โดยตรง ในทางตรงกันข้าม การทำงานเดียวกันในการดัดแปลงวิดีโอด้วยวิธีดั้งเดิมนั้น นักพัฒนาซอฟต์แวร์จะต้องใช้ตัวกลาง เช่น องค์ประกอบ <canvas> (ดูรายละเอียดของกระบวนการประเภทนี้ได้ที่ เช่น video + canvas = magic)

การสนับสนุนเบราว์เซอร์

Chrome 94 ขึ้นไปรองรับสตรีมที่แทรกได้สำหรับ MediaStreamTrack

กรณีการใช้งาน

กรณีการใช้งานสตรีมที่แทรกได้สำหรับ MediaStreamTrack รวมถึงแต่ไม่จำกัดเพียง

  • อุปกรณ์เสริมสำหรับการประชุมทางวิดีโอ เช่น "หมวกตลกๆ" หรือพื้นหลังเสมือน
  • การประมวลผลเสียง เช่น Vocoder ของซอฟต์แวร์

วิธีใช้สตรีมที่แทรกได้สำหรับ MediaStreamTrack

การตรวจหาฟีเจอร์

คุณตรวจหาฟีเจอร์สตรีมที่แทรกได้สำหรับการรองรับ MediaStreamTrack ได้ดังนี้

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

แนวคิดหลัก

สตรีมที่แทรกได้สำหรับ MediaStreamTrack สร้างขึ้นจากแนวคิดที่ก่อนหน้านี้เสนอโดย WebCodecs และแยก MediaStreamTrack ออกเป็น 2 องค์ประกอบในเชิงแนวคิด

  • MediaStreamTrackProcessor ซึ่งใช้แหล่งที่มาของออบเจ็กต์ MediaStreamTrack และสร้าง สตรีมของเฟรมสื่อ โดยเฉพาะออบเจ็กต์ VideoFrame หรือ AudioFrame คุณสามารถคิดว่า นี่คือแหล่งที่มาของแทร็กที่สามารถแสดงเฟรมที่ไม่ได้เข้ารหัสจากแทร็กเป็น ReadableStream
  • ซึ่งใช้สตรีมของเฟรมสื่อและแสดงอินเทอร์เฟซ MediaStreamTrackMediaStreamTrackGenerator โดยสามารถส่งไปยัง Sink ใดก็ได้ เช่นเดียวกับแทร็กจาก getUserMedia() โดยรับเฟรมสื่อเป็นอินพุต

MediaStreamTrackProcessor

ออบเจ็กต์ MediaStreamTrackProcessor จะแสดงพร็อพเพอร์ตี้ readable ซึ่งจะช่วยให้อ่าน เฟรมจาก MediaStreamTrack ได้ หากแทร็กเป็นแทร็กวิดีโอ ก้อนข้อมูลที่อ่านจาก readable จะเป็นออบเจ็กต์ VideoFrame หากแทร็กเป็นแทร็กเสียง ชิ้นส่วน ที่อ่านจาก readable จะเป็นออบเจ็กต์ AudioFrame

MediaStreamTrackGenerator

ออบเจ็กต์ MediaStreamTrackGenerator จะแสดงพร็อพเพอร์ตี้ writable เช่นกัน ซึ่งเป็น WritableStream ที่อนุญาตให้เขียนเฟรมสื่อไปยัง MediaStreamTrackGenerator ซึ่งเป็น MediaStreamTrack หากแอตทริบิวต์ kind เป็น "audio" สตรีมจะยอมรับออบเจ็กต์ AudioFrame และจะล้มเหลวหากเป็นออบเจ็กต์ประเภทอื่น หาก kind เป็น "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;

สาธิต

คุณดูการสาธิตเครื่องสแกนคิวอาร์โค้ดจากส่วนด้านบน ในการทำงานบนเบราว์เซอร์เดสก์ท็อปหรือเบราว์เซอร์บนอุปกรณ์เคลื่อนที่ได้ ถือคิวอาร์โค้ดไว้ตรงหน้ากล้อง แล้วแอปจะ ตรวจหาและไฮไลต์คิวอาร์โค้ดนั้น คุณดูซอร์สโค้ดของแอปพลิเคชันได้ ใน GitHub

เครื่องสแกนคิวอาร์โค้ดที่ทำงานในแท็บเบราว์เซอร์บนเดสก์ท็อปซึ่งแสดงคิวอาร์โค้ดที่ตรวจพบและไฮไลต์ไว้บนโทรศัพท์ที่ผู้ใช้ถือไว้หน้ากล้องของแล็ปท็อป

ข้อควรพิจารณาด้านความปลอดภัยและความเป็นส่วนตัว

ความปลอดภัยของ API นี้ขึ้นอยู่กับกลไกที่มีอยู่แล้วในแพลตฟอร์มเว็บ เมื่อมีการเปิดเผยข้อมูลโดยใช้ อินเทอร์เฟซ VideoFrame และ AudioFrame กฎของอินเทอร์เฟซเหล่านั้นในการจัดการกับ ข้อมูลที่ติดแท็กต้นทางจะมีผลบังคับใช้ เช่น ระบบจะเข้าถึงข้อมูลจากแหล่งข้อมูลข้ามต้นทางไม่ได้เนื่องจาก ข้อจำกัดที่มีอยู่ในการเข้าถึงแหล่งข้อมูลดังกล่าว (เช่น เข้าถึงพิกเซลของ องค์ประกอบรูปภาพหรือวิดีโอข้ามต้นทางไม่ได้) นอกจากนี้ การเข้าถึงข้อมูลสื่อจากกล้อง ไมโครโฟน หรือหน้าจอจะต้องได้รับการให้สิทธิ์จากผู้ใช้ ข้อมูลสื่อที่ API นี้แสดงนั้นพร้อมใช้งานอยู่แล้ว ผ่าน API อื่นๆ

ความคิดเห็น

ทีม Chromium ต้องการทราบความคิดเห็นของคุณเกี่ยวกับประสบการณ์การใช้งานสตรีมที่แทรกได้สำหรับ MediaStreamTrack

บอกเราเกี่ยวกับการออกแบบ API

มีสิ่งใดเกี่ยวกับ API ที่ทำงานไม่เป็นไปตามที่คุณคาดหวังไว้หรือไม่ หรือมีเมธอด หรือพร็อพเพอร์ตี้ที่ขาดหายไปซึ่งคุณต้องใช้เพื่อนำแนวคิดไปใช้ไหม หากมีคำถามหรือความคิดเห็นเกี่ยวกับ โมเดลความปลอดภัย แจ้งปัญหาเกี่ยวกับข้อกำหนดในที่เก็บ GitHub ที่เกี่ยวข้อง หรือแสดงความคิดเห็น ในปัญหาที่มีอยู่

รายงานปัญหาเกี่ยวกับการติดตั้งใช้งาน

หากพบข้อบกพร่องในการใช้งาน Chromium หรือการติดตั้งใช้งานแตกต่างจากข้อกำหนด ยื่นข้อบกพร่องที่ new.crbug.com โปรดใส่รายละเอียดให้มากที่สุดเท่าที่จะทำได้ วิธีการง่ายๆ ในการทำซ้ำ และป้อน Blink>MediaStream ในช่องคอมโพเนนต์

แสดงการสนับสนุน API

คุณวางแผนที่จะใช้สตรีมที่แทรกได้สำหรับ MediaStreamTrack ไหม การสนับสนุนแบบสาธารณะของคุณจะช่วยให้ทีม Chromium จัดลําดับความสําคัญของฟีเจอร์และแสดงให้ผู้ให้บริการเบราว์เซอร์รายอื่นๆ เห็นว่าการรองรับฟีเจอร์เหล่านี้มีความสําคัญเพียงใด

ทวีตถึง @ChromiumDev โดยใช้แฮชแท็ก #InsertableStreams และแจ้งให้เราทราบว่าคุณใช้ฟีเจอร์นี้ที่ไหนและอย่างไร

คำขอบคุณ

สตรีมที่แทรกได้สำหรับMediaStreamTrackเขียนโดย Harald Alvestrand และ Guido Urdaneta บทความนี้ได้รับการตรวจสอบโดย Harald Alvestrand, Joe Medley, Ben Wagner, Huib Kleinhout และ François Beaufort รูปภาพหลักโดย Chris Montgomery ใน Unsplash