ReplayKit の RPScreenRecorder#startCapture を使ってアプリをキャプチャする
iOS9でReplayKitが登場し、iOS10でReplayKitにライブ機能が追加されました。
そしてiOS11で ReplayKit Live に対応したアプリでiPhoneの画面自体をキャプチャできるようになるなど新たな機能が追加されました。
今回はiOS11で追加された RPScreenRecorder#startCapture
を触ってみたのでメモしていきます。
AVPlayer
と Metal
、 SpriteKit
をキャプチャし動画に書き出すサンプルを作ってみたので興味があれば見てみてください。
https://github.com/yoshimin/ReplayKitSample
※左がMetalで右がSpriteKit
RPScreenRecorderとは
RPScreenRecorder
自体はiOS9で登場したアプリ画面をキャプチャしてくれるクラスです。
ただ、iOS9で登場した機能は
func startRecording(handler: ((Error?) -> Void)? = nil)
により画面のキャプチャを開始し
func stopRecording(handler: ((RPPreviewViewController?, Error?) -> Void)? = nil)
によりキャプチャを終了すると、 RPPreviewViewController
というキャプチャした動画を再生するためのViewControllerが渡されるので、それを表示することでユーザーが動画の確認やカメラロールへの保存、シェアなどができるというものでした。
実装はシンプルでかんたんなのですが、プログラム側で RPScreenRecorder
録画された動画を取得することはできず使いみちは限られていました。
それが今回iOS11で RPScreenRecorder
でキャプチャした映像をリアルタイムに受け取ることができるようになりました。
PScreenRecorder#startCaptureの使い方
ではどうやってキャプチャするかというと
func startCapture(handler captureHandler: ((CMSampleBuffer, RPSampleBufferType, Error?) -> Void)?, completionHandler: ((Error?) -> Void)? = nil)
で開始して
func stopCapture(handler: ((Error?) -> Void)? = nil)
で終了する。
これだけです。
startCapture
でキャプチャを開始すると第二引数のコールバックが呼ばれます。
もし開始に失敗した場合はここで Error
が返ってきます。
第一引数の captureHandler
はキャプチャ中継続的に呼ばれ、ここで CMSampleBuffer
が返ってくるのであとはこれを好きに扱うことができます。
今回作ったサンプルのように動画に書き出す場合、 返された CMSampleBuffer
が音声データなのか映像データなのかを判別する必要がありますが、それは captureHandler
の第二引数である
RPSampleBufferType を使います。
RPSampleBufferType
は以下のように3つのタイプがあり、 .video
なら映像データ、 .audioApp
ならアプリ音声と判別ができます。
public enum RPSampleBufferType : Int {
case video
case audioApp
case audioMic
}
3つめに audioMic
というのがありますが、マイク音声も取れます。
マイク音声を録音するには startCapture
する前に
RPScreenRecorder.shared().isMicrophoneEnabled = true
を1行書いてあげればOKです。
ただし、音声が録音できるのは isMicrophoneEnabled
を true
にした状態で startCapture
すると、以下のようなダイアログが表示されるので、ユーザーが「画面とマイクを収録」を選んでくれた場合のみです。
使ってみて
使い方は簡単だし、 CMSampleBuffer
があれば使い方は開発者の自由なので実装の幅が広がりそうかなと思いました。
UIView
だけでなく Metal
や SpriteKit
の画面も簡単にキャプチャできるのでゲーム配信とかライトに作れそう。(SpriteKit使ってゲーム作る人は少なそうですが)
使ってみて気づいたのは、サイレントモード中の消音や、端末のボリュームの上げ下げはそのままキャプチャに反映されます(ただしボリュームを上げ下げしたときのUIまでは映り込みません)。
アプリの画面上に映るものはキャプチャされてしまうのでサンプルアプリも「録画/停止」ボタン(上のスクショを参照)も一緒にキャプチャされています。
Metal
による描画だけをキャプチャしたいとかはできなそうです。
あと、startCapture
したときにユーザーに「画面の収録を許可しますか?」というダイアログをOSが出してきますが、このダイアログのメッセージ部分には「収録内容はカメラロールに保存したり友達と共有したりできます。」と書いてます。
実装者がそのような機能を実装しないと保存も共有もできないのでどうゆう意図なのか気になります。
これらの機能を実装しないとリジェクトされたりするのでしょうか?
ということで RPScreenRecorder#startCapture
を使ってみたまとめでした。
Author And Source
この問題について(ReplayKit の RPScreenRecorder#startCapture を使ってアプリをキャプチャする), 我々は、より多くの情報をここで見つけました https://qiita.com/yoshimin@github/items/71e31fdc4a0ae626fd29著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .