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

François Beaufort
François Beaufort

يسمح Chrome 66 لصفحات الويب باستخدام عرض ثانوي مُرفق من خلال Presentation API والتحكم في محتواها من خلال Presentation 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);
  });
}

يؤدي الاتصال الذي يتلقّى رسالة إلى تنشيط "رسالة" حدث يمكنك الاستماع إليه. يمكن أن تكون الرسالة سلسلة أو 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 الرسمي الذي استخدمناه في هذه المقالة.

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

لقطة شاشة للعرض التوضيحي لجدار الصور
الصورة من تأليف "خوسيه لويس ميزا" / 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 ويأتي الدعم لاحقًا.

الموارد