1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Cloudflare Pages で iOS Safari から mp4 が再生できない

Last updated at Posted at 2022-01-09

TL;DR

iOS Safari は mp4 などのメディアコンテンツを HTTP 範囲リクエスト(206 Partial Content) で受け取らないと再生してくれませんが
Cloudflare Pages は HTTP 範囲リクエスト に対応してないため 200 OK で返してきます(response header に Accept-Ranges があり、値が none 以外であれば、そのサーバーは HTTP 範囲リクエストに対応してることになります)。
その response を Service Worker でインターセプトして206に書き換えて解決します。

Nuxt × Workbox の場合

当方は普段 Nuxt × Workbox を利用しているためその場合の利用法になります(それ以外の環境の方は参考程度に御覧ください)

nuxt.config.js
export default {
  ...
  workbox: {
    cachingExtensions: '~/plugins/workbox-range-request.js',
  },
}
/plugins/workbox-range-request.js
// メディアファイルのrangeRequest対応

const myPlugin = {
  async fetchDidSucceed({ request, response }) {
    if (response && response.status !== 206 && request.headers.has('range')) {
      response = await workbox.rangeRequests.createPartialResponse(request, response)
    }
    return response
  },
}

workbox.routing.registerRoute(
  /\.(mp3|ogg|mp4|webm)/,
  new workbox.strategies.CacheFirst({
    cacheName: 'media-file-cache',
    plugins: [
      new workbox.rangeRequests.RangeRequestsPlugin(),
      myPlugin,
    ],
  }),
  'GET'
)

本来 Cloudflare に限らず、 Service Worker を利用したサイトの動画を iOS で再生する際は
range request に対応する必要がありますが、
workbox の RangeRequestsPlugin では キャッシュされたレスポンス のみのコントロールになってしまいます。
今回の Cloudflare の場合は キャッシュされる前のオリジンレスポンス のコントロールも必要になりますので、
(workboxの場合は) fetchDidSucceed のタイミングで最適化するコードを入れました。

Service Worker 以外の解決法

確認してませんが、Cloudflare Workers を利用して
上記の createPartialResponse 関数内と同様の処理を施せば対応可能かと思います。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?