播放服务人员的声音 [英] Play a sound from a Service Worker
问题描述
是否可以播放来自服务人员的音频文件?
Is there a way to play an audio file from a service worker?
我正在尝试使用 io.sound 库,但这是一个需要 window 的JavaScript插件,所以它不起作用.
I'm trying to use io.sound library but it is a JavaScript plugin that requires window, so it doesn't work.
编辑
根据Jeff的建议,我正在尝试打开一个新窗口并将消息发布到该窗口.这是我的代码:
As suggested by Jeff I'm trying to open a new window and post a message to that window. this is my code:
function notifyClientToPlaySound() {
idbKeyval.get('pageToOpenOnNotification')
.then(url => {
console.log("notifyClientToPlaySound", url);
clients.matchAll({
type: "window"
//includeUncontrolled: true
})
.then((windowClients) => {
console.log("notifyClientToPlaySound - windowClients", windowClients);
for (var i = 0; i < windowClients.length; i++) {
var client = windowClients[i];
if (client.url === url && "focus" in client) {
notify({ event: "push" });
return client.focus();
}
}
//https://developer.mozilla.org/en-US/docs/Web/API/Clients/openWindow
if (clients.openWindow) {
return clients.openWindow("/")
.then(() => {
notify({ event: "push" });
});
}
})
});
}
现在从 self.addEventListener("push",(event)=> {...}
self.addEventListener("push", (event) => {
console.log("[serviceWorker] Push message received", event);
event.waitUntil(
idbKeyval.get('fetchNotificationDataUrl')
.then(url => {
console.log("[serviceWorker] Fetching notification data from -> " + url);
return fetch(url, {
credentials: "include"
});
})
.then(response => {
if (response.status !== 200) {
// Either show a message to the user explaining the error
// or enter a generic message and handle the
// onnotificationclick event to direct the user to a web page
console.log("[serviceWorker] Looks like there was a problem. Status Code: " + response.status);
throw new Error();
}
// Examine the text in the response
return response.json();
})
.then(data => {
if (!data) {
console.error("[serviceWorker] The API returned no data. Showing default notification", data);
//throw new Error();
showDefaultNotification({ url: "/" });
}
notifyClientToPlaySound(); <------ HERE
var title = data.Title;
var message = data.Message;
var icon = data.Icon;
var tag = data.Tag;
var url = data.Url;
return self.registration.showNotification(title, {
body: message,
icon: icon,
tag: tag,
data: {
url: url
},
requireInteraction: true
});
})
.catch(error => {
console.error("[serviceWorker] Unable to retrieve data", error);
var title = "An error occurred";
var message = "We were unable to get the information for this push message";
var icon = "/favicon.ico";
var tag = "notification-error";
return self.registration.showNotification(title, {
body: message,
icon: icon,
tag: tag,
data: {
url: "/"
},
requireInteraction: true
});
})
);
});
但是,当调用 clients.openWindow 时,它将返回以下异常:
But when clients.openWindow is called, it returns the following exception:
未捕获(承诺)的DOMException:不允许打开窗口.
Uncaught (in promise) DOMException: Not allowed to open a window.
我该如何解决?
推荐答案
Web Notifications API的现行规范确实引用了
The living specification for the Web Notifications API does reference a sound
property that could be specified when showing a notification, and would theoretically allow you to play the sound of your choosing when showing a notification from a service worker.
However, while the specification references this property, as of the time of this writing, it's not supported in any browsers.
更新(19年8月):似乎已从
Update (Aug. '19): It looks like reference to sound
has been removed from https://notifications.spec.whatwg.org/#alerting-the-user
最好的选择是发布消息一个由当前服务人员控制的打开的窗口,并让该窗口播放声音以响应 message
事件.
Your best bet would be post a message along to an open window that's controlled by the current service worker, and have the window play the sound in response to the message
event.
如果没有可用的受控客户端(例如,由于您的服务人员已被 push
事件唤醒,并且您的站点当前未在浏览器中打开),则可以选择在您的内打开新窗口
notificationclick 处理程序,响应于用户单击您在 push
事件处理程序中显示的通知而触发.然后,您可以在该新窗口中发布一条消息.
If there is no controlled client available (e.g. because your service worker has been awoken by a push
event, and your site isn't currently open in a browser) then you'd have the option of opening a new window inside your notificationclick
handler, which is triggered in response to a user clicking on the notification you display in your push
event handler. You can then post a message to that new window.
这篇关于播放服务人员的声音的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!