เนื้อหาของ MediaStreamTrack
จะแสดงเป็นสตรีมที่ดัดแปลงหรือใช้สร้างเนื้อหาใหม่ได้
ข้อมูลเบื้องต้น
ในบริบทของ Media Capture and Streams API อินเทอร์เฟซ MediaStreamTrack
แสดงถึงสื่อแทร็กเดียวภายในสตรีม ซึ่งโดยทั่วไปจะเป็นแทร็กเสียงหรือวิดีโอ แต่อาจมีแทร็กประเภทอื่นๆ อยู่
ออบเจ็กต์ MediaStream
ประกอบด้วยออบเจ็กต์ MediaStreamTrack
อย่างน้อย 1 รายการ ซึ่งแสดงแทร็กเสียงหรือวิดีโอต่างๆ MediaStreamTrack
แต่ละรายการอาจมีแชแนลอย่างน้อย 1 รายการ ช่องแสดงหน่วยที่เล็กที่สุดของสตรีมสื่อ เช่น สัญญาณเสียงที่เชื่อมโยงกับลำโพงหนึ่งๆ เช่น ซ้ายหรือขวาในแทร็กเสียงสเตอริโอ
สตรีมที่แทรกได้สำหรับ 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
ออกเป็น 2 ส่วนตามแนวคิด ดังนี้
MediaStreamTrackProcessor
ซึ่งใช้แหล่งที่มาของออบเจ็กต์MediaStreamTrack
และสร้างสตรีมเฟรมสื่อ โดยเฉพาะออบเจ็กต์VideoFrame
หรือAudioFrame
คุณอาจคิดว่าสิ่งนี้เป็นแทร็กซิงค์ที่แสดงเฟรมที่ไม่ได้เข้ารหัสจากแทร็กเป็นReadableStream
MediaStreamTrackGenerator
ซึ่งใช้สตรีมเฟรมสื่อและแสดงอินเทอร์เฟซMediaStreamTrack
ซึ่งสามารถส่งไปยังซิงค์ใดก็ได้ เช่นเดียวกับแทร็กจาก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;
สาธิต
คุณดูการสาธิตการทำงานของเครื่องมือสแกนคิวอาร์โค้ดจากส่วนด้านบนได้บนเบราว์เซอร์ในเดสก์ท็อปหรืออุปกรณ์เคลื่อนที่ ถือคิวอาร์โค้ดไว้หน้ากล้อง แล้วแอปจะตรวจหาและไฮไลต์ให้ คุณดูซอร์สโค้ดของแอปพลิเคชันได้ใน Glitch
ข้อควรพิจารณาด้านความปลอดภัยและความเป็นส่วนตัว
ความปลอดภัยของ API นี้ขึ้นอยู่กับกลไกที่มีอยู่ในแพลตฟอร์มเว็บ เมื่อมีการเปิดเผยข้อมูลโดยใช้อินเทอร์เฟซ VideoFrame
และ AudioFrame
ระบบจะใช้กฎของอินเทอร์เฟซเหล่านั้นเพื่อจัดการกับข้อมูลที่ปนเปื้อนจากแหล่งที่มา เช่น ไม่สามารถเข้าถึงข้อมูลจากทรัพยากรข้ามแหล่งที่มาเนื่องจากข้อจํากัดที่มีอยู่ในการเข้าถึงทรัพยากรดังกล่าว (เช่น ไม่สามารถเข้าถึงพิกเซลขององค์ประกอบรูปภาพหรือวิดีโอข้ามแหล่งที่มา) นอกจากนี้ การเข้าถึงข้อมูลสื่อจากกล้อง ไมโครโฟน หรือหน้าจอยังขึ้นอยู่กับการให้สิทธิ์ของผู้ใช้ด้วย ข้อมูลสื่อที่ API นี้แสดงมีให้บริการผ่าน API อื่นๆ อยู่แล้ว
ความคิดเห็น
ทีม Chromium อยากทราบความคิดเห็นของคุณเกี่ยวกับสตรีมที่แทรกได้สำหรับ
MediaStreamTrack
บอกเราเกี่ยวกับการออกแบบ API
มีสิ่งใดเกี่ยวกับ API ที่ไม่ทำงานตามที่คาดไว้ไหม หรือมีเมธอดหรือพร็อพเพอร์ตี้ที่ขาดหายไปซึ่งคุณต้องนำไปใช้กับแนวคิดของคุณ คุณมีคำถามหรือความคิดเห็นเกี่ยวกับรูปแบบการรักษาความปลอดภัยไหม แจ้งปัญหาเกี่ยวกับข้อกำหนดใน GitHub repo ที่เกี่ยวข้อง หรือแสดงความคิดเห็นในปัญหาที่มีอยู่
รายงานปัญหาเกี่ยวกับการติดตั้งใช้งาน
หากพบข้อบกพร่องในการใช้งาน 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