تنفيذ CameraStream باستخدام WebRTC

1. قبل البدء

تنتمي السمة CameraStream إلى الأجهزة التي يمكنها بث خلاصات الفيديو إلى الشاشات الذكية وأجهزة Chromecast والهواتف الذكية. أصبح بروتوكول WebRTC متوافقًا الآن مع سمة CameraStream، ما يعني أنّه يمكنك تقليل وقت الاستجابة لبدء التشغيل والبث بشكل كبير من جهاز كاميرا إلى جهاز شاشة Google Nest.

أجهزة الكاميرا التي تبث المحتوى إلى شاشة Google Nest

المتطلبات الأساسية

المُعطيات

  • كيفية نشر خدمة السحابة الإلكترونية للمنزل الذكي
  • كيفية ربط خدمتك بخدمة "مساعد Google"
  • كيفية البث إلى شاشة Google Nest باستخدام بروتوكول WebRTC

المتطلبات

  • متصفح ويب، مثل Google Chrome
  • جهاز iOS أو Android مزوّد بتطبيق Google Home
  • الإصدار 10.16 من Node.js أو إصدار أحدث
  • خطة Blaze (الدفع حسب الاستخدام) لمنصّة Firebase
  • جهاز كاميرا ويب مضمّن أو خارجي يمكنه التعامل مع دقة عالية الدقة بالكامل
  • شاشة Google Nest

2. البدء

تثبيت Firebase CLI

تتيح لك أداة Firebase CLI عرض تطبيقات الويب محليًا ونشرها على "استضافة Firebase".

لتثبيت واجهة برمجة التطبيقات Firebase CLI، اتّبِع الخطوات التالية:

  1. في وحدة التحكّم الطرفية، نزِّل واجهة Firebase CLI وثبتْها:
$ npm install -g firebase-tools
  1. تأكَّد من تثبيت واجهة برمجة التطبيقات بشكل صحيح:
$ firebase --version
  1. عليك تفويض واجهة برمجة التطبيقات Firebase CLI باستخدام حسابك على Google:
$ firebase login

إنشاء مشروع

  1. انتقِل إلى Google Home Developer Console.
  2. انقر على إنشاء مشروع، وأدخِل اسمًا للمشروع، ثم انقر على إنشاء مشروع.

اسم المشروع

تشغيل تطبيق عميل CameraStream

يتضمّن رمز المصدر الخاص بهذا الدليل التعليمي لأحد عملاء WebRTC الذي ينشئ جلسة WebRTC ويتفاوض عليها ويديرها بين كاميرا الويب وجهاز شاشة المنزل الذكي من Google.

لتشغيل تطبيق عميل WebRTC في CameraStream، يمكنك تنفيذ أحد الإجراءات التالية:

  • انقر على الزر التالي لتنزيل رمز المصدر على جهاز التطوير:

  • استنسِخ مستودع GitHub هذا:
    $ git clone https://github.com/google-home/smarthome-camerastream-webrtc.git
    

يحتوي الرمز على الأدلة التالية:

  • دليل camerastream-start الذي يحتوي على الرمز المبدئي الذي تستند إليه
  • دليل camerastream-done الذي يحتوي على رمز الحلّ لمشروع Codelab المكتمل

يحتوي الدليل camerastream-start على الأدلة الفرعية التالية:

  • الدليل الفرعي public الذي يحتوي على واجهة مستخدم أمامية للتحكّم بسهولة في حالة جهاز الكاميرا ومراقبتها
  • الدليل الفرعي functions الذي يحتوي على خدمة سحابة إلكترونية مُطبَّقة بالكامل تدير الكاميرا باستخدام Cloud Functions لـ Firebase و"قاعدة البيانات الآنية الاستجابة"

يحتوي الرمز المبدئي على TODO تعليقًا تشير إلى مكان إضافة رمز أو تغييره، مثل المثال التالي:

// TODO: Implement full SYNC response.

إنشاء مشروع على Firebase

  1. انتقِل إلى Firebase.
  2. انقر على إنشاء مشروع وأدخِل اسم مشروعك.
  3. ضَع علامة في مربّع الاختيار الخاص بالاتفاقية وانقر على متابعة. إذا لم يكن هناك مربّع اختيار للاتفاقية، يمكنك تخطّي هذه الخطوة.
    إنشاء مشروع Firebase
  4. بعد إنشاء مشروعك على Firebase، ابحث عن رقم تعريف المشروع. انتقِل إلى نظرة عامة على المشروع وانقر على رمز الإعدادات > إعدادات المشروع.
    فتح إعدادات المشروع
  5. يظهر مشروعك ضمن علامة التبويب عام.
    الإعدادات العامة للمشروع

الربط مع Firebase

  1. انتقِل إلى الدليل camerastream-start، ثمّ أعدّ واجهة Firebase CLI باستخدام مشروعك على "مساعد Google":
$ cd camerastream-start
$ firebase use <firebase-project-id>
  1. في الدليل camerastream-start، انتقِل إلى المجلد functions ثم ثبِّت جميع التبعيات اللازمة:
$ cd functions
$ npm install
  1. إذا ظهرت لك الرسالة التالية، تجاهلها. يرجع سبب هذا التحذير إلى التبعيات القديمة. لمزيد من المعلومات، يُرجى الاطّلاع على هذه المشكلة على GitHub.
found 5 high severity vulnerabilities
  run `npm audit fix` to fix them, or `npm audit` for details
  1. بدء مشروع على Firebase:
$ firebase init
  1. اختَر الدوالّ واستضافة. يؤدي ذلك إلى إعداد واجهات برمجة التطبيقات والميزات اللازمة لمشروعك.
? Which Firebase CLI features do you want to set up for this folder? Press Space to select features, then Enter to confirm your choices. 
❯◯ Realtime Database: Configure a security rules file for Realtime Database and (optionally) provision default instance
 ◯ Firestore: Deploy rules and create indexes for Firestore
 ◉ Functions: Configure a Cloud Functions directory and its files
 ◉ Hosting: Configure files for Firebase Hosting and (optionally) set up GitHub Action deploys
 ◯ Hosting: Set up GitHub Action deploys
 ◯ Storage: Configure a security rules file for Cloud Storage
 ◯ Extensions: Set up an empty Extensions manifest
  1. اضبط Cloud Functions باستخدام الملفات التلقائية، وتأكَّد من عدم استبدال ملفَي index.js وpackage.json الحاليَين في نموذج المشروع:
? Would you like to initialize a new codebase, or overwrite an existing one?
Overwrite

? What language would you like to use to write Cloud Functions? 
JavaScript

? File functions/package.json already exists. Overwrite? 
No

? File functions/index.js already exists. Overwrite? 
No

? Do you want to install dependencies with npm now? 
Yes
  1. اضبط ميزة "الاستضافة" باستخدام الدليل public في رمز المشروع واستخدِم ملف index.html الحالي:
? What do you want to use as your public directory? 
public

? Configure as a single-page app (rewrite all urls to /index.html)? 
Yes

? Set up automatic builds and deploys with GitHub?
No

? File public/index.html already exists. Overwrite?
 No

3- تبادل رسائل بروتوكول وصف الجلسة (SDP)

يُعدّ تبادل رسائل وصف الجلسة (SDP) خطوة مهمة في إنشاء بث WebRTC. بروتوكول SDP هو بروتوكول مستند إلى نص يصف خصائص جلسة الوسائط المتعددة. ويُستخدَم هذا البروتوكول في WebRTC للتفاوض على مَعلمات الاتصال من نظير إلى نظير، مثل برامج الترميز المستخدَمة وعناوين IP للمشاركين والمنافذ المستخدَمة لنقل الوسائط.

لاستخدام "قاعدة بيانات في الوقت الفعلي" كمضيف لتبادل رسائل وصف الجلسة بين كاميرا الويب وتطبيق CameraStream لأجهزة المنزل الذكي، اتّبِع الخطوات التالية:

  1. في وحدة تحكّم Firebase، انقر على إنشاء > قاعدة بيانات في الوقت الفعلي > إنشاء قاعدة بيانات.

صفحة &quot;قاعدة بيانات في الوقت الفعلي&quot; في وحدة تحكُّم Firebase

  1. في القائمة المنسدلة موقع "قاعدة بيانات الوقت الفعلي"، اختَر موقعًا مناسبًا لاستضافة قاعدة بياناتك.

القائمة المنسدلة لموقع &quot;قاعدة بيانات Realtime&quot; في مربّع الحوار &quot;إعداد قاعدة البيانات&quot;

  1. اختَر البدء في وضع الاختبار، ثم انقر على تفعيل. عند تفعيل "قاعدة بيانات الوقت الفعلي"، يجب أن يكون بإمكانك الإشارة إليها من تطبيق عميل CameraStream.
  1. في وحدة تحكُّم Firebase، اختَر 513f2be95dcd7896.png إعدادات المشروع > إعدادات المشروع > e584a9026e2b407f.pngإضافة Firebase إلى تطبيق الويب لبدء سير عمل الإعداد.
  2. إذا سبق لك إضافة تطبيق إلى مشروعك على Firebase، انقر على إضافة تطبيق لعرض خيارات المنصة.
  3. أدخِل لقبًا للتطبيق، مثل My web app، ثم انقر على تسجيل التطبيق.
  4. في قسم إضافة حزمة تطوير البرامج (SDK) لمنصّة Firebase، اختَر استخدام علامة <script>.
  5. انسخ القيم من عنصر firebasebaseConfig ثم الصقها في ملف camaerastream-start/public/webrtc_generator.js.
const firebaseConfig = {
  apiKey: "XXXXX",
  authDomain: "XXXXX",
  projectId: "XXXXX",
  storageBucket: "XXXXX",
  messagingSenderId: "XXXXX",
  appId: "XXXXX",
  measurementId: "XXXXX"
};
  1. انقر على متابعة إلى وحدة التحكّم لإكمال العملية. سيظهر لك تطبيق الويب الذي تم إنشاؤه حديثًا في صفحة إعدادات المشروع.

4. إنشاء كاميرا WebRTC

بعد ضبط الإجراء، يجب أن تعالج خدمة السحابة الإلكترونية النوايا التالية:

  • نية SYNC تحدث عندما يريد "مساعد Google" معرفة الأجهزة التي ربطها المستخدم. يتم إرسال هذا الرمز إلى خدمتك عندما يربط المستخدم حسابًا. يجب الردّ باستخدام حمولة JSON تتضمّن أجهزة المستخدم وإمكاناتها.
  • نية EXECUTE/QUERY تحدث عندما يريد "مساعد Google" التحكّم في جهاز نيابةً عن أحد المستخدمين. يجب الردّ باستخدام حِمل JSON يتضمّن حالة التنفيذ لكل جهاز مطلوب.

في هذا القسم، يمكنك تعديل الدوال التي تم نشرها سابقًا لمعالجة هذه النوايا.

تعديل الردّ على SYNC

  1. انتقِل إلى ملف functions/index.js. يحتوي على الرمز البرمجي للاستجابة لطلبات "مساعد Google".
  2. عدِّل intent SYNC لعرض البيانات الوصفية للجهاز وإمكاناته:

index.js

app.onSync((body) => {
return {
  requestId: body.requestId,
  payload: {
    agentUserId: USER_ID,
    devices: [{
      id: 'camera',
      type: 'action.devices.types.CAMERA',
      traits: [
        'action.devices.traits.OnOff',
        'action.devices.traits.CameraStream',
      ],
      name: {
        defaultNames: ['My WebRTC Camera'],
        name: 'Camera',
        nicknames: ['Camera'],
      },
      deviceInfo: {
        manufacturer: 'Acme Co',
        model: 'acme-camera',
        hwVersion: '1.0',
        swVersion: '1.0.1',
      },
      willReportState: false,
      attributes: {
        cameraStreamSupportedProtocols:['webrtc'],
        cameraStreamNeedAuthToken: true, 
        cameraStreamSupportsPreview: true
      },
    }],
  },
};
});
  1. لم يتم تحديد USER_ID في الرمز. أضِف ما يلي ضمن const _ = require('underscore');:
// Hardcoded user ID
const USER_ID = '123';

معالجة النية EXECUTE

يعالج EXECUTE intent الأوامر لتعديل حالة الجهاز. يعرض الردّ حالة كلّ أمر، مثل SUCCESS أو ERROR أو PENDING، وحالة الجهاز الجديدة.

لمعالجة طلب EXECUTE، عدِّل طلب EXECUTE لعرض نقطة نهاية signaling لمشروع Firebase في ملف functions/index.js:

index.js

app.onExecute(async (body,headers) => {
  var array = headers.authorization.split(' ');
  var snapshot = await firebaseRef.ref('/userId/'+array[1]).once('value');
  var offerGenLocation = snapshot.val().type;
  const {requestId} = body;

  var result = {
    status: 'SUCCESS',
    states: {
      cameraStreamProtocol: 'webrtc',
      cameraStreamSignalingUrl:'https://us-central1-<project-id>.cloudfunctions.net/signaling?token='+array[1], // TODO: Add Firebase hosting URL
      cameraStreamIceServers: '',
      cameraStreamOffer:'',
      cameraStreamAuthToken:'',
    },
    ids: [ 
      'camera'
    ],
  };
  
  return {
    requestId: requestId,
    payload: {
      commands: [result],
    },
  };
});

التعامل مع مشاركة الموارد المتعدّدة المصادر (CORS)

لمعالجة CORS بسبب استخدام طريقة POST لإرسال ملف وصف الجلسة، أضِف عنوان URL لاستضافة Firebase إلى صفيف allowlist في ملف functions/index.js:

index.js

'use strict';
.....

var allowList = ['https://www.gstatic.com','https://<firebase-project-id>.web.app']; //TODO Add Firebase hosting URL.

لمزيد من المعلومات عن مشاركة الموارد المتعددة المصادر (CORS)، يُرجى الاطّلاع على مشاركة الموارد المتعددة المصادر (CORS).

التعامل مع إنهاء البث

للتعامل مع إنهاء بث WebRTC، أضِف عنوان URL لدالة "الإرسال" في Firebase إلى ملف public/webrtc_generator.js:

webrtc_generator.js

terminateButton.onclick = function(){
  console.log('Terminating Stream!!')
  var signalingURL = 'https://us-central1-<project-id>.cloudfunctions.net/signaling'; //TODO Add Firebase hosting URL
   var http = new XMLHttpRequest();

النشر على Firebase

للنشر على Firebase، يمكنك نشر عملية التسليم المعدَّلة في السحابة الإلكترونية باستخدام Firebase CLI:

$ firebase deploy

ينشر هذا الأمر تطبيق ويب والعديد من وظائف السحابة الإلكترونية لبرنامج Firebase:

...

✔ Deploy complete!

Project Console: https://console.firebase.google.com/project/<project-id>/overview
Hosting URL: https://<project-id>.web.app

ضبط مشروعك على Developer Console

  1. انتقِل إلى Play Console.
  2. انقر على إنشاء مشروع، وأدخِل اسمًا للمشروع، ثم انقر على إنشاء مشروع.

اسم المشروع

اختيار الدمج من السحابة الإلكترونية إلى السحابة الإلكترونية

في صفحة المشروع الرئيسية في "وحدة تحكّم المطوّر"، اختَر إضافة عملية دمج من السحابة الإلكترونية إلى السحابة الإلكترونية ضمن من السحابة الإلكترونية إلى السحابة الإلكترونية.

إضافة عملية دمج من السحابة الإلكترونية إلى السحابة الإلكترونية

  1. أدخِل اسم عملية الدمج، واختَر كاميرا ضمن نوع الجهاز. سيظهر هذا الاسم في تطبيق Google Home لاحقًا عندما يكون هناك جهاز يجب إعداده. بالنسبة إلى هذا الدليل التعليمي حول رموز الترميز، أدخلنا WebRTC Codelab كاسم معروض، ولكن يمكنك استخدام اسم مختلف.

إضافة اسم معروض

  1. ضمن علامة التطبيق التجارية، حمِّل ملف png لرمز التطبيق بحجم 144 × 144 بكسل واسمه .png.

إضافة رمز تطبيق

تفعيل ربط الحساب

لتفعيل ربط الحسابات بعد نشر مشروعك، اتّبِع الخطوات التالية:

  1. انتقِل إلى Developer Console وافتح المشروع.
  2. ضمن قسم من السحابة الإلكترونية إلى السحابة الإلكترونية، انقر على تطوير > تعديل بجانب عملية الدمج.
  3. في صفحة الإعداد والضبط، ابحث عن قسم ربط الحساب وأدخِل المعلومات التالية في مربّعات النصّ المقابلة:

معرِّف العميل

ABC123

سر العميل

DEF456

عنوان URL للترخيص

https://us-central1-
.cloudfunctions.net/fakeauth

عنوان URL للرمز المميّز

https://us-central1-
.cloudfunctions.net/faketoken

تعديل عناوين URL لربط الحساب

  1. انقر على حفظ > اختبار.

5- اختبار كاميرا WebRTC الافتراضية

  1. انتقِل إلى عنوان URL للاستضافة الذي ظهر لك عند نشر مشروعك على Firebase. ستظهر لك الواجهة التالية، وهي تطبيق CameraStream العميل:

واجهة تطبيق عميل CameraStream

  1. في لوحة درجة دقة الفيديو على الجهاز، اختَر الفيديو المطلوب.
  2. امنح تطبيق CameraStream العميل الإذن بالوصول إلى كاميرا الويب والميكروفون. تظهر خلاصة فيديو من كاميرا الويب على جهاز العميل.
  1. في تطبيق Google Home، انقر على إضافة > يعمل مع Google.

صفحة &quot;إعداد جهاز&quot; في تطبيق Google Home

  1. ابحث عن الإجراء الذي أنشأته ثم اختَره.

إجراء المنزل الذكي في تطبيق Google Home

  1. دوِّن الرمز الأبجدي الرقمي الفريد المكوّن من خمسة أحرف لأنّك ستحتاج إليه لاحقًا.

الرمز الأبجدي الرقمي الفريد المكوّن من خمسة أرقام

  1. انقر على الرجوع. تتم إضافة كاميرا WebRTC إلى البنية في تطبيق Google Home.

بدء بث WebRTC

  1. في صفحة الويب الخاصة بتطبيق CameraStream، أدخِل الرمز الأبجدي الرقمي من القسم الأخير في مربّع نص قيمة الرمز المميّز لربط الحساب، ثم انقر على إرسال.

مربّع نص قيمة رمز ربط الحساب

  1. لبدء جلسة WebRTC من جهاز شاشة Google الذكية، عليك تنفيذ أحد الإجراءات التالية:
  • قُل "Ok Google، أريد بث كاميرا WebRTC".
  • على جهاز الشاشة الذكية من Google، انقر على Home control (التحكّم في المنزل) > Camera (الكاميرا) > WebRTC camera (كاميرا WebRTC).

من تطبيق CameraStream لعملاء المنزل الذكي من Google، ستلاحظ أنّه تم إنشاء وتبادل عرض SPD وSDP للإجابة بنجاح. يتم بث الصورة من كاميرا الويب إلى جهازك من خلال تقنية WebRTC.

6- تهانينا

تهانينا! لقد تعرّفت على كيفية بث المحتوى من كاميرا الويب إلى جهاز شاشة Google Nest باستخدام بروتوكول WebRTC.

مزيد من المعلومات