بدء استخدام أجهزة الوسائط

عند تطوير الإصدار للويب، يوفّر معيار WebRTC واجهات برمجة التطبيقات للوصول إلى. الكاميرات والميكروفونات المتصلة بجهاز الكمبيوتر أو الهاتف الذكي. هذه الأجهزة يُشار إليها عادةً باسم "أجهزة الوسائط" ويمكن الوصول إليها باستخدام JavaScript من خلال الكائن navigator.mediaDevices الذي ينفذ MediaDevices من واجهة pyplot. من هذا الكائن، يمكننا تعداد جميع الأجهزة المتصلة، والاستماع إلى تغييرات الجهاز (عندما يكون الجهاز متصلاً أو غير متصل)، وفتح جهاز لاسترداد بث وسائط (انظر أدناه).

أكثر الطرق شيوعًا لاستخدام هذا الأمر هي من خلال الدالة getUserMedia()، التي يعرض وعدًا يتم تسليمه إلى MediaStream للوسائط المطابقة الأجهزة. تستخدم هذه الدالة كائن MediaStreamConstraints واحدًا المتطلبات التي لدينا. على سبيل المثال، لفتح صفحة الكاميرا والميكروفون الافتراضيين، سنتخذ الإجراءات التالية.

استخدام الوعود

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);
    });

استخدام async/await

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 تحتوي على فيديو واحد ومقطع صوتي واحد. في حال رفض الإذن، تظهر الرسالة تم رمي PermissionDeniedError. في حال عدم توفّر أجهزة مطابقة متصل، سيتم طرح NotFoundError.

يتوفّر المرجع الكامل لواجهة برمجة التطبيقات للواجهة MediaDevices على MDN Web. المستندات.

جارٍ الاستعلام عن أجهزة الوسائط

وفي تطبيق أكثر تعقيدًا، سنرغب على الأرجح في التحقق من جميع الكاميرات والميكروفونات المتصلة وتقديم الملاحظات المناسبة إلى المستخدم. ويمكن إجراء ذلك من خلال استدعاء الدالة enumerateDevices(). سيؤدي هذا إلى عرض وعد تتم مطابقته مع مصفوفة MediaDevicesInfo التي تصف لكل جهاز وسائط معروف. ويمكننا استخدام ذلك لتقديم واجهة مستخدم إلى المستخدم على اختيار اللعبة التي يفضلونها. يحتوي كل MediaDevicesInfo على سمة باسم kind بالقيمة audioinput أو audiooutput أو videoinput، مما يشير إلى أو نوع جهاز الوسائط.

استخدام الوعود

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/await

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 أو سماعة رأس بلوتوث أو مجموعة من مكبرات الصوت الخارجية. ضِمن لدعم ذلك بشكل صحيح، يجب أن يصغي تطبيق الويب إلى التغييرات من أجهزة الوسائط. يمكن إجراء ذلك من خلال إضافة مستمع إلى 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() يسمح لنا بفتح جهاز وسائط يستوفي متطلبات معينة. يمكن أن يكون هذا المطلب غير محددة بوضوح (الصوت و/أو الفيديو)، أو محددة جدًا (الحد الأدنى للكاميرا درجة الدقة أو رقم تعريف دقيق للجهاز). يوصى بأن تستخدم التطبيقات التي تستخدم تفحص واجهة برمجة التطبيقات 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>