播放服务人员的声音 [英] Play a sound from a Service Worker

查看:71
本文介绍了播放服务人员的声音的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否可以播放来自服务人员的音频文件?

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月):似乎已从声音的引用-the-user_"rel =" nofollow noreferrer> https://notifications.spec.whatwg.org/#alerting-the-user

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆