$ cat post.metadata

React Nativeで実現するPiP × バックグラウンド再生の並列設計

React NativeMobile

React Nativeアプリで Picture-in-Picture(PiP)とバックグラウンド音声再生をフォールバックモデルで共存させる設計パターン。状態遷移、Now Playing情報の受け渡し、AudioSessionの整合性、PWA制約への対応まで解説。

$ cat post.content | render --format=markdown

React Nativeで実現するPiP × バックグラウンド再生の並列設計

動画配信サービスを開発していると、ユーザーから「動画を見ながら別のアプリを使いたい」「歩きながら講義を聞きたい」といった要望が必ず出てきます。

これらを実現するのが Picture-in-Picture(PiP)バックグラウンド音声再生 ですが、React Nativeで両方を同時にサポートしようとすると、意外なほど設計上の落とし穴があります。

本記事では、React Nativeアプリで PiP とバックグラウンド音声再生を フォールバックモデル で共存させる設計パターンを紹介します。

対象読者

  • React Nativeで動画プレイヤーを実装している開発者
  • PiPやバックグラウンド再生の設計で悩んでいる方
  • iOS / Web / PWA のクロスプラットフォーム対応を検討している方

プラットフォーム別の対応状況

まず現実を整理します。「PiP」と「バックグラウンド再生」は似て非なるもので、プラットフォームごとに対応状況が異なります。

機能Mobile (React Native)Web (Safari)Web (PWA)
バックグラウンド音声再生react-native-video + react-native-track-player で実現可能非対応非対応
PiPreact-native-videopictureInPicture prop で制御可能ブラウザネイティブで動作iOS制約により不可
ロック画面 / Control Center 操作react-native-track-player 経由で対応

ポイントは PWA(Webクリップ)ではPiPもバックグラウンド再生も不可 という点です。これはiOSプラットフォーム側の制約であり、アプリケーション側で回避する手段がありません。

なぜ expo-video ではなく react-native-video を使うのか

Expo SDK 51 以降で提供されている expo-video は、Expoエコシステムとの統合が優れており、シンプルなユースケースでは導入しやすいライブラリです。しかし、本記事で扱うようなバックグラウンド再生のシナリオでは 動画の連続再生(プレイリスト再生)をサポートしていない という制約があります。

教育系・講座系のアプリでは「レッスン1が終わったら自動でレッスン2に進む」というプレイリスト的な連続再生が求められます。フォアグラウンドだけでなく、バックグラウンド再生中にも次の動画へシームレスに遷移する必要がありますが、expo-video は現時点でこのユースケースをカバーしていません。

一方、react-native-video + react-native-track-player の組み合わせであれば、TrackPlayer のキュー管理機能を活用してバックグラウンドでの連続再生を実現できます。

ライブラリPiPバックグラウンド再生バックグラウンド連続再生Control Center
expo-video対応対応非対応限定的
react-native-video + track-player対応対応対応対応

この「バックグラウンドでの連続再生」要件が、react-native-video を選択した決定的な理由です。

設計方針 PiP優先・音声フォールバックモデル

検討の結果たどり着いたのが「PiPが使える場面ではPiPを優先し、PiPが終了/非対応の場合はバックグラウンド音声にフォールバックする」というモデルです。

このモデルの良いところは、ユーザーの意図に応じて最適な再生モードが自動選択される 点です。映像が必要な場面ではPiPが、音声だけで十分な場面ではバックグラウンド再生が使われます。

Mobile(React Native)の状態遷移設計

React Nativeでの実装が最も複雑です。核心は 動画プレイヤーとオーディオプレイヤーの制御権の受け渡し にあります。

実装上の重要ポイント

1. react-native-video の PiP 有効化

まず pictureInPicture を有効にします。

tsx
<Video source={{ uri: videoUrl }} pictureInPicture={true} // PiPを有効化 playInBackground={true} // バックグラウンド再生も有効 onPictureInPictureStatusChanged={({ isActive }) => { setPipActive(isActive); if (!isActive) { // PiP終了 → バックグラウンド音声再生に移行 handoffToAudioPlayer(); } }} />

2. Now Playing 情報の受け渡し

PiPとバックグラウンド音声では、ロック画面 / Control Center に表示する Now Playing 情報の管理者 が異なります。ここが最大の難所です。

3. AudioSession の整合性

iOS の AudioSession カテゴリは状態遷移に合わせて適切に管理する必要があります。

状態AudioSession カテゴリmixWithOthers
フォアグラウンド再生.playbackなし
PiP 再生.playbackなし(維持)
バックグラウンド音声.playbackなし(維持)

mixWithOthers を設定すると他のアプリの音声と混ざってしまうため、動画コンテンツでは基本的に使用しません。

ユーザー体験マッピング

設計が正しいかどうかは、具体的なユースケースで検証します。

シナリオ最適な再生モード理由
レッスン動画を見ながらメモを取るPiP映像を見ながら別アプリを操作したい
講義を聞きながら移動バックグラウンド音声画面ロックして省電力
視聴中に電話がかかってきたPiP → 通話後に復帰iOS標準挙動に準拠
PiP非対応デバイスバックグラウンド音声フォールバックで現行動作を維持

Web での対応

Safari

ブラウザネイティブの PiP API が動作するため、動画プレイヤー(Mux Player 等)が標準対応していれば追加実装は不要です。ユーザーの発見しやすさを向上させたい場合は、プレイヤーUIに明示的なPiPボタンを追加するとよいでしょう。

PWA(Webクリップ)

iOSの制約により、PWA環境では PiPもバックグラウンド再生も不可 です。これはアプリ側では解決できないため、以下の対応が現実的です。

  • ユーザーへの案内 「バックグラウンド再生はSafariまたはネイティブアプリをご利用ください」
  • 可能であれば、ネイティブアプリへの誘導導線を設置

実装の優先順位

すべてを一度に実装するのではなく、段階的に進めることを推奨します。

優先度対応内容工数インパクト
Phase 1PWA制約をユーザーに案内即日問い合わせを即座に解決
Phase 2Mobile PiP + 遷移ハンドリング中〜大ネイティブアプリのUX大幅向上
Phase 3Web PiPボタンの明示追加Safariでの発見性向上

Phase 1 で即座にユーザーの困りごとを解決し、Phase 2 は十分な検証期間を設けて進めるのが現実的です。特に Phase 2 では、既存のオーディオ再生まわりのロジックとの相互作用が複雑になるため、段階的なテストが重要です。

まとめ

PiP × バックグラウンド再生の並列設計で押さえるべきポイントは3つです。

  1. フォールバックモデル PiP → バックグラウンド音声、という優先順位で自動遷移する
  2. 制御権の受け渡し 動画プレイヤーと音声プレイヤー間の Now Playing 情報・AudioSession の引き継ぎを確実に行う
  3. プラットフォーム制約の受容 PWAの制約は回避不可能。ユーザーへの適切な案内で対応する

React Nativeで動画配信アプリを開発している方の参考になれば幸いです。

$ echo $TAGS
#React Native#PiP#Picture-in-Picture#バックグラウンド再生#iOS#react-native-video#動画プレイヤー