Presentation Receiver API Sample

Available in Chrome 58+ | View on GitHub | Browse Samples

Background

This sample illustrates the use of Presentation API, which gives the ability to access external presentation-type displays and use them for presenting Web content. The PresentationRequest object is associated with a request to initiate or reconnect to a presentation made by a controlling browsing context and it takes in a presentation request URL when constructed. A presentation can be started by calling the start() method on the PresentationRequest object.

Live Output


Controller

const presentationRequest = new PresentationRequest(['receiver/index.html']);

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

let presentationConnection;

document.querySelector('#start').addEventListener('click', function() {
log('Starting presentation request...');
presentationRequest.start()
.then(connection => {
log('> Connected to ' + connection.url + ', id: ' + connection.id);
})
.catch(error => {
log('> ' + error.name + ': ' + error.message);
});
});

presentationRequest.addEventListener('connectionavailable', function(event) {
presentationConnection = event.connection;
presentationConnection.addEventListener('close', function() {
log('> Connection closed.');
});
presentationConnection.addEventListener('terminate', function() {
log('> Connection terminated.');
});
presentationConnection.addEventListener('message', function(event) {
log('> ' + event.data);
});
});

document.querySelector('#sendMessage').addEventListener('click', function() {
const message = document.querySelector('#message').value.trim();
const lang = document.body.lang || 'en-US';

log('Sending "' + message + '"...');
presentationConnection.send(JSON.stringify({message, lang}));
});

document.querySelector('#close').addEventListener('click', function() {
log('Closing connection...');
presentationConnection.close();
});

document.querySelector('#terminate').addEventListener('click', function() {
log('Terminating connection...');
presentationConnection.terminate();
});

document.querySelector('#reconnect').addEventListener('click', () => {
const presentationId = document.querySelector('#presentationId').value.trim();

presentationRequest.reconnect(presentationId)
.then(connection => {
log('Reconnected to ' + connection.id);
})
.catch(error => {
log('Presentation.reconnect() error, ' + error.name + ': ' + error.message);
});
});

/* Availability monitoring */

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

Receiver

let connectionIdx = 0;
let messageIdx = 0;

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

function addConnection(connection) {
connection.connectionId = ++connectionIdx;
addMessage('New connection #' + connectionIdx);

connection.addEventListener('message', function(event) {
messageIdx++;
const data = JSON.parse(event.data);
const logString = 'Message ' + messageIdx + ' from connection #' +
connection.connectionId + ': ' + data.message;
addMessage(logString, data.lang);
maybeSetFruit(data.message);
connection.send('Received message ' + messageIdx);
});

connection.addEventListener('close', function(event) {
addMessage('Connection #' + connection.connectionId + ' closed, reason = ' +
event.reason + ', message = ' + event.message);
});
};

/* Utils */

const fruitEmoji = {
'grapes': '\u{1F347}',
'watermelon': '\u{1F349}',
'melon': '\u{1F348}',
'tangerine': '\u{1F34A}',
'lemon': '\u{1F34B}',
'banana': '\u{1F34C}',
'pineapple': '\u{1F34D}',
'green apple': '\u{1F35F}',
'apple': '\u{1F34E}',
'pear': '\u{1F350}',
'peach': '\u{1F351}',
'cherries': '\u{1F352}',
'strawberry': '\u{1F353}'
};

function addMessage(content, language) {
const listItem = document.createElement("li");
if (language) {
listItem.lang = language;
}
listItem.textContent = content;
document.querySelector("#message-list").appendChild(listItem);
};

function maybeSetFruit(message) {
const fruit = message.toLowerCase();
if (fruit in fruitEmoji) {
document.querySelector('#main').textContent = fruitEmoji[fruit];
}
};