播放服务工作者的声音

时间:2017-02-16 08:33:11

标签: javascript audio service-worker

有没有办法从服务工作者播放音频文件?

我正在尝试使用 io.sound 库,但它是一个需要 window 的JavaScript插件,所以它不起作用。

修改

正如Jeff所建议的,我正在尝试打开一个新窗口并向该窗口发布消息。这是我的代码:

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中的 event.waitUntil(..)调用此函数(“push”,(event)=&gt; {...}

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 时,它会返回以下异常:

  

Uncaught(在promise中)DOMException:不允许打开窗口。

我该如何解决这个问题?

1 个答案:

答案 0 :(得分:2)

Web Notifications API的实时规范确实引用了在显示通知时可以指定的sound property,理论上允许您在显示服务工作者的通知时播放您选择的声音。< / p>

但是,虽然规范引用了此属性,截至撰写本文时,it's not supported in any browsers

您最好的选择是post a message一个由当前服务工作人员控制的打开窗口,并让窗口播放声音以响应message事件。

如果没有可用的受控客户端(例如,因为您的服务工作人员被push事件唤醒,并且您的网站目前尚未在浏览器中打开)那么您就拥有了notificationclick处理程序中opening a new window的选项,该响应是在用户点击您在push事件处理程序中显示的通知时触发的。然后,您可以将消息发布到该新窗口。