mcpField
R
react-native-moq

react-native-moq

github.com/software-mansion-labs開発296414 回インストール2 週間前に更新
リポジトリ

react-native-moq について

react-native-moq は moq-kit を基盤とする React Native 向け MoQ バインディングです。モバイルアプリで MoQ リレーに接続し、フックまたは命令型 API から映像・音声・データのトラックを送受信できます。

主な機能

  1. 01MoQ リレーへの接続とブロードキャスト検索
  2. 02映像・音声ブロードキャストの再生
  3. 03カメラとマイクからのメディア配信
  4. 04データトラックの送受信
  5. 05フックと命令型 API

活用シーン

  1. 01React Native アプリでライブ配信を視聴
  2. 02端末のカメラとマイクからメディアを配信
  3. 03クライアント間でデータメッセージを交換

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/software-mansion-labs/skills --skill react-native-moq

インストール後、Claude Code で/react-native-moqを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

references/
custom-tracks.md
imperative.md
playback.md
publishing.md

詳細

react-native-moq

Media over QUIC(MoQ)の React Native バインディングです。サブ秒の低遅延でライブ動画、音声、データのトラックを MoQ リレーに配信し、リレーから受信できます。Software Mansion の moq-kit ネイティブライブラリを基盤としています。

要件: React Native New Architecture(Fabric + TurboModules)、iOS 16 以降、Android API 30 以降。

npm install react-native-moq
cd ios && pod install

オプションのプレーヤー UI(全画面モーダル、コントロール、音量スライダー):

npm install react-native-moq-ui @react-native-vector-icons/material-icons

iOS では、Info.plist の UIAppFonts に MaterialIcons.ttf も追加し、再度 pod install を実行する必要があります。<VideoView> 上に独自のプレーヤー UI を構成する場合は、このパッケージを省略してください。

基本的な考え方

  • Session は MoQ リレーへの 1 つの接続です(useSession(url))。自動接続はしないため、自分で session.connect() を呼び出してください。1 つのセッションで購読と配信の両方を行えます。
  • 購読: useBroadcasts(session, prefix) でパスプレフィックス配下のライブブロードキャストを一覧表示し、BroadcastInfo を選択して、useVideoPlayer / useAudioPlayer を使い、<VideoView player={player}> でレンダリングします。生メディアを扱う方法として、useAudioChunks(エンコード済みまたは PCM を JS に渡す)や useDataMessages(文字列ペイロード)もあります。
  • 配信: キャプチャフックでトラックを生成する(useCamera、useMicrophone、useMultiCamera)か、自分で生成し(useDataTrack、useAudioSource、useVideoSource)、usePublisher(session).publish({ path, tracks }) を呼び出します。画面共有(useScreenBroadcast)は別プロセスで動作します。
  • すべてのフックには、フックを使わない代替手段があります。状態を持つものにはオブジェクトと destroy() を返す create*、購読フックには start() / stop() を返す subscribe* があります。references/imperative.md を参照してください。
  • オブジェクトはリアクティブな状態(session.state、publisher.state、player.isPlaying など)を公開し、変更時にフックが再レンダリングされます。addListener または useEvent / useEventListener ヘルパーを使って手動で購読することもできます。

クイックスタート — 視聴

function Watch() {
  const session = useSession('https://relay.example.com', (s) => s.connect());
  const broadcasts = useBroadcasts(session, ''); // '' = all paths
  return broadcasts.map((b) => <BroadcastPlayer key={b.path} broadcast={b} />);
}

function BroadcastPlayer({ broadcast }: { broadcast: BroadcastInfo }) {
  const player = useVideoPlayer(broadcast, (p) => p.play());
  return <VideoView player={player} style={{ width: '100%', aspectRatio: 16 / 9 }} />;
}

useVideoPlayer / useAudioPlayer は null ではないブロードキャストを必要とするため、ブロードキャストが存在する場合にのみレンダリングされる子コンポーネント内でマウントしてください。

クイックスタート — ライブ配信

const session = useSession(url, (s) => s.connect());
const camera = useCamera();
const microphone = useMicrophone();
const publisher = usePublisher(session);

<PublisherView camera={camera} style={styles.preview} />
// when session.state === 'connected':
publisher.publish({ path: 'live/test', tracks: [camera, microphone] });

重要なルール

  1. エラーは例外ではなく文字列です。 状態は 'connected' | 'error:...' のようなユニオンです。state.startsWith('error:') で確認してください。メディアの失敗時に例外がスローされることはありません。セッションではメッセージは状態文字列にのみ含まれます(state.slice(6))。キャプチャトラックとパブリッシャーには、さらに lastError フィールドがあります。プレーヤーにはエラーを確認する手段がないため、セッションとパブリッシャーの状態を確認してください。
  2. publish() を呼び出すには session.state === 'connected' が必要です。 そうでない場合、パブリッシャーはただちに error:session is not connected になります。セッションの状態に応じてライブ配信ボタンを有効にしてください。
  3. getSupportedVideoCodecs() / getSupportedAudioCodecs() でコーデックを確認してください。 Android では、サポートされていないエンコーダー(多くの場合 h265)を使うと、エラーなしで配信が開始されたあと、ひそかに停止します。デフォルトでは h264 / opus を使用してください。
  4. 権限の設定はホストアプリ側で行います。 Android では CAMERA / RECORD_AUDIO をリクエストし、iOS では NSCameraUsageDescription / NSMicrophoneUsageDescription を追加してください。プレビューが黒い場合、通常は権限が不足しています。
  5. <VideoView> は子要素を受け取りません(Android のネイティブビューは ViewGroup ではありません)。オーバーレイは絶対位置指定した兄弟要素としてレンダリングしてください。
  6. キャプチャフックは参照カウントされるデバイスシングルトンです。 すべてのコンシューマーが同じ物理カメラ/マイクを共有し、flip() はすべてのコンシューマーに影響します。フックを条件付きで呼び出すのではなく、マウントしたままハードウェアをオフにするには enabled: false を使用してください。
  7. ブロードキャストのパスは購読プレフィックスからの相対パスです。 (ブロードキャスト live/test は、プレフィックス 'live' の下では path: 'test' として表示されます。)完全なパスを確認するには '' を購読してください。一覧に表示されたブロードキャストを再生できず、リレーエラー code=13 NotFound が発生する場合、パスとプレフィックスが一致していません。
  8. データトラックはカタログに含まれません。 パブリッシャーとサブスクライバーは、別途トラック名について合意する必要があります(デフォルトは 'data')。
  9. アイドル状態の iOS マイクキャプチャは、オーディオセッションを playAndRecord に保持するため、他のオーディオライブラリを妨げることがあります(insufficientPriority)。配信していないときは、マイクを無効にしてください(enabled: false)。

リファレンス

タスク参照
セッション、ブロードキャストの検出、動画/音声の再生、<VideoView>、統計情報、トラックの切り替え、イベント、react-native-moq-uireferences/playback.md
カメラ、マルチカメラ、マイク、パブリッシャーのライフサイクル、画面のブロードキャスト、コーデックのクエリreferences/publishing.md
データトラックとメッセージ、JS への音声チャンク、自前の音声(PCM)と動画(フレームバッファー)の送信references/custom-tracks.md
React を使用しない方法:create* ハンドル、subscribe* 関数、クリーンアップreferences/imperative.md

コメント