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

François Beaufort
François Beaufort

يسمح الإصدار 66 من Chrome لصفحات الويب باستخدام شاشة ثانوية مرفقة من خلال 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 wont 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.

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

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

يمكننا الآن إجراء المزيد من الإجراءات ومراقبة أحداث "الإغلاق" و "الإيقاف" كما هو موضّح أدناه. يُرجى العلم أنّه من الممكن إعادة الربط بجهاز "مغلق" 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 الصفحة الداخلية للتعرّف على عمليات الاكتشاف/التوفّر الداخلية.

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

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

الموارد