React Native WebRTC Kit 1.0.0 リリース

React Native WebRTC Kit 1.0.0 をリリースしました。 React Native WebRTC Kit (長い…) は WebRTC ネイティブライブラリ (libwebrtc) を React Native アプリケーションから使えるライブラリです。 WebRTC を利用する React Native アプリケーションを作りたい場合にご利用ください。

リポジトリはこちら。ライセンスは Apache License 2.0 です。

なお、今回も @akisutesama の開発力に大変お世話になりました (特に React Native のビルド) 。ありがとうございました。

対応プラットフォーム

現時点では iOS のみに対応しています。 Android は追って対応する予定です。

サポートについて

React Native WebRTC Kit に対する有償のサポートについては現在提供しておりません。質問やバグ報告は Issues の利用をお願いします。ただし、 Sora のライセンス契約の有無に関わらず、 Issue への応答時間と問題の解決を保証しませんのでご了承ください。

Issue とプルリクエストは、基本的にバグ修正のみ対応します。なにぶん弊社のリソースに限りがあるので、新機能の要望やプルリクエストには対応しません(できません)。機能の追加や変更を行いたい場合は、本ライブラリをフォークしてご利用ください。

基本的な開発方針

  • 本ライブラリは特定の WebRTC 製品やサービスに依存しない汎用的なライブラリです。現在公開しているサンプルアプリケーションは弊社製品の WebRTC SFU Sora に依存していますが、 Sora 専用のライブラリではありません。
  • ただし、本ライブラリの仕様は WebRTC SFU Sora の利用に必要な範囲のみに限られます。例えば、現在は Sora がデータチャネルに対応していないので、本ライブラリも対応していません (今後 Sora はデータチャネルに対応する予定ですので、その後に追って対応します) 。
  • 積極的に最新版の WebRTC ライブラリに追従します。現時点で対応しているバージョンは M66 です。大目に見てください。

WebRTC ライブラリについて

本ライブラリが利用する WebRTC ライブラリ (iOS なら “WebRTC.framework”) は、デフォルトの設定では弊社がビルドしたバイナリを指定しています。このバイナリは弊社製品用の設定でビルドしてあるので、他のバイナリを使いたい場合は適宜入れ替えてください。具体的な方法はドキュメントを参照してください。

react-native-webrtc との関係について

本ライブラリと同種のライブラリである react-native-webrtc は、おそらく WebRTC を利用する React Native アプリケーションの開発に最も使われていると思われるライブラリです。ただし、本ライブラリと react-native-webrtc の間に互換性はありません

元々は本ライブラリは react-native-webrtc の完全互換を目的として開発が始まりました。さらに遡ること、当初は react-native-webrtc を拡張あるいは修正し、開発に貢献する予定でした。現状 react-native-webrtc の開発は活発ではなく、リリースのペースが早い WebRTC への追従が遅れがちだったからです。弊社の製品は WebRTC の最新版に追従する必要がありました。

しかし、 react-native-webrtc が依存する古い libwebrtc を最新版に入れ替えれば OK とはいきません。最新版の libwebrtc は API が更新されており、まとまった範囲のコードの書き換えが必要でした。そこでフォークを検討しましたが、 react-native-webrtc の設計と実装は過度に複雑な面があり、そこに手を入れるよりフルスクラッチで実装するほうが易しいと判断し、互換性のあるライブラリの開発を始めました。しかし、 libwebrtc への追従の際に JavaScript 側の API も変更する必要があるとわかりました。最終的に互換性の維持は困難と判断し、中途半端に互換性を維持するよりやりたいようにやるか面倒くさい、というわけで互換性を捨ててまったく新しいライブラリを開発することにしました。

ところで、本ライブラリ名が決まるまでの候補がこちらです。ご笑納ください。

  • react-native-libwebrtc
  • react-native-webrtc-shiguredo
  • react-native-webrtc-yet-another
  • react-native-webrtc-kai (改)
  • react-native-webrtc-plus
  • react-native-webrtc-extra (しばらくこれだった)
  • react-native-webrtc-super
  • react-native-webrtc-final
  • react-native-webrtc-next
  • react-native-webrtc-ng (next generation)
  • react-native-webrtc-good
  • react-native-webrtc-very-good
  • react-native-webrtc-wonderful
  • react-native-webrtc-perfect

ブラウザ API との相違点

本ライブラリの API は可能な範囲でブラウザ API を下敷きにしています。 ただし、 React Native というアプリケーションであるプラットフォームの違いと、 libwebrtc とブラウザの違いから同一の API の提供は難しいです。アプリケーション開発用のライブラリとしての使い勝手を優先して、主に以下の変更を加えています。詳しくは API リファレンスを参照してください。

  • ブラウザ API では接頭辞のないすべてのクラスに接頭辞 RTC を追加しました。例: MediaStream -> RTCMediaStream
  • 映像を描画するビュー RTCVideoView を追加しました。
  • getUserMedia で起動したデバイスを停止する stopUserMedia を追加しました。
  • getUserMedia の機能はデバイスに依存します。

JavaScript から libwebrtc を扱う仕組み

一体 JavaScript からどうやって RTCPeerConnection を操作しているのか気になる方もいると思いますので、 iOS の場合について簡単に説明しておきます。ネイティブモジュールの詳細は公式のドキュメントを参照してください。特に React Native ライブラリの開発に関しては情報が少なくてつらいです。

本ライブラリのネイティブモジュールは、 JavaScript の WebRTCModule オブジェクトで表されます。 WebRTCModule オブジェクトのメソッドはネイティブレベル (ObjC) で実装されており、 JavaScript で呼んだメソッドと同名のネイティブのメソッドが実行されます。

このときに JavaScript で渡した引数は、ネイティブに JSON オブジェクトとして渡されます。 iOS であれば NSString, NSNumber, NSArray, NSDictionary のいずれかです (boolean の扱いがね…) 。この JSON オブジェクトはネイティブで変換用メソッドを実装すれば任意のオブジェクトに変換されてメソッドに渡されます (JSON -> RTCConfiguration など) 。ただし、一部のオブジェクト (RTCPeerConnection や RTCMediaStream など) は JSON と相互変換しにくいので、ネイティブ側で専用のユニークなタグ (ID) をオブジェクトに割り当て、そのタグを JavaScript とネイティブ間で受け渡しすることで操作しています。これは react-native-webrtc でも同様です。

以上の実装が気になる方は、次のファイルが参考になるかもしれません。

  • WebRTC.js
  • RCTConvert+WebRTC.h / .m
  • WebRTCModule.h / .m
  • WebRTCModule+RTCPeerConnection.h / .m

Swift について

本ライブラリのネイティブモジュールは ObjC で実装されています。すでに Swift も 4 まで進んだ時代になぜ ObjC なのか、 Swift で実装できないのかと思われるかもしれませんが、公式ドキュメントにもあるようにできなくはありません。しかし、ネイティブモジュールの実装では React Native が提供する ObjC のマクロが重要になります。 Swift で実装可能な範囲はまだまだ一部で、まだまだ ObjC が必要なのが現状です (今後もたいして変わらないでしょう) 。