使用媒体会话 Web API 的媒体通知不适用于 Web 音频 API

Tob*_*rth 4 javascript android google-chrome android-notifications progressive-web-apps

我正在尝试在我的 PWA 中针对当前播放的音频内容实现自定义通知。

正如标题所述;我使用 Android v8.1.0 和 Google Chrome 应用程序 v68.0.x。根据这篇文章:The Media Session API is supported in Chrome 57. 我认为我使用的版本应该是最新的才能处理这些通知。

首先,截取我播放的音频内容的代码:

let context = getContext();
await context.resume().catch(console.error);
let source = context.createBufferSource();
source.connect(context.destination);
source.start(0);
Run Code Online (Sandbox Code Playgroud)

音频内容的播放工作正常,没有问题。我尝试在调用更新媒体会话 API 的元数据source.start(..),如下所示:

let updateMediaSession = (payload) => {
  if (!('mediaSession' in navigator)) {
    return;
  }

  navigator.mediaSession.metadata = new MediaMetadata({
    title: payload.title,
    artist: payload.artist,
    album: payload.album,
    artwork: [
      {
        src: '/static/logos/android-chrome-36x36.png',
        sizes: '36x36',
        type: 'image/png',
      },
      {
        src: '/static/logos/android-chrome-48x48.png',
        sizes: '48x48',
        type: 'image/png',
      },
      {
        src: '/static/logos/android-chrome-72x72.png',
        sizes: '72x72',
        type: 'image/png',
      },
      {
        src: '/static/logos/android-chrome-96x96.png',
        sizes: '96x96',
        type: 'image/png',
      },
      {
        src: '/static/logos/android-chrome-144x144.png',
        sizes: '144x144',
        type: 'image/png',
      },
      {
        src: '/static/logos/android-chrome-192x192.png',
        sizes: '192x192',
        type: 'image/png',
      },
      {
        src: '/static/logos/android-chrome-256x256.png',
        sizes: '256x256',
        type: 'image/png',
      },
      {
        src: '/static/logos/android-chrome-384x384.png',
        sizes: '384x384',
        type: 'image/png',
      },
      {
        src: '/static/logos/android-chrome-512x512.png',
        sizes: '512x512',
        type: 'image/png',
      },],
  });

  navigator.mediaSession.setActionHandler('play', () => ...);
  navigator.mediaSession.setActionHandler('pause', () => ...);
  navigator.mediaSession.setActionHandler('seekbackward', () => ...);
  navigator.mediaSession.setActionHandler('seekforward', () => ...);
  navigator.mediaSession.setActionHandler('previoustrack',() => ...);
  navigator.mediaSession.setActionHandler('nexttrack', () => ...);
};
Run Code Online (Sandbox Code Playgroud)

我像这样更新播放状态:

  if ('mediaSession' in navigator) {
    navigator.mediaSession.playbackState = 'paused';
  }
Run Code Online (Sandbox Code Playgroud)

  if ('mediaSession' in navigator) {
    navigator.mediaSession.playbackState = 'playing';
  }
Run Code Online (Sandbox Code Playgroud)

问题 通知没有显示在我的智能手机上。

我已将源代码部署到具有域的正确服务器上。在进行测试之前,我在智能手机上导航到该网站,清除了所有数据,卸载了任何潜在的 PWA 并刷新了页面。

似乎一切都按预期执行,但没有显示任何内容。我期待这样的事情。

有谁知道为什么这不起作用? 在此输入图像描述

Jed*_*ell 7

这里有两个问题。第一个是一个非常简单的修复。

updateNotification正在阻止updateMediaSession运行,否则会导致双重通知。您可以通过简单地使用updateNotification条件检查来解决此问题if(!('mediaSession' in navigation))。因此,如果设备支持mediaSession,请使用mediaSession,否则(它是计算机)创建通知。

其次(也是最重要的),使用mediaSession需要一个audio(或video) 元素来播放通知才能显示。看来你没有使用它。

您可以更改为audio在后台使用该元素,然后重新设计控件以在交互时进行修改,或者您可以通过在不可见元素中播放无声音频剪辑audio并立即暂停它来解决这个问题(如果播放,通知将消失)通过)。我建议使用audio.

如果您决定使用解决方法,我发现这个存储库包含不同长度的无声音频剪辑。我能开始工作的最短时间是 5 秒,再短就不会向我显示通知。