当 mp3 被 Workbox 缓存时,无法 scrub/scroll 通过 jPlayer 音频

Cannot scrub/scroll through jPlayer audio when mp3 is cached by Workbox

我已经将单个页面 HTML5 Cordova 应用程序转换为 PWA。该应用程序广泛使用 jPlayer 来播放 mp3 文件。我在这里使用的是圆形 jPlayer 的变体:http://jplayer.org/latest/demo-05/。圆形播放器有一个圆形进度条,也可以用来在轨道上来回滑动。

在我使用 Workbox(版本 4.3.1)缓存 mp3 之前,在 PWA 模式下一切正常。然后擦洗失败。我可以抓住擦洗条并移动它,但当我松开它时,轨道会从头开始重新开始。如果我对 mp3 使用预缓存或对所有 mp3 文件使用专用音频缓存,就会发生这种情况。关闭缓存,更新 service worker 并刷新——这样我就可以擦洗了。打开缓存并刷新和清理失败。

我真的很想通过清理来处理缓存的音频文件,以便该应用程序可以离线工作。

这在本质上似乎与 Make mp3 seekable PHP 相似。

我是从 Workbox 文档的 recipe for serving cached audio and video.

中摘录的

某些浏览器请求媒体资产(例如 <video><audio> 元素的 src 的方式存在一些问题,除非您配置 Workbox 时采取特定步骤。

GitHub issue discussion 中提供了完整的详细信息;重点总结如下:

  • 必须告知 Workbox 尊重 Range request headers by adding in the workbox-range-requests plugin 用作处理程序的策略。

  • 音频或视频元素需要使用 crossOrigin attribute 选择加入 CORS 模式,例如通过 .

  • 如果你想从缓存中提供媒体,你应该提前明确地将它添加到缓存中。这可以通过预缓存或直接调用 cache.add() 来实现。使用运行时缓存策略将媒体文件隐式添加到缓存中不太可能奏效,因为在运行时,只有部分内容通过 Range 请求从网络中获取。

综上所述,这是使用 Workbox 提供缓存媒体内容的一种方法示例:

<!-- In your page: -->
<!-- You currently need to set crossOrigin even for same-origin URLs! -->
<video src="movie.mp4" crossOrigin="anonymous"></video>
// In your service worker:
// It's up to you to either precache or explicitly call cache.add('movie.mp4')
// to populate the cache.
//
// This route will go against the network if there isn't a cache match,
// but it won't populate the cache at runtime.
// If there is a cache match, then it will properly serve partial responses.
workbox.routing.registerRoute(
  /.*\.mp4/,
  new workbox.strategies.CacheFirst({
    cacheName: 'your-cache-name-here',
    plugins: [
      new workbox.cacheableResponse.Plugin({statuses: [200]}),
      new workbox.rangeRequests.Plugin(),
    ],
  }),
);

如果您计划预缓存媒体文件,那么您需要采取额外步骤来显式路由内容,以便从预缓存中读取它们,因为标准预缓存响应处理程序不会使用范围请求插件:

workbox.routing.registerRoute(
  /.*\.mp4/,
  new workbox.strategies.CacheOnly({
    cacheName: workbox.core.cacheNames.precache,
    plugins: [
      new workbox.rangeRequests.Plugin(),
    ],
    // This is needed since precached resources may
    // have a ?_WB_REVISION=... URL param.
    matchOptions: {
      ignoreSearch: true,
    }
  }),
);

// List this *after* the preceding runtime caching route.
workbox.precaching.precacheAndRoute([...]);