API پل جاوااسکریپت
رسانه و پخش روی صفحه دیگر
اعلان رسانهای صفحهٔ قفل که صفحهٔ شما کنترل میکند، و ارسال ویدیو به تلویزیون.
requestPictureInPicture استاندارد وب#
video.requestPictureInPicture() — Picture-in-Picture
نمونه
API استاندارد تصویر در تصویر: یک ویدیو را در پنجره کوچک شناور کنید در حالی که کاربر کار دیگری میکند. Chrome در اندروید آن را دارد و WebView اندروید ندارد؛ در اپلیکیشن ویدیو پنجره شناور را پر میکند، همانطور که در Chrome.
خروجی: یک Promise برای یک PictureInPictureWindow (رویدادهای width، height، resize). ویدیو enterpictureinpicture و سپس leavepictureinpicture را میگیرد وقتی کاربر پنجره را میبندد یا بزرگ میکند؛ document.pictureInPictureElement در این فاصله همان ویدیو است. بدون لمس NotAllowedError رد میکند، پیش از بارگذاری فراداده ویدیو یا وقتی disablePictureInPicture دارد InvalidStateError رد میکند. نیازمندی: تصویر در تصویر در ساخت روشن باشد (وقتی کد شما requestPictureInPicture را فراخوانی کند خودش روشن میشود)، اندروید ۸ یا جدیدتر.
<video id="v" src="clip.mp4" controls playsinline></video>
<button id="pip">Pop out</button>
<script>
const v = document.getElementById('v');
const btn = document.getElementById('pip');
btn.hidden = !document.pictureInPictureEnabled;
btn.addEventListener('click', async () => {
try {
if (document.pictureInPictureElement) await document.exitPictureInPicture();
else await v.requestPictureInPicture();
} catch (e) {
console.warn('Picture-in-Picture:', e.name);
}
});
v.addEventListener('enterpictureinpicture', () => { btn.textContent = 'Back to app'; });
v.addEventListener('leavepictureinpicture', () => { btn.textContent = 'Pop out'; });
</script>هنگام خروج کاربر خودکار به پنجرهٔ شناور بروید و ساختی را که پشتیبانی نمیکند گزارش دهید:
const v = document.getElementById('v');
if (!document.pictureInPictureEnabled || v.disablePictureInPicture) {
document.getElementById('pip').hidden = true; // this build has no picture-in-picture
}
document.addEventListener('visibilitychange', async () => {
if (document.hidden && !v.paused && !document.pictureInPictureElement) {
try { await v.requestPictureInPicture(); }
catch (e) { console.warn(e.name); } // NotAllowedError without a tap
}
});منتظر فراداده بمانید و با پنجره تغییر اندازه دهید:
async function popOut(video) {
if (video.readyState < 1) await new Promise((r) => video.addEventListener('loadedmetadata', r, { once: true }));
try {
const pipWin = await video.requestPictureInPicture();
pipWin.addEventListener('resize', () => console.log(pipWin.width, pipWin.height));
} catch (e) {
if (e.name === 'InvalidStateError') showMessage('This video cannot float.');
else if (e.name === 'NotAllowedError') showMessage('Tap the button to pop out.');
}
}
document.getElementById('pip').onclick = () => popOut(document.getElementById('v'));نکتهها: Android کل اپلیکیشن را در پنجرهٔ شناور قرار میدهد، بنابراین ویدیو ابتدا بهتنهایی (تمامصفحه) نشان داده میشود و پنجره شکل ویدیو را میگیرد؛ با خروج از پنجره، ویدیو به صفحه برمیگردد. document.exitPictureInPicture() اپلیکیشن را به تمامصفحه برمیگرداند. وقتی ساخت شما تصویر در تصویر ندارد، document.pictureInPictureEnabled برابر false است، مثل مرورگری که آن را ندارد. تغییر حالت بهصورت appmint:pip به صفحه میرسد. مسیرهای داخلی: __pipEnter, __pipExit, __pipAvailable, __pipPrepare.
__pipAvailable پل#
window.WebToApk.__pipAvailable(): Boolean
اینکه آیا video.requestPictureInPicture() میتواند کار کند: PiP در ساخت روشن باشد، Android 8 یا بالاتر.
نمونه
همراه با WebToApk.__pipEnter مستند شده - نمونهٔ آنجا این یکی را هم نشان میدهد.
انتقال داخلی پشت video.requestPictureInPicture() و document.exitPictureInPicture(). صفحهها از API استاندارد استفاده میکنند؛ هرگز اینها را مستقیم فراخوانی نکنید، چون متدهای __ ممکن است بدون اطلاع تغییر کنند.
خروجی: __pipEnter(width, height) وقتی اندروید پنجره را پذیرفت "ok" برمیگرداند (با نسبت ابعاد ویدیو)، در غیر این صورت "unsupported" / "failed". باز و بسته شدن پنجره بهصورت appmint:pip با {inPip} میرسد. __pipAvailable() وقتی ساخت تصویر در تصویر را روی اندروید ۸ به بالا دارد درست است. نیازمندی: تصویر در تصویر در ساخت روشن باشد.
از API عمومی استفاده کنید:
const video = document.querySelector('video');
button.addEventListener('click', () => video.requestPictureInPicture());ابتدا پشتیبانی را بررسی کنید و رد شدن را گزارش کنید:
async function floatVideo(video) {
if (!document.pictureInPictureEnabled) { showMessage('Picture-in-picture is not on in this app.'); return; }
try {
await video.requestPictureInPicture();
} catch (err) {
showMessage('Could not open the floating window.');
}
}دوباره از آن خارج شوید و وضعیت را با رویدادهای استاندارد دنبال کنید:
video.addEventListener('enterpictureinpicture', () => hideControls());
video.addEventListener('leavepictureinpicture', () => showControls());
closeBtn.onclick = () => { if (document.pictureInPictureElement) document.exitPictureInPicture(); };نکتهها: در پوستهٔ اپلیکیشن پیادهسازی شده است (PictureInPictureShim.kt). __pipPrepare مانع میشود پوسته هنگام ورود به پنجره، صفحه را برای مرحلهٔ تمامصفحه به حالت افقی بچرخاند.
__pipEnter پل#
window.WebToApk.__pipEnter(width: Int, height: Int): String
پنجرهٔ PiP را با نسبت ابعاد ویدیوی [width]×[height] باز میکند: «ok»، یا «unsupported» / «failed». تغییر حالت بهصورت `appmint:pip`.
نمونه
انتقال داخلی پشت video.requestPictureInPicture() و document.exitPictureInPicture(). صفحهها از API استاندارد استفاده میکنند؛ هرگز اینها را مستقیم فراخوانی نکنید، چون متدهای __ ممکن است بدون اطلاع تغییر کنند.
خروجی: __pipEnter(width, height) وقتی اندروید پنجره را پذیرفت "ok" برمیگرداند (با نسبت ابعاد ویدیو)، در غیر این صورت "unsupported" / "failed". باز و بسته شدن پنجره بهصورت appmint:pip با {inPip} میرسد. __pipAvailable() وقتی ساخت تصویر در تصویر را روی اندروید ۸ به بالا دارد درست است. نیازمندی: تصویر در تصویر در ساخت روشن باشد.
از API عمومی استفاده کنید:
const video = document.querySelector('video');
button.addEventListener('click', () => video.requestPictureInPicture());ابتدا پشتیبانی را بررسی کنید و رد شدن را گزارش کنید:
async function floatVideo(video) {
if (!document.pictureInPictureEnabled) { showMessage('Picture-in-picture is not on in this app.'); return; }
try {
await video.requestPictureInPicture();
} catch (err) {
showMessage('Could not open the floating window.');
}
}دوباره از آن خارج شوید و وضعیت را با رویدادهای استاندارد دنبال کنید:
video.addEventListener('enterpictureinpicture', () => hideControls());
video.addEventListener('leavepictureinpicture', () => showControls());
closeBtn.onclick = () => { if (document.pictureInPictureElement) document.exitPictureInPicture(); };نکتهها: در پوستهٔ اپلیکیشن پیادهسازی شده است (PictureInPictureShim.kt). __pipPrepare مانع میشود پوسته هنگام ورود به پنجره، صفحه را برای مرحلهٔ تمامصفحه به حالت افقی بچرخاند.
__pipExit پل#
window.WebToApk.__pipExit()
document.exitPictureInPicture(): اپلیکیشن را به تمامصفحه برمیگرداند.
نمونه
همراه با WebToApk.__pipEnter مستند شده - نمونهٔ آنجا این یکی را هم نشان میدهد.
انتقال داخلی پشت video.requestPictureInPicture() و document.exitPictureInPicture(). صفحهها از API استاندارد استفاده میکنند؛ هرگز اینها را مستقیم فراخوانی نکنید، چون متدهای __ ممکن است بدون اطلاع تغییر کنند.
خروجی: __pipEnter(width, height) وقتی اندروید پنجره را پذیرفت "ok" برمیگرداند (با نسبت ابعاد ویدیو)، در غیر این صورت "unsupported" / "failed". باز و بسته شدن پنجره بهصورت appmint:pip با {inPip} میرسد. __pipAvailable() وقتی ساخت تصویر در تصویر را روی اندروید ۸ به بالا دارد درست است. نیازمندی: تصویر در تصویر در ساخت روشن باشد.
از API عمومی استفاده کنید:
const video = document.querySelector('video');
button.addEventListener('click', () => video.requestPictureInPicture());ابتدا پشتیبانی را بررسی کنید و رد شدن را گزارش کنید:
async function floatVideo(video) {
if (!document.pictureInPictureEnabled) { showMessage('Picture-in-picture is not on in this app.'); return; }
try {
await video.requestPictureInPicture();
} catch (err) {
showMessage('Could not open the floating window.');
}
}دوباره از آن خارج شوید و وضعیت را با رویدادهای استاندارد دنبال کنید:
video.addEventListener('enterpictureinpicture', () => hideControls());
video.addEventListener('leavepictureinpicture', () => showControls());
closeBtn.onclick = () => { if (document.pictureInPictureElement) document.exitPictureInPicture(); };نکتهها: در پوستهٔ اپلیکیشن پیادهسازی شده است (PictureInPictureShim.kt). __pipPrepare مانع میشود پوسته هنگام ورود به پنجره، صفحه را برای مرحلهٔ تمامصفحه به حالت افقی بچرخاند.
__pipPrepare پل#
window.WebToApk.__pipPrepare()
صفحه میخواهد برای PiP ویدیویی را تمامصفحه کند: برای آن حالت افقی را اجباری نکنید.
نمونه
همراه با WebToApk.__pipEnter مستند شده - نمونهٔ آنجا این یکی را هم نشان میدهد.
انتقال داخلی پشت video.requestPictureInPicture() و document.exitPictureInPicture(). صفحهها از API استاندارد استفاده میکنند؛ هرگز اینها را مستقیم فراخوانی نکنید، چون متدهای __ ممکن است بدون اطلاع تغییر کنند.
خروجی: __pipEnter(width, height) وقتی اندروید پنجره را پذیرفت "ok" برمیگرداند (با نسبت ابعاد ویدیو)، در غیر این صورت "unsupported" / "failed". باز و بسته شدن پنجره بهصورت appmint:pip با {inPip} میرسد. __pipAvailable() وقتی ساخت تصویر در تصویر را روی اندروید ۸ به بالا دارد درست است. نیازمندی: تصویر در تصویر در ساخت روشن باشد.
از API عمومی استفاده کنید:
const video = document.querySelector('video');
button.addEventListener('click', () => video.requestPictureInPicture());ابتدا پشتیبانی را بررسی کنید و رد شدن را گزارش کنید:
async function floatVideo(video) {
if (!document.pictureInPictureEnabled) { showMessage('Picture-in-picture is not on in this app.'); return; }
try {
await video.requestPictureInPicture();
} catch (err) {
showMessage('Could not open the floating window.');
}
}دوباره از آن خارج شوید و وضعیت را با رویدادهای استاندارد دنبال کنید:
video.addEventListener('enterpictureinpicture', () => hideControls());
video.addEventListener('leavepictureinpicture', () => showControls());
closeBtn.onclick = () => { if (document.pictureInPictureElement) document.exitPictureInPicture(); };نکتهها: در پوستهٔ اپلیکیشن پیادهسازی شده است (PictureInPictureShim.kt). __pipPrepare مانع میشود پوسته هنگام ورود به پنجره، صفحه را برای مرحلهٔ تمامصفحه به حالت افقی بچرخاند.
castMedia پل#
window.WebToApk.castMedia(mediaUrl: String)
[mediaUrl] را به هر چیزی روی این گوشی که بتواند آن را روی صفحه دیگر پخش کند - Chromecast، اپلیکیشن Smart TV، یک پخشکننده محلی - از طریق انتخابگر سیستم پیشنهاد میکند. نوع از روی URL گرفته میشود ([CastMediaType]): فایل صوتی (.mp3, .m4a, .aac, .ogg, .opus, .wav, .flac …) یا URL از نوع `data:` صوتی به اپلیکیشنهای صوتی پیشنهاد میشود، هر چیز دیگر - فایلهای ویدیو، مانیفستهای پخش زنده، URLهای بدون پسوند - به اپلیکیشنهای ویدیو. این یک تحویل است، نه نشست پخش: اپلیکیشن کنترل پخش را نگه نمیدارد و فراخوانی برگشتی وجود ندارد. صفحهای که نشست واقعی میخواهد باید بهجای آن از Cast SDK در جاوااسکریپت استفاده کند.
نمونه
یک نشانی ویدیو یا صوت را به اپلیکیشنهای روی گوشی که میتوانند آن را روی صفحه دیگر پخش کنند (اپلیکیشن Chromecast، اپلیکیشن Smart TV، پخشکننده ویدیو) از طریق انتخابگر «Cast to...» اندروید پیشنهاد میکند.
مقدار برگشتی: هیچ، و بدون callback. نیازمندی: چیزی برای روشن کردن نیست. گوشی به اپلیکیشنی نیاز دارد که پیوند را بپذیرد.
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);
});یک قسمت پادکست را از یک فهرست به یک بلندگو یا اپلیکیشن تلویزیون بفرستید (پیوند .mp3 به اپلیکیشنهای صوتی پیشنهاد میشود):
// <li><button class="cast" data-src="https://example.com/ep12.mp3">Cast</button> Episode 12</li>
document.getElementById('episodes').addEventListener('click', function (e) {
var btn = e.target.closest('button.cast');
if (!btn) return;
var src = btn.getAttribute('data-src') || '';
if (src.indexOf('https://') !== 0) {
alert('This episode cannot be cast'); // files inside the app cannot be handed over
return;
}
if (window.WebToApk && typeof window.WebToApk.castMedia === 'function') {
window.WebToApk.castMedia(src);
}
});دکمهٔ Cast را فقط داخل اپلیکیشن نشان دهید و پیش از واگذاری یک پخش زنده، پخشکنندهٔ خود صفحه را مکث کنید:
var castBtn = document.getElementById('cast-live');
var canCast = !!(window.WebToApk && typeof window.WebToApk.castMedia === 'function');
castBtn.hidden = !canCast;
castBtn.addEventListener('click', function () {
var video = document.getElementById('live');
video.pause(); // avoid playing twice, here and on the TV
window.WebToApk.castMedia('https://example.com/live/stream.m3u8'); // offered to video apps
});نکتهها:
- این یک واگذاری است، نه یک نشست cast: پس از انتخاب اپلیکیشن توسط کاربر، صفحهٔ شما پخش را کنترل نمیکند.
- نشانی باید یک پیوند کامل
https://باشد که اپلیکیشنهای دیگر بتوانند باز کنند. فایلی داخل ZIP اپلیکیشن شما، یک URL از نوعblob:یا نشانی صفحه وب پخش نمیشود. - نوع از روی پیوند میآید: فایل صوتی (
.mp3،.m4a،.aac،.ogg،.opus،.wav،.flac…) یا URL از نوعaudio/data:به اپلیکیشنهای صوتی پیشنهاد میشود؛ هر چیز دیگر - فایلهای ویدیو، پخشهای.m3u8، پیوندهای بدون پسوند فایل - به اپلیکیشنهای ویدیو.
clearMediaNotification پل#
window.WebToApk.clearMediaNotification()
به محتوای وب اجازه میدهد اعلان سبک رسانهٔ Android را کنترل کند و callbackهای کنترل پخش (play/pause/next/prev) را از صفحهٔ قفل و پردهٔ اعلانها دریافت کند. استفاده از JavaScript: window.WebToApk.setMediaMetadata('Song Title', 'Artist Name', 'https://…/art.jpg') window.WebToApk.setPlaybackState(true, 30000, 240000) // در حال پخش، موقعیت به ms، مدت به ms window.WebToApk.clearMediaNotification() Callback از Android ← JS: window.WebToApkOnMediaAction('play'|'pause'|'next'|'prev'|'stop')
با گروه خودش، پل اعلان رسانه، توضیح داده شده است، نه بهتنهایی.
نمونه
اعلان رسانه و کنترلهای صفحه قفل آن را حذف میکند، مثلاً وقتی کاربر پخشکننده شما را میبندد.
خروجی: هیچ. نیازمندی: هنگام ساخت، اعلان رسانه را در مرحله ۴ (دسترسی) روشن کنید. بدون آن، فراخوانی کاری نمیکند.
فراخوانی استاندارد وب برای این وجود ندارد، پس از پل استفاده کنید:
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;
});
}یک تایمر خواب که پس از تعداد دقیقهٔ انتخابشده صدا را قطع میکند و اعلان را حذف میکند:
var sleepTimer = null;
function setSleepTimer(minutes) {
clearTimeout(sleepTimer);
sleepTimer = setTimeout(function () {
var audio = document.getElementById('player');
audio.pause();
if (window.WebToApk && typeof window.WebToApk.clearMediaNotification === 'function') {
window.WebToApk.clearMediaNotification();
}
}, minutes * 60 * 1000);
}
document.getElementById('sleep-30').addEventListener('click', function () { setSleepTimer(30); });وقتی آخرین آهنگ یک فهرست پخش تمام شد اعلان را حذف کنید، بهجای اینکه دکمه پخش بیفایده بماند:
var audio = document.getElementById('player');
var playlist = ['https://example.com/1.mp3', 'https://example.com/2.mp3'];
var current = 0;
audio.addEventListener('ended', function () {
current++;
if (current < playlist.length) {
audio.src = playlist[current];
audio.play();
} else if (window.WebToApk && typeof window.WebToApk.clearMediaNotification === 'function') {
window.WebToApk.clearMediaNotification();
}
});نکتهها: این را برای «توقف» استفاده کنید، نه برای «مکث» (برای مکث، setPlaybackState(false, ...) را بفرستید تا دکمهٔ پخش بماند). تنظیم navigator.mediaSession.metadata = null اعلان را حذف نمیکند. setMediaMetadata / setPlaybackState بعدی (یا فراداده / وضعیت جدید navigator.mediaSession) اعلان و کنترلهای صفحهٔ قفل را برمیگرداند.
setMediaMetadata پل#
window.WebToApk.setMediaMetadata(title: String, artist: String, artworkUrl: String)
به محتوای وب اجازه میدهد اعلان سبک رسانهٔ Android را کنترل کند و callbackهای کنترل پخش (play/pause/next/prev) را از صفحهٔ قفل و پردهٔ اعلانها دریافت کند. استفاده از JavaScript: window.WebToApk.setMediaMetadata('Song Title', 'Artist Name', 'https://…/art.jpg') window.WebToApk.setPlaybackState(true, 30000, 240000) // در حال پخش، موقعیت به ms، مدت به ms window.WebToApk.clearMediaNotification() Callback از Android ← JS: window.WebToApkOnMediaAction('play'|'pause'|'next'|'prev'|'stop')
با گروه خودش، پل اعلان رسانه، توضیح داده شده است، نه بهتنهایی.
نمونه
عنوان، هنرمند و تصویر جلد اعلان رسانه و پخشکنندهٔ صفحهٔ قفل را تنظیم میکند. صفحهها معمولاً navigator.mediaSession.metadata را تنظیم میکنند که این را برای شما صدا میزند.
خروجی: هیچ. نیازمندی: هنگام ساخت، اعلان رسانه را در مرحله ۴ (دسترسی) روشن کنید. بدون آن، فراخوانی کاری نمیکند.
روش عمومی (از این استفاده کنید):
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' }]
});
}فراخوانی خام. آرگومانها: title, artist, artworkUrl (برای بدون تصویر از '' استفاده کنید):
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(); });
}عنوان اعلان را برای یک پخش زنده رادیویی بهروز نگه دارید، جایی که آهنگ بدون بارگذاری فایل جدید عوض میشود:
var lastSong = '';
function refreshNowPlaying() {
fetch('https://example.com/radio/now-playing.json')
.then(function (r) { return r.json(); })
.then(function (np) { // e.g. { "title": "...", "artist": "...", "cover": "https://..." }
var key = np.title + '|' + np.artist;
if (key === lastSong) return; // only update when the song really changed
lastSong = key;
if (window.WebToApk && typeof window.WebToApk.setMediaMetadata === 'function') {
window.WebToApk.setMediaMetadata(np.title || 'Live radio', np.artist || '', np.cover || '');
}
})
.catch(function () { /* try again on the next tick */ });
}
document.getElementById('radio').addEventListener('play', function () {
refreshNowPlaying();
setInterval(refreshNowPlaying, 30000);
}, { once: true });نکتهها:
- اعلان با این فراخوانی ظاهر (یا بهروز) میشود. عنوان خالی نام اپلیکیشن را نشان میدهد.
artworkUrlباید یک نشانی کاملhttps://در اینترنت باشد. اپلیکیشن آن را دانلود میکند (محدودیت ۴ ثانیه)؛ اگر شکست خورد، آیکون اپلیکیشن نشان داده میشود.- فشار دکمهها را با
navigator.mediaSession.setActionHandlerدریافت کنید (navigator.mediaSessionرا ببینید)، یا باwindow.WebToApkOnMediaAction = function (action) { ... }خودتان (play،pause،next،prev،stop) - یکی از این دو را استفاده کنید. پس ازclearMediaNotification()، فراخوانی بعدی این (یاsetPlaybackState) اعلان و کنترلهای صفحه قفل را برمیگرداند.
setPlaybackState پل#
window.WebToApk.setPlaybackState(isPlaying: Boolean, positionMs: Long, durationMs: Long)
به محتوای وب اجازه میدهد اعلان سبک رسانهٔ Android را کنترل کند و callbackهای کنترل پخش (play/pause/next/prev) را از صفحهٔ قفل و پردهٔ اعلانها دریافت کند. استفاده از JavaScript: window.WebToApk.setMediaMetadata('Song Title', 'Artist Name', 'https://…/art.jpg') window.WebToApk.setPlaybackState(true, 30000, 240000) // در حال پخش، موقعیت به ms، مدت به ms window.WebToApk.clearMediaNotification() Callback از Android ← JS: window.WebToApkOnMediaAction('play'|'pause'|'next'|'prev'|'stop')
با گروه خودش، پل اعلان رسانه، توضیح داده شده است، نه بهتنهایی.
نمونه
به اعلان رسانه میگوید در حال پخش هستید یا متوقف، و کجای آهنگ هستید. صفحهها معمولاً navigator.mediaSession.playbackState را تنظیم و setPositionState را فراخوانی میکنند که این را برایتان فراخوانی میکنند.
خروجی: هیچ. نیازمندی: هنگام ساخت، اعلان رسانه را در مرحله ۴ (دسترسی) روشن کنید. بدون آن، فراخوانی کاری نمیکند.
روش عمومی (از این استفاده کنید):
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);فراخوانی خام. آرگومانها: isPlaying (true/false)، positionMs، durationMs (میلیثانیه صحیح):
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)
);
}پس از جستجوی کاربر موقعیت جدید را گزارش کنید و وقتی آهنگ تمام شد اعلان را به «پخش» برگردانید:
var audio = document.getElementById('player');
function report(playing) {
if (!(window.WebToApk && typeof window.WebToApk.setPlaybackState === 'function')) return;
var durMs = Math.floor((audio.duration || 0) * 1000);
var posMs = Math.floor(audio.currentTime * 1000);
window.WebToApk.setPlaybackState(playing, Math.min(posMs, durMs || posMs), durMs);
}
audio.addEventListener('seeked', function () { report(!audio.paused); });
audio.addEventListener('ended', function () { report(false); }); // Play button, notification can be swiped awayنکتهها: true دکمهٔ مکث را نشان میدهد و مانع کنار زدن اعلان میشود؛ false دکمهٔ پخش را نشان میدهد. ابتدا setMediaMetadata را صدا بزنید تا اعلان عنوان داشته باشد. برای حذف اعلان هنگام توقف کاربر، صدا بزنید clearMediaNotification().