เมื่อพัฒนาสำหรับเว็บ มาตรฐาน WebRTC จะมี API สำหรับการเข้าถึง
กล้องและไมโครโฟนที่เชื่อมต่อกับคอมพิวเตอร์หรือสมาร์ทโฟน อุปกรณ์เหล่านี้
มักเรียกว่าอุปกรณ์สื่อและเข้าถึงได้ด้วย JavaScript
ผ่านออบเจ็กต์ navigator.mediaDevices
ซึ่งใช้ MediaDevices
ของ Google จากออบเจ็กต์นี้ เราสามารถแจกแจงอุปกรณ์ที่เชื่อมต่อทั้งหมด
อุปกรณ์เปลี่ยนแปลง (เมื่ออุปกรณ์เชื่อมต่ออยู่หรือยกเลิกการเชื่อมต่อ) และเปิดอุปกรณ์
เพื่อเรียกสตรีมสื่อ (ดูด้านล่าง)
วิธีที่ใช้กันมากที่สุดคือการใช้ฟังก์ชัน getUserMedia()
ซึ่ง
แสดงสัญญาที่จะแก้ไขเป็น MediaStream
สำหรับสื่อที่ตรงกัน
อุปกรณ์ ฟังก์ชันนี้ใช้ออบเจ็กต์ MediaStreamConstraints
รายการเดียวที่
ระบุข้อกำหนดที่เรามี ตัวอย่างเช่น หากต้องการเปิด
ไมโครโฟนและกล้องเริ่มต้น เราจะดำเนินการต่อไปนี้
การใช้ Promises
const constraints = {
'video': true,
'audio': true
}
navigator.mediaDevices.getUserMedia(constraints)
.then(stream => {
console.log('Got MediaStream:', stream);
})
.catch(error => {
console.error('Error accessing media devices.', error);
});
การใช้แบบไม่พร้อมกัน/รอ
const openMediaDevices = async (constraints) => {
return await navigator.mediaDevices.getUserMedia(constraints);
}
try {
const stream = openMediaDevices({'video':true,'audio':true});
console.log('Got MediaStream:', stream);
} catch(error) {
console.error('Error accessing media devices.', error);
}
การเรียก getUserMedia()
จะเรียกใช้คำขอสิทธิ์ หากผู้ใช้
ยอมรับสิทธิ์ สัญญาจะได้รับการแก้ไขด้วย MediaStream
ที่มี
วิดีโอ 1 แทร็กและแทร็กเสียง 1 แทร็ก หากสิทธิ์ถูกปฏิเสธ
PermissionDeniedError
โยนแล้ว ในกรณีที่ไม่มีอุปกรณ์ที่ตรงกัน
เชื่อมต่อแล้ว จะมีการส่ง NotFoundError
ดูข้อมูลอ้างอิง API ฉบับเต็มสำหรับอินเทอร์เฟซ MediaDevices
ได้ที่ MDN web
เอกสาร
กำลังค้นหาอุปกรณ์สื่อ
ในแอปพลิเคชันที่ซับซ้อน เราต้องตรวจสอบ
กล้องและไมโครโฟนที่เชื่อมต่ออยู่ และให้ความคิดเห็นที่เหมาะสมแก่
ผู้ใช้ ซึ่งทำได้ด้วยการเรียกใช้ฟังก์ชัน enumerateDevices()
การดำเนินการนี้จะ
แสดงผลสัญญาที่แก้ไขเป็นอาร์เรย์ของ MediaDevicesInfo
ที่อธิบาย
อุปกรณ์สื่อที่รู้จักแต่ละเครื่อง เราสามารถใช้สิ่งนี้เพื่อนำเสนอ UI แก่ผู้ใช้ ซึ่ง
ให้เลือกวิธีที่ตนชอบ MediaDevicesInfo
แต่ละรายการมีพร็อพเพอร์ตี้ชื่อ
kind
ที่มีค่า audioinput
, audiooutput
หรือ videoinput
หมายถึง
ว่าเป็นอุปกรณ์สื่อประเภทใด
การใช้ Promises
function getConnectedDevices(type, callback) {
navigator.mediaDevices.enumerateDevices()
.then(devices => {
const filtered = devices.filter(device => device.kind === type);
callback(filtered);
});
}
getConnectedDevices('videoinput', cameras => console.log('Cameras found', cameras));
การใช้แบบไม่พร้อมกัน/รอ
async function getConnectedDevices(type) {
const devices = await navigator.mediaDevices.enumerateDevices();
return devices.filter(device => device.kind === type)
}
const videoCameras = getConnectedDevices('videoinput');
console.log('Cameras found:', videoCameras);
การฟังการเปลี่ยนแปลงของอุปกรณ์
คอมพิวเตอร์ส่วนใหญ่รองรับการเสียบปลั๊กอุปกรณ์ต่างๆ ระหว่างรันไทม์ อาจจะเป็น
เว็บแคมที่เชื่อมต่อด้วย USB, ชุดหูฟังบลูทูธ หรือชุดลำโพงภายนอก ใน
เพื่อที่จะสนับสนุนอย่างเหมาะสม เว็บแอปพลิเคชันควรรับฟังการเปลี่ยนแปลง
ของอุปกรณ์สื่อต่างๆ ซึ่งทำได้โดยการเพิ่ม Listener ลงใน
navigator.mediaDevices
สำหรับกิจกรรม devicechange
// Updates the select element with the provided set of cameras
function updateCameraList(cameras) {
const listElement = document.querySelector('select#availableCameras');
listElement.innerHTML = '';
cameras.map(camera => {
const cameraOption = document.createElement('option');
cameraOption.label = camera.label;
cameraOption.value = camera.deviceId;
}).forEach(cameraOption => listElement.add(cameraOption));
}
// Fetch an array of devices of a certain type
async function getConnectedDevices(type) {
const devices = await navigator.mediaDevices.enumerateDevices();
return devices.filter(device => device.kind === type)
}
// Get the initial set of cameras connected
const videoCameras = getConnectedDevices('videoinput');
updateCameraList(videoCameras);
// Listen for changes to media devices and update the list accordingly
navigator.mediaDevices.addEventListener('devicechange', event => {
const newCameraList = getConnectedDevices('video');
updateCameraList(newCameraList);
});
ข้อจำกัดสื่อ
ออบเจ็กต์ข้อจำกัด ซึ่งต้องนำ MediaStreamConstraints
ไปใช้
อินเทอร์เฟซหนึ่ง ซึ่งเราจะส่งเป็นพารามิเตอร์ไปยัง getUserMedia()
ทำให้เราสามารถเปิด
อุปกรณ์สื่อที่มีคุณสมบัติตรงตามข้อกำหนดบางประการ ข้อกำหนดนี้อาจเป็น
กำหนดแบบคร่าวๆ (เสียงและ/หรือวิดีโอ) หรือเฉพาะเจาะจงมาก (กล้องขั้นต่ำ
หรือรหัสอุปกรณ์ที่แน่นอน) ขอแนะนำให้แอปพลิเคชันที่ใช้
API ของ getUserMedia()
จะตรวจสอบอุปกรณ์ที่มีอยู่ก่อนแล้วจึงระบุ
ข้อจำกัดที่ตรงกับอุปกรณ์ทุกประการโดยใช้ข้อจำกัด deviceId
และหากเป็นไปได้ อุปกรณ์จะได้รับการกำหนดค่าตามข้อจำกัดดังกล่าวด้วย พ
สามารถเปิดใช้การตัดเสียงก้องในไมโครโฟน หรือตั้งค่าความกว้างขั้นต่ำหรือเฉพาะ
และความสูงของวิดีโอจากกล้อง
async function getConnectedDevices(type) {
const devices = await navigator.mediaDevices.enumerateDevices();
return devices.filter(device => device.kind === type)
}
// Open camera with at least minWidth and minHeight capabilities
async function openCamera(cameraId, minWidth, minHeight) {
const constraints = {
'audio': {'echoCancellation': true},
'video': {
'deviceId': cameraId,
'width': {'min': minWidth},
'height': {'min': minHeight}
}
}
return await navigator.mediaDevices.getUserMedia(constraints);
}
const cameras = getConnectedDevices('videoinput');
if (cameras && cameras.length > 0) {
// Open first available video camera with a resolution of 1280x720 pixels
const stream = openCamera(cameras[0].deviceId, 1280, 720);
}
ดูเอกสารประกอบฉบับเต็มเกี่ยวกับอินเทอร์เฟซของ MediaStreamConstraints
ได้
บนเว็บ MDN
เอกสาร
การเล่นในเครื่อง
เมื่อเปิดอุปกรณ์สื่อและเรามีMediaStream
พร้อมใช้งาน
สามารถกำหนดให้กับองค์ประกอบวิดีโอหรือเสียงเพื่อเล่นสตรีมในเครื่อง
async function playVideoFromCamera() {
try {
const constraints = {'video': true, 'audio': true};
const stream = await navigator.mediaDevices.getUserMedia(constraints);
const videoElement = document.querySelector('video#localVideo');
videoElement.srcObject = stream;
} catch(error) {
console.error('Error opening video camera.', error);
}
}
HTML ที่จำเป็นสำหรับองค์ประกอบวิดีโอทั่วไปที่ใช้กับ getUserMedia()
จะ
มักจะมีแอตทริบิวต์ autoplay
และ playsinline
autoplay
จะทำให้สตรีมใหม่ที่กำหนด
ให้กับองค์ประกอบนั้นเล่นโดยอัตโนมัติ
แอตทริบิวต์ playsinline
อนุญาตให้วิดีโอเล่นในหน้าได้ แทนที่จะเล่นแบบเต็มหน้า
บนหน้าจอ ในเบราว์เซอร์มือถือบางเบราว์เซอร์ ขอแนะนำให้ใช้
controls="false"
สำหรับสตรีมแบบสด เว้นแต่ผู้ใช้ควรจะหยุดได้
ให้พวกเขา
<html>
<head><title>Local video playback</title></head>
<body>
<video id="localVideo" autoplay playsinline controls="false"/>
</body>
</html>