JavaScript bridge API
Media and casting
The lock-screen media notification your page drives, and handing a video to a TV.
castMedia bridge#
window.WebToApk.castMedia(mediaUrl: String)
Offers [mediaUrl] to whatever on this phone can play it on another screen - Chromecast, a Smart TV app, a local player - through the system chooser. The type is taken from the URL ([CastMediaType]): an audio file (.mp3, .m4a, .aac, .ogg, .opus, .wav, .flac …) or an audio `data:` URL is offered to audio apps, anything else - video files, stream manifests, extension-less URLs - to video apps. This is a hand-off, not a cast session: the app does not stay in control of playback, and there is no callback. A page that needs a real session should use the Cast SDK in JavaScript instead.
Example
Offers a video or audio address to the apps on the phone that can play it on another screen (a Chromecast app, a Smart TV app, a video player), through the Android "Cast to..." chooser.
Returns: nothing, and no callback. Needs: nothing to switch on. The phone needs an app that accepts the link.
function castToTv(url) {
if (window.WebToApk && typeof window.WebToApk.castMedia === 'function') {
window.WebToApk.castMedia(url); // opens the "Cast to..." chooser
} else {
alert('Casting is only available in the app');
}
}
document.getElementById('cast-btn').addEventListener('click', function () {
var video = document.querySelector('video');
var url = video && video.currentSrc ? video.currentSrc : 'https://example.com/movie.mp4';
castToTv(url);
});Notes:
- This is a hand-off, not a cast session: your page does not control playback after the user picks an app.
- The address must be a full
https://link that other apps can open. A file inside your app ZIP, ablob:URL or a web page address will not play. - The type comes from the link: an audio file (
.mp3,.m4a,.aac,.ogg,.opus,.wav,.flac…) or anaudio/data:URL is offered to audio apps; anything else - video files,.m3u8streams, links without a file extension - to video apps.
clearMediaNotification bridge#
window.WebToApk.clearMediaNotification()
Lets web content drive the Android media-style notification and receive transport control callbacks (play/pause/next/prev) from the lock screen and notification shade. Usage from JavaScript: window.WebToApk.setMediaMetadata('Song Title', 'Artist Name', 'https://…/art.jpg') window.WebToApk.setPlaybackState(true, 30000, 240000) // playing, pos ms, dur ms window.WebToApk.clearMediaNotification() Callback from Android → JS: window.WebToApkOnMediaAction('play'|'pause'|'next'|'prev'|'stop')
Described by its group, Media Notification Bridge, rather than on its own.
Example
Removes the media notification and its lock-screen controls, for example when the user closes your player.
Returns: nothing. Needs: turn on Media Notification in Step 4 (Access) when you build. Without it the call does nothing.
There is no standard web call for this, so use the bridge:
function closePlayer() {
var audio = document.getElementById('player');
audio.pause();
audio.currentTime = 0;
if (window.WebToApk && typeof window.WebToApk.clearMediaNotification === 'function') {
window.WebToApk.clearMediaNotification();
}
}
document.getElementById('close-player').addEventListener('click', closePlayer);
// The notification's own Stop button already removes it; just stop your audio:
if ('mediaSession' in navigator) {
navigator.mediaSession.setActionHandler('stop', function () {
var audio = document.getElementById('player');
audio.pause();
audio.currentTime = 0;
});
}Notes: Use this for "stop", not for "pause" (for pause, send setPlaybackState(false, ...) so the Play button stays). Setting navigator.mediaSession.metadata = null does not remove the notification. The next setMediaMetadata / setPlaybackState (or new navigator.mediaSession metadata / state) brings the notification and the lock-screen controls back.
setMediaMetadata bridge#
window.WebToApk.setMediaMetadata(title: String, artist: String, artworkUrl: String)
Lets web content drive the Android media-style notification and receive transport control callbacks (play/pause/next/prev) from the lock screen and notification shade. Usage from JavaScript: window.WebToApk.setMediaMetadata('Song Title', 'Artist Name', 'https://…/art.jpg') window.WebToApk.setPlaybackState(true, 30000, 240000) // playing, pos ms, dur ms window.WebToApk.clearMediaNotification() Callback from Android → JS: window.WebToApkOnMediaAction('play'|'pause'|'next'|'prev'|'stop')
Described by its group, Media Notification Bridge, rather than on its own.
Example
Sets the title, artist and cover picture of the media notification and lock-screen player. Pages normally set navigator.mediaSession.metadata, which calls this for you.
Returns: nothing. Needs: turn on Media Notification in Step 4 (Access) when you build. Without it the call does nothing.
The public way (use this):
if ('mediaSession' in navigator && window.MediaMetadata) {
navigator.mediaSession.metadata = new MediaMetadata({
title: 'Episode 12', artist: 'My Podcast',
artwork: [{ src: 'https://example.com/cover.jpg', sizes: '512x512' }]
});
}The raw call. Arguments: title, artist, artworkUrl (use '' for no picture):
function showNowPlaying(track) {
if (!(window.WebToApk && typeof window.WebToApk.setMediaMetadata === 'function')) return;
window.WebToApk.setMediaMetadata(track.title, track.artist || '', track.cover || '');
window.WebToApk.setPlaybackState(true, 0, Math.round(track.seconds * 1000));
}
// Buttons in the notification come back through the standard API:
if ('mediaSession' in navigator) {
navigator.mediaSession.setActionHandler('nexttrack', function () { playNext(); });
navigator.mediaSession.setActionHandler('previoustrack', function () { playPrevious(); });
}Notes:
- The notification appears (or updates) with this call. An empty title shows the app name.
artworkUrlmust be a fullhttps://address on the internet. The app downloads it (4-second limit); if that fails, the app icon is shown.- Receive button presses with
navigator.mediaSession.setActionHandler(seenavigator.mediaSession), or with your ownwindow.WebToApkOnMediaAction = function (action) { ... }(play,pause,next,prev,stop) - use one of the two. AfterclearMediaNotification(), the next call to this (orsetPlaybackState) brings the notification and the lock-screen controls back.
setPlaybackState bridge#
window.WebToApk.setPlaybackState(isPlaying: Boolean, positionMs: Long, durationMs: Long)
Lets web content drive the Android media-style notification and receive transport control callbacks (play/pause/next/prev) from the lock screen and notification shade. Usage from JavaScript: window.WebToApk.setMediaMetadata('Song Title', 'Artist Name', 'https://…/art.jpg') window.WebToApk.setPlaybackState(true, 30000, 240000) // playing, pos ms, dur ms window.WebToApk.clearMediaNotification() Callback from Android → JS: window.WebToApkOnMediaAction('play'|'pause'|'next'|'prev'|'stop')
Described by its group, Media Notification Bridge, rather than on its own.
Example
Tells the media notification whether you are playing or paused, and where you are in the track. Pages normally set navigator.mediaSession.playbackState and call setPositionState, which call this for you.
Returns: nothing. Needs: turn on Media Notification in Step 4 (Access) when you build. Without it the call does nothing.
The public way (use this):
var audio = document.getElementById('player');
function publish() {
if (!('mediaSession' in navigator)) return;
navigator.mediaSession.playbackState = audio.paused ? 'paused' : 'playing';
if (audio.duration > 0 && navigator.mediaSession.setPositionState) {
navigator.mediaSession.setPositionState({ duration: audio.duration, position: audio.currentTime });
}
}
audio.addEventListener('play', publish);
audio.addEventListener('pause', publish);The raw call. Arguments: isPlaying (true/false), positionMs, durationMs (whole milliseconds):
function publishRaw(audio) {
if (!(window.WebToApk && typeof window.WebToApk.setPlaybackState === 'function')) return;
window.WebToApk.setPlaybackState(
!audio.paused,
Math.floor(audio.currentTime * 1000),
Math.floor((audio.duration || 0) * 1000)
);
}Notes: true shows the Pause button and keeps the notification from being swiped away; false shows Play. Call setMediaMetadata first, so the notification has a title. To remove the notification when the user stops, call clearMediaNotification().