画像/映像に関連する技術に携わる開発者としては、ユーザー目線を忘れないために、日々、下記のような記事を読みマーケットを学んでいく必要がある。
SNOWは現在チェックしておかねばならないアプリの一つである。
こんな事件もあったようだ。
一部の人たちにとっては、目が大きくなるというのはクリティカルなポイントだということが分かる。彼女達にとって重要なのはbitrateなどではない。
SNOWはローカルへの画像、動画の保存を行うが、WebRTCによるリモートとの動画通信においてもSNOWのようなフィルタ機能を付けてみたい、というのが今回のテーマとなる。
WebRTC iOS SDKでの実装を考えていく。
ローカルのデバイスカメラからのキャプチャを送信するために、VideoSourceやVideoTrackを組み立てる部分、 最新のバージョンでは以下のように書く。
以前はこのVideoCapturerとVideoSourceを別々に自分で用意することが出来なかった。RTCVideoCapturerプロトコルが用意されたことで、それを実装したクラスを用意すれば、 カメラ以外からも画像を流せるようになった。
Android側のSDKでは以前から、同様のVideoCapturerインタフェースは存在し、 スクリーンやファイルからキャプチャするクラスも用意されていた。 iOS側も同じように開かれたインタフェースにしていこうという事だろう。
このようにインタフェースが開かれたことによって、 CapturerがVideoSourceにビデオフレームを流す箇所をフックすることもできるようなった。 少し工夫すれば、フィルタ処理を簡単にかませるようになっている。
フィルタの実装
RTCVideoSourceは、RTCVideoCapturerDelegateプロトコルを実装している。 といってもこのプロトコルが要求するメッセージは一つだけだ。
- (void)capturer:(RTCVideoCapturer *)capturer didCaptureVideoFrame:(RTCVideoFrame *)frame;
このように処理が流れるので、同じプロトコルを実装したクラスを間に挟みvideo frameを中継する。この中継地点で処理をかましてしまえばいい。
フィルタ用のクラスの実装例
このように用意したフィルタを使い、冒頭のVideoSource, VideoCapturer, VideoTrack生成箇所を書き換える。
これで先程の処理の流れが構築できた。
注意点として、このfilterオブジェクトはCapturer内ではweakリファレンスとして保存されている。 そのため、リファレンスカウンタがゼロになって開放されないように、一連のセッションが終了するまでどこかで保持しておく必要がある。
後は上で省略したフィルタ部分を好きに書いていくだけだ。
iOSの場合はCoreImageフレームワークが充実しているので、基本的にはそれを利用してフィルタ処理を実装していくことになるだろう。
渡ってきたRTCVideoFrameから、CIImageの編集にもっていくまでの流れまで含めた形で、MyVideoSourceFilterを書き直すと、だいたい以下のようなコードがテンプレとなる。
あとは一般的な画像処理アプリと同じようなCIFilterの処理をfilterImage内に書いていくだけだ。