(تقريبًا) كاميرا ويب عديمة الفائدة تتدفق من المستعرض. الجزء 2. WebRTC

بطريقة ما واحد من المقالات القديمة والتي تم التخلي عنها بالفعل ، كتبت عن مدى سهولة وبطبيعة الحال يمكنك بث الفيديو من قماش عبر مآخذ الويب. في تلك المقالة ، تحدثت بإيجاز عن كيفية التقاط الفيديو من الكاميرا والصوت من الميكروفون باستخدام واجهة برمجة تطبيقات ميدياستريم، كيفية ترميز الدفق المستلم وإرساله عبر مآخذ الويب إلى الخادم. ومع ذلك ، فإنهم في الواقع لا يفعلون ذلك ، فبالنسبة لعمليات البث ، يستخدمون إما برنامجًا خاصًا يحتاج إلى التثبيت والتهيئة: مرتجلاً ، يمكن أن يكون هذا فتح برامج البث، أو يستخدمون WebRTC ، الذي يعمل مباشرة خارج الصندوق ، أي أنه لا يتطلب تثبيت أي مكونات إضافية على غرار مشغل الفلاش ، والتي سيتم حذفها من متصفح Chromium بالفعل في ديسمبر.

اليوم سنتحدث عن WebRTC.

الاتصال في الوقت الفعلي عبر الويب (WebRTC) ليس بروتوكولًا واحدًا ، فهو عبارة عن مجموعة كاملة من المعايير والبروتوكولات وواجهات برمجة تطبيقات JavaScript التي توفر معًا اتصال صوتي مرئي في الوقت الفعلي من نظير إلى نظير ، ويمكن أيضًا استخدامها لنقل أي البيانات الثنائية. عادةً ما تعمل المتصفحات كأقران ، ولكن يمكن أن تكون أيضًا تطبيقًا للهاتف المحمول ، على سبيل المثال. لتنظيم اتصال p2p بين العملاء ، يلزم دعم المتصفح لأنواع مختلفة من ترميز الفيديو والصوت ، ودعم مجموعة متنوعة من بروتوكولات الشبكة ، وضمان تفاعل الأجهزة مع المتصفح (من خلال طبقات نظام التشغيل): كاميرات الويب ، وبطاقات الصوت. كل هذه المجموعة من التقنيات مخفية خلف تجريد JavaScript API لراحة المطور.

يتلخص كل ذلك في ثلاث واجهات برمجة تطبيقات:

تحضير تدفقات الصوت والفيديو للإرسال

يبدأ كل شيء "بالتقاط" تدفقات وسائط كاميرا الويب والميكروفون. بالطبع ، التدفقات الأولية ليست مناسبة لتنظيم مؤتمر عن بعد ، فكل دفق يحتاج إلى المعالجة: تحسين الجودة ، ومزامنة الصوت مع الفيديو ، ووضع علامات التزامن في دفق الفيديو ، والتأكد من أن معدل البت المطابق لعرض النطاق الترددي المتغير باستمرار للقناة . يعتني المتصفح بكل هذا ، ولا يضطر المطور حتى إلى القلق بشأن توفير الترميز لتدفقات الوسائط. داخل متصفح حديث ، توجد بالفعل طبقات برامج للالتقاط وتحسين الجودة (إزالة الصدى والضوضاء من الصوت وتحسين الصورة) وترميز الفيديو والصوت. يظهر مخطط الطبقة في الشكل. 1:

(تقريبًا) كاميرا ويب عديمة الفائدة تتدفق من المستعرض. الجزء 2. WebRTCأرز. 1. طبقات معالجة الصوت والفيديو في المتصفح

تتم جميع عمليات المعالجة مباشرة في المتصفح نفسه ، دون الحاجة إلى معالجة إضافية. لا المكونات الإضافية المطلوبة. ومع ذلك ، لا تزال الأمور غير وردية في عام 2020. هناك متصفحات لا تدعم بشكل كامل حتى الآن واجهة برمجة تطبيقات ميدياستريم، يمكنك اتباع الرابط ومشاهدة جدول التوافق في الأسفل. IE على وجه الخصوص مخيب للآمال مرة أخرى.

يمكنك القيام بأشياء شيقة للغاية باستخدام التدفقات المستلمة: يمكنك استنساخ وتغيير دقة الفيديو والتلاعب بجودة الصوت ، ويمكنك التقاط و "إرفاق" تدفق Media Stream بـ علامة وإلقاء نظرة على نفسك على صفحة html. أو يمكنك رسم دفق على قماش ، وتعيين WebGL أو CSS3 ، وتطبيق عوامل تصفية مختلفة على الفيديو ، والتقاط الفيديو المعالج من القماش ثم إرساله عبر الشبكة إلى الخادم ، وتحويل الشفرة ونشره للجميع (مرحبًا بك لايف ، نشل و اخرين). لن أقوم هنا بتحليل كيفية إنجاز مثل هذه الأشياء ، سأقدم بعض الأمثلة الموجودة على الويب:

https://jeeliz.com/ - يقوم الرجال بعمل سيرة ذاتية حقيقية بجافا سكريبت. لديهم كل ترسانة مكتبات js متنوعة للعمل مع دفق فيديو على قماش: اكتشاف الوجوه ، والأشياء ، وتطبيق المرشحات (الأقنعة ، كما هو الحال في Instagram) ، وما إلى ذلك. مثال ممتاز لكيفية معالجة الفيديو في الوقت الفعلي مباشرة في المتصفح بدون مكونات إضافية.

Canvas CaptureStream API - وثائق API لالتقاط دفق فيديو من قماش. مدعوم بالفعل في Chrome و Opera و Firefox

RTCPeer الاتصال

لقد وصلنا إلى النقطة المهمة ، ولكن كيف ننقل الفيديو إلى مستخدم آخر؟ يأتي في المقدمة RTCPeer الاتصال. باختصار ، في هذه الخطوة تقريبًا ، تحتاج إلى إنشاء كائن RTCPeerConnection:

const peerConnection = new RTCPeerConnection({
  iceServers: [{
    urls: 'stun:stun.l.google.com:19302'
  }]
});

نحدد iceServers كأحد الخيارات - هذا خادم يساعد على توفير اتصال بين مستعرضين خلف NAT'om. أي ، تم حل المشكلة هنا: كيف تعرف IP للمحاور إذا كان وراء NAT لمزود الخدمة الخاص به؟ يأتي بروتوكول ICE للإنقاذ ، في الواقع ، لا ينطبق ICE على WebRTC على الإطلاق ، ولكن المزيد حول ذلك لاحقًا.

في السابق ، كان لدينا تدفقات Usermedia:

navigator.mediaDevices.getUserMedia({ video: true, audio: true }).then(stream => {
  // Usermedia-потоки, обычно это видео и аудио 
  const tracks = stream.getTracks();

   for (const track of tracks) {
     // каждый трек присоединяем к peerConnection
     peerConnection.addTrack(track);
   }
}).catch(console.error);

بعد ذلك ، يبدأ الحدث المطلوب عند التفاوض على peerConnection ، حيث يجب علينا في المعالج إنشاء عرض (من حيث SDP - بروتوكول وصف الجلسة) وتعيينه إلى peerConnection عبر طريقة setLocalDescription. حول SDP - ما هو وحول تنسيقات العرض والإجابة - سنتحدث أكثر.

بعد تعيين نظير LocalDescription ، يقوم المستعرض "بتجميع" مرشحات الجليد ، أي يجد طرقًا مختلفة للتواصل من خلال NAT. حرائق حدث onicegatheringstatechange. في معالج onicegatheringstatechange ، نسمح بالاتصال بخادم webrtc-signaling-server لتبادل وصف الجلسة بين الأقران:

peerConnection.oniceconnectionstatechange = (event) => {
      console.log('Connection state: ', peerConnection.iceConnectionState);

      if (peerConnection.iceConnectionState === 'connected') {
        // Можем активировать кнопку Start broadcast
        setBroadcasting(true);
        setBroadcastingBtnActive(true);
      }
    };

// Событие срабатывает сразу, как только добавился медаиапоток в peerConnection
peerConnection.onnegotiationneeded = (event) => {
      // Создаем и назначаем SDP offer
      peerConnection.createOffer().
        then((offer) => peerConnection.setLocalDescription(offer)).
        catch(console.error);
    };

// Событие срабатывает каждый раз, как появляется ICE кандидат
peerConnection.onicegatheringstatechange = (ev) => {
      let connection = ev.target;

      // Now we can activate broadcast button
      if (connection.iceGatheringState === 'complete') {
        let delay = 50;
        let tries = 0;
        let maxTries = 3;

        let timerId = setTimeout(function allowStreaming() {
          if (isOnline) {
            setBroadcastingBtnActive(true);
            return;
          }

          if (tries < maxTries) {
            tries += 1;
            delay *= 2;
            timerId = setTimeout(allowStreaming, delay);
          } else {
            // TODO: show user notification
            console.error("Can't connect to server");

            alert("Can't connect to server");
          }
        }, delay);
      }
    };

خادم webrtc-signaling-server هو الخادم المطلوب لتبادل وصف الجلسة بين نظيرين ، ويمكن أن يكون أبسط websocket أو xhr-server على أي PL. مهمتها بسيطة: قبول وصف الجلسة من أحد الأقران ونقله إلى آخر.

بعد تبادل أوصاف الجلسة ، يكون كلا الجانبين جاهزًا للبث واستقبال تدفقات الفيديو ، على الجانب الذي يستقبل دفق الفيديو ، يتم تشغيل حدث المسار على اتصال النظير ، في المعالج ، يمكن تعيين المسارات المستلمة إلى وانظر إلى محاورك المفضل. مزيد من النظرية والتفاصيل.

الروابط والأدب:

https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection - توثيق RTCPeer الاتصال

https://github.com/pion/webrtc - تنفيذ بروتوكولات WebRTC أثناء التنقل

https://webrtcforthecurious.com/ - كتاب من مبدعي الرائد

https://hpbn.co/ - كتاب شبكات متصفح عالية الأداء. تتم مناقشة قضايا ضمان الأداء العالي لتطبيقات الويب بالتفصيل. في النهاية ، تم وصف WebRTC. الكتاب قديم بالتأكيد (2013) ، لكنه لا يفقد أهميته.

في الجزء التالي ، أريد أن أعطي جزءًا أكبر قليلاً من النظرية والممارسة لتحليل استقبال ومعالجة دفق الفيديو على الخادم باستخدام pion ، وتحويل الشفرة إلى HLS عبر ffmpeg للبث اللاحق للمشاهدين في المتصفح.

للصبر: النموذج الأولي الخاص بي من بث الفيديو من كاميرا ويب للتفاعل من خلال خادم قائم على الرواد في نشل (هذه مجرد تجربة).

المصدر: www.habr.com

إضافة تعليق