I would like to create an HTML5 app in javascript that will run in Safari on an iOS device but be able to use Airplay as a second screen or expanded screen (not mirrored). The idea would be to have one UI on the device and a separate UI on the Airplay device. I know this can be done in a native app but this could be interesting if I could also do this in a browser.
Asked
Active
Viewed 174 times
1 Answers
0
I don't know what iOS devices you use for test but you can try with the WebKit API by Safari on iOS.
if (window.WebKitPlaybackTargetAvailabilityEvent) {
// Airplay is available
var video = document.getElementById('video');
video.addEventListener('webkitplaybacktargetavailabilitychanged', function(event) {
if (event.availability === 'available') {
// Airplay receiver is available
var receiverName = event.target.getAttribute('webkitCurrentPlaybackTargetName');
var picker = new WebKitPlaybackTargetPicker();
picker.showPicker(function (receiver) {
// Airplay receiver has been selected
var receiverUrl = receiver.url;
var externalWindow = window.open(receiverUrl);
externalWindow.focus();
}, function () {
console.log('Airplay receiver selection failed');
}, video);
}
});
}
But you have to know that not all Airplay receivers support displaying HTML content, so you may need to test different receivers to see which ones work with your app.
Example of HTML content with Safari Webkit
// Function to display HTML content on an external AirPlay-enabled display
function displayOnAirPlay(htmlContent) {
// Call webkitShowPlaybackTargetPicker to allow user to select AirPlay device
webkitShowPlaybackTargetPicker(function(target) {
if (target) {
// If a target device was selected, create a new window and load the HTML content
var externalWindow = target.createRemoteWebView();
externalWindow.loadHTMLString(htmlContent, { baseURL: null });
externalWindow.show();
}
});
}
// usage: display the contents of a div with ID "content" on an external display
var content = document.getElementById("content").innerHTML;
displayOnAirPlay(content);
This is a working example of HTML content, with a basic button and basic display content in the selected device.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>AirPlay Example</title>
</head>
<body>
<h1>AirPlay Example</h1>
<div id="content">
<p>This is some HTML content that will be displayed on the external AirPlay-enabled display.</p>
</div>
<button id="displayButton">Display on AirPlay</button>
<script>
// Get a reference to the display button and the content div
const displayButton = document.getElementById('displayButton');
const contentDiv = document.getElementById('content');
// Add an event listener to the display button
displayButton.addEventListener('click', async () => {
try {
// Request access to the ExternalOutputContext API
const context = await navigator.externalOutputContext.request();
// Get the list of available external displays
const displays = await context.getDisplays();
// Prompt the user to select an AirPlay-enabled display
const selectedDisplay = await context.showDisplayPicker(displays);
// If a display was selected, create a new window and load the HTML content
if (selectedDisplay) {
const externalWindow = await selectedDisplay.createWindow();
externalWindow.document.body.innerHTML = contentDiv.innerHTML;
externalWindow.show();
}
} catch (error) {
console.error(error);
}
});
</script>
</body>
</html>

arngrim280
- 59
- 3
-
How would this allow sending html content to the Airplay display? I see you created a video element, but what would you do with it? – jpcoder Mar 01 '23 at 02:42
-
This code is just an example, and in this case it works for video elements, but you can edit and use other html elements. I'm going to edit the post and add an example of sending HTML content. – arngrim280 Mar 01 '23 at 02:51
-
Thanks for the update. This looks promising but I have not been able to get this to work. Where does webkitShowPlaybackTargetPicker come from? Do you have a basic working example? – jpcoder Mar 01 '23 at 03:48
-
ok, try the new code that I added to the post, is a code with a button to allow the user to select an AirPlay device, and when a device is selected, it creates a new window on that device using the createRemoteWebView method, and load the HTML content from the content Div into that window using the loadHTMLString method. – arngrim280 Mar 01 '23 at 04:14
-
Does this work for you? I'm not finding that navigator has a webkitShowPlaybackTargetPicker method. If this does work for you, what devices did you test it on (host and airplay device)? – jpcoder Mar 01 '23 at 05:33
-
ohh you are right, that method was removed, sorry, now you need to use the ExternalOutputContext API and showDisplayPicker method, look my code again I already update it. – arngrim280 Mar 01 '23 at 05:49
-
Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/252231/discussion-between-jpcoder-and-arngrim280). – jpcoder Mar 01 '23 at 14:21
-
Did you test this? I'm showing navigator.externalOutputContext is undefined, even on an iOS device. – jpcoder Mar 01 '23 at 15:55
-
yeah it works for me with an iPhone 8 plus, what devices are you using for testing? – arngrim280 Mar 01 '23 at 17:12
-
iPhone 12 Pro with iOS 16.2. I added alert(navigator.externalOutputContext); to your code and it shows it's undefined. I also can not find any information on "externalOutputContext". Do you have a link to docs? – jpcoder Mar 01 '23 at 18:37