การเริ่มต้นใช้งานอุปกรณ์สื่อ

เมื่อพัฒนาสำหรับเว็บ มาตรฐาน 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>