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

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

ที่มา

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

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

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

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

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

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

Use Case

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

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

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

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

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

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

แนวคิดหลัก

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

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

MediaStreamTrackProcessor

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

MediaStreamTrackGenerator

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

ข้อมูลประชากร

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

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

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

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

ความคิดเห็น

ทีม Chromium ต้องการทราบข้อมูลเกี่ยวกับประสบการณ์ที่คุณได้รับจากสตรีมที่แทรกได้สำหรับ MediaStreamTrack

บอกให้เราทราบเกี่ยวกับการออกแบบ API

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

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

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

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

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

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

ข้อความแสดงการยอมรับ

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