عرض صفحات الويب على شاشات إضافية متصلة

François Beaufort
François Beaufort

يسمح الإصدار Chrome 66 لصفحات الويب باستخدام شاشة عرض مُرفقة ثانوية من خلال Presentation API والتحكّم في محتواها من خلال Presentation Receiver API.

1/2. اختيار المستخدم لشاشة ثانوية مرفقة
1/2. يختار المستخدم شاشة ثانوية مرفقة
2/2. يتم عرض صفحة ويب تلقائيًا على الشاشة التي تم اختيارها مسبقًا
2/2. يتم عرض صفحة ويب تلقائيًا على الشاشة التي تم اختيارها سابقًا.

الخلفية

حتى الآن، يمكن لمطوّري البرامج على الويب إنشاء تجارب تتيح للمستخدمين رؤية محتوى محلي في Chrome يختلف عن المحتوى الذي يظهر على شاشة عن بُعد، وفي الوقت نفسه، يمكنهم التحكّم في هذه التجربة على الجهاز. وتشمل الأمثلة إدارة قائمة تشغيل على youtube.com أثناء تشغيل الفيديوهات على التلفزيون، أو عرض شرائح عرض تتضمّن ملاحظات المتحدّث على كمبيوتر محمول أثناء عرض التقديم في وضع ملء الشاشة في جلسة Hangout.

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

عرض صفحة

سأشرح لك كيفية استخدام واجهة برمجة التطبيقات Presentation API لعرض صفحة ويب على الشاشة الثانوية المرفقة. تتوفّر النتيجة النهائية على الرابط https://googlechrome.github.io/samples/presentation-api/.

أولاً، سننشئ عنصرًا جديدًا من النوع PresentationRequest يحتوي على عنوان URL الذي نريد عرضه على الشاشة الثانوية المرفقة.

const presentationRequest = new PresentationRequest('receiver.html');

In this article, I won’t cover use cases where the parameter passed to
`PresentationRequest` can be an array like `['cast://foo’, 'apple://foo',
'https://example.com']` as this is not relevant there.

We can now monitor presentation display availability and toggle a "Present"
button visibility based on presentation displays availability. Note that we can
also decide to always show this button.

<aside class="caution"><b>Caution:</b> The browser may use more energy while the <code>availability</code> object is alive
and actively listening for presentation display availability changes. Please
use it with caution in order to save energy on mobile.</aside>

```js
presentationRequest.getAvailability()
  .then(availability => {
    console.log('Available presentation displays: ' + availability.value);
    availability.addEventListener('change', function() {
      console.log('> Available presentation displays: ' + availability.value);
    });
  })
  .catch(error => {
    console.log('Presentation availability not supported, ' + error.name + ': ' +
        error.message);
  });

يتطلب عرض طلب عرض عرض تقديمي إجراءً من المستخدم، مثل النقر على زر. لنفترض أنّنا نُجري طلبًا إلى presentationRequest.start() عند النقر على زرّ، ثمّ ننتظر حلّ المشكلة بعد أن يختار المستخدم شاشة عرض التقديم (مثل شاشة عرض ثانوية مرفقة في حالة الاستخدام).

function onPresentButtonClick() {
  presentationRequest.start()
  .then(connection => {
    console.log('Connected to ' + connection.url + ', id: ' + connection.id);
  })
  .catch(error => {
    console.log(error);
  });
}

قد تتضمّن القائمة المقدَّمة للمستخدم أيضًا نقاط نهاية عن بُعد، مثل أجهزة Chromecast إذا كنت متصلاً بشبكة تعرض إعلانات عنها. يُرجى العِلم أنّه لا تظهر الشاشات المطابقة في القائمة. يمكنك الاطّلاع على http://crbug.com/840466.

أداة اختيار شاشة العرض التقديمي
أداة اختيار شاشة العرض التقديمي

عند حلّ الوعد، يتم عرض صفحة الويب على عنوان URL للعنصر PresentationRequest على الشاشة المحدّدة. تهانينا.

يمكننا الآن إجراء المزيد من الإجراءات ومراقبة أحداث "الإغلاق" و "الإيقاف" كما هو موضّح أدناه. تجدر الإشارة إلى أنّه من الممكن إعادة الربط بجهاز "مغلق" presentationConnection باستخدام presentationRequest.reconnect(presentationId) حيث يكون presentationId هو رقم تعريف كائن presentationRequest السابق.

function onCloseButtonClick() {
  // Disconnect presentation connection but will allow reconnection.
  presentationConnection.close();
}

presentationConnection.addEventListener('close', function() {
  console.log('Connection closed.');
});


function onTerminateButtonClick() {
  // Stop presentation connection for good.
  presentationConnection.terminate();
}

presentationConnection.addEventListener('terminate', function() {
  console.log('Connection terminated.');
});

التواصل مع الصفحة

تخطر على بالك الآن هذا سؤال رائع، ولكن كيف يمكنني تمرير الرسائل بين صفحة وحدة التحكُّم (الصفحة التي أنشأناها للتو) وصفحة المُستلِم (الصفحة التي مررنا بها إلى الكائن PresentationRequest

أولاً، لنسترِد عمليات الربط الحالية في صفحة المُستلِم باستخدام navigator.presentation.receiver.connectionList وننصت إلى عمليات الربط القادمة كما هو موضّح أدناه.

// Receiver page

navigator.presentation.receiver.connectionList
.then(list => {
  list.connections.map(connection => addConnection(connection));
  list.addEventListener('connectionavailable', function(event) {
    addConnection(event.connection);
  });
});

function addConnection(connection) {

  connection.addEventListener('message', function(event) {
    console.log('Message: ' + event.data);
    connection.send('Hey controller! I just received a message.');
  });

  connection.addEventListener('close', function(event) {
    console.log('Connection closed!', event.reason);
  });
}

يؤدي الاتصال الذي يتلقّى رسالة إلى بدء حدث "message" يمكنك الاستماع إليه. يمكن أن تكون الرسالة سلسلة أو Blob أو ArrayBuffer أو ArrayBufferView. ما عليك سوى طلب connection.send(message) من صفحة وحدة التحكّم أو صفحة المستلِم لإرساله.

// Controller page

function onSendMessageButtonClick() {
  presentationConnection.send('Hello!');
}

presentationConnection.addEventListener('message', function(event) {
  console.log('I just received ' + event.data + ' from the receiver.');
});

يمكنك الاطّلاع على العيّنة على الرابط https://googlechrome.github.io/samples/presentation-api/ للتعرّف على طريقة عملها. أنا متأكد من أنك ستستمتع بهذا كثيرًا مثلي.

العيّنات والعروض التوضيحية

يمكنك الاطِّلاع على نموذج Chrome الرسمي الذي استخدمناه في هذه المقالة.

ننصحك أيضًا بمشاهدة العرض التجريبي لميزة "جدار الصور" التفاعلي. يتيح تطبيق الويب هذا لأجهزة التحكّم المتعددة عرض عرض شرائح للصور بشكل تعاوني على شاشة عرض العروض التقديمية. يتوفّر الرمز على الرابط https://github.com/GoogleChromeLabs/presentation-api-samples.

لقطة شاشة للعرض التوضيحي لخدمة &quot;صور الحائط&quot;
صورة تابعة لـ José Luis Mieza / CC BY-NC-SA 2.0

ملاحظة أخرى

يحتوي Chrome على قائمة متصفّح "البث" التي يمكن للمستخدمين تفعيلها في أي وقت أثناء زيارة أحد المواقع الإلكترونية. إذا أردت التحكّم في العرض التقديمي التلقائي لهذه القائمة، عليك تخصيص navigator.presentation.defaultRequest لكائن presentationRequest مخصّص تم إنشاؤه في وقت سابق.

// Make this presentation the default one when using the "Cast" browser menu.
navigator.presentation.defaultRequest = presentationRequest;

نصائح للمطوّرين

لفحص صفحة المستلِم وتصحيح أخطاءها، انتقِل إلى صفحة chrome://inspect الداخلية، واختَر "غير ذلك"، ثم انقر على رابط "فحص" بجانب عنوان URL المعروض حاليًا.

فحص صفحات أجهزة استقبال العروض
فحص صفحات مستلمي العروض التقديمية

يمكنك أيضًا الاطّلاع على chrome://media-router-internals الصفحة الداخلية للتعرّف على عمليات الاكتشاف/التوفّر الداخلية.

الخطوات التالية

بدءًا من Chrome 66، أصبحت أنظمة ChromeOS وLinux وWindows متاحة. ستتوفّر لاحقًا إمكانية استخدام التطبيق على أجهزة Mac.

الموارد