
React NativeアプリでコラボLIVE配信ーアーキテクチャと使用ライブラリの概要
このnoteは、先月、stand.fm社が主催しているTECH STANDイベントにて「React NativeアプリでコラボLIVE配信」というテーマで登壇した内容をまとめたものです。
自己紹介
こんばんは、瀬戸口です。2018年からstand.fmの開発をしています。
もともとバックエンドよりで、アプリ開発の入り口がReact Nativeなので、React Nativeには毎日感謝しながら暮らしています。
どうぞよろしくお願いします。
今日話すこと
今⽇はstand.fmのコラボLIVE配信機能の話をします。
React Nativeに関係する範囲で、ライブラリやアーキテクチャの話を共有できればと思います。
コラボLIVE配信:機能概要
コラボLIVE配信機能は、配信者と複数人のゲストがリアルタイムに通話して、その会話がコンテンツとして多数のリスナーにLIVE配信されるという機能です。
一人の語りで面白い音声コンテンツを作るのは難しいけど、対話からは楽しみながら面白いコンテンツが生まれやすいのではないか、という思いでコラボ機能を作りました。
アーキテクチャ概観(コラボLIVE配信)
コラボLIVE配信のアーキテクチャの概観です。
配信者とゲストがWebRTCで会話した内容を配信者のアプリからLIVEサーバに送信して、LIVEサーバからHLSでリスナーに配信されるという流れになってます。
LIVEサーバ
LIVEサーバはWowza Streaming Engineという製品を使用しています。
HLS:HTTP Live Streaming
このLIVEサーバが、HLS配信を行います。
LIVEの音声ストリームを1秒ごとの音声ファイルに分割し、そのリストをplaylist.m3u8というファイル名で公開します。
playlistの内容は毎秒更新されるので、クライアントはこれを繰り返し取得することでLIVEをほぼリアルタイムに視聴することができます。
LIVEサーバ → CDN → リスナー
HLSの再生にはreact-native-track-playerというライブラリを使用しています。
このライブラリはLIVEを視聴している最中に他のアプリを開いてstand.fmがバックグラウンドになっても、バックグラウンド再⽣で継続して視聴できたりして、すごくよかったです。
配信者→LIVEサーバ(一人LIVE配信オンリーのとき)
つぎは配信者側の話です。
まずコラボライブ機能ができる前、一人LIVE配信のみ可能だった時は、Wowzaが配布しているiOS・Android用のSDKで音声の録音からライブサーバへの送信までできたため、これを改造してReact Nativeから使用する用のインターフェースを追加して、native moduleとして使用していました。
アーキテクチャ概観(一人LIVE配信オンリーのとき)
一人LIVE配信しかできないときのアーキテクチャはこんな感じでした。
一人LIVE配信とコラボLIVE配信の差分
この一人ライブ配信に機能追加してコラボライブ配信できるようにするために、音声周りで必要だったのは、通話機能の追加と、通話内容をライブサーバに送信する機能の二点でした。
通話の部分はWebRTCを使用しました。
WebRTC
WebRTCはウェブブラウザ間のP2P通信でビデオチャットができる技術で、stand.fmは映像は無いので音声部分だけ使用しています。
WebRTCの遅延時間は端末間の距離に依存しますが、およそ0.1秒程度のタイムラグと非常に小さく、声同士のコミュニケーションに適してます。
ちなみにHLSは遅延10秒程度なので、配信者の声がリスナーに届くまで10秒のタイムラグがあります。
アーキテクチャ概観(コラボ収録)
WebRTCを使用した通話は、コラボLIVE機能ができる前からstand.fmに存在してました。
コラボライブではなくコラボ収録という機能で、複数人で通話してその内容を1つの音声ファイルに録音して、それをサーバにアップロードして公開するという機能です。
これは配信者とゲスト全員の音声が配信者のアプリ内に集約されるため、配信者のアプリ内の操作で収録途中に切り取りや挿入などの編集ができます。
アーキテクチャ概観(コラボLIVE配信)
コラボLIVE機能を作るにあたっては、コラボ収録機能の通話部分を再利用しつつ、配信者のアプリがLIVEサーバに音声ストリームを送信できるよう機能を追加しました。
LIVEサーバへの送信はいままではWowzaのSDKを利用していたのですが、WowzaのSDKで録音したのではない音声ストリームをサーバに送信するために、RTMPで送信する方式に変更しました。
全体としては、少人数しか参加できないけど低遅延なWebRTCで会話をして、タイムラグ大きいけど大人数に配信できるHLSでリスナーに声を届けるという使い分けになっています。
コラボLIVE配信: 配信者のアプリの音声まわりの構成
これが配信者のアプリの音声周りの構成です。
まず通話のところはreact-native-webrtcというライブラリを使用しています。
ただし通話内容をストリームとして取得するために改造する必要があったため、WebRTCライブラリの本体とreact-native-webrtcをforkして使用しています。
音声ストリームをLIVEサーバに送信するところは、iOS用のHaishinKitというライブラリでRTMP送信ができて、これを自作のnpmパッケージでReact Native用にラップして使用しています。
まとめ: React Nativeまわりで、できたこと・やったこと
まとめです。
React Nativeアプリでコラボライブ配信機能を作った話をしました。
HLSを視聴したり、WebRTCで通話したりするところは既存のライブラリで実現可能でした。
これに対してWebRTCの通話音声を取得したり、ライブサーバに送信したりするところは、ライブラリを改造したり自作したりする必要がありました。
このあたり実はiOS版でしか完成してなくて、Android版ではまだコラボ収録とコラボライブができない状況なので、早く完成させたいと思っています。
各種OSSライブラリのリンク
このスライドは、コラボライブ機能の⾳声周りでお世話になっているOSSライブラリのリファレンスです。
ありがとうございます。
宣伝
最後に会社の宣伝なんですが、いまstandfmではエンジニアを熱狂的に募集しているので、よかったら採⽤ページをご覧ください。
技術イベントも定期開催しています。ぜひご参加ください。
発表は以上です、ありがとうございました。