【Swift】 Apple WatchにiPhoneのカメラ映像を表示する
watchOSにインストールされているカメラアプリはiPhoneのカメラ映像をリアルタイムで表示することができます。この機能は監視カメラアプリやドライブレコーダーアプリといったカメラを使用したiPhoneアプリに応用することができます。
iPhoneのカメラ映像をリアルタイムでWatchアプリに表示する機能を実現する方法について紹介します。
iPhoneアプリ側からビデオフレームを抽出する
以下のデリゲートメソッドを使用することでビデオフレームを抽出することができます。
func captureOutput(AVCaptureOutput, didOutput: CMSampleBuffer, from: AVCaptureConnection)
新しいビデオフレームが書き込まれる度に上記デリゲートメソッドがコールされます。このデリゲートメソッドを使用して、ビデオフレームをCMSampleBuffer
として取得します。 CMSampleBuffer
はビデオフレーム情報やタイムスタンプ情報などのさまざまな情報を含むオブジェクトです。このオブジェクトに含まれるビデオフレーム情報をWatchアプリに送信します。
CMSampleBufferをUIImageに変換する
CMSampleBuffer
には多くの情報が含まれていますが、Watchアプリに送信するのはビデオフレーム情報だけです。 従ってCMSampleBuffer
オブジェクトからビデオフレームデータを抽出し、UIImage
オブジェクトに変換します。
画像データのリサイズと圧縮
iPhoneアプリからWatchアプリに送信できるデータのサイズには制限があるため、画像データをできるだけ小さくします。 画像データは以下のメソッドでサイズ変更・圧縮します。
func scaledBy(x: CGFloat, y: CGFloat) -> CGAffineTransform
func jpegData(compressionQuality: CGFloat) -> Data?
Watchアプリに画像データを送信する
現在、iPhoneアプリからWatchアプリにデータを送信する方法は3つあります。
func sendMessage(_:replyHandler:errorHandler:)またはfuncsendMessageData(_:replyHandler:errorHandler :)
func transferUserInfo(_ :)
func transferFile(_:metadata :)
上記の各方法には、送信データサイズと送信タイミングの上限が異なります。
メソッド | 上限サイズ | 通信タイプ |
---|---|---|
sendMessage または sendMessageData | 65,536 bytes (65.5 KB) | 即時 |
transferUserInfo | 65,536 bytes (65.5 KB) | 即時でない |
transferFile | 262,144 bytes (262.1 KB) | 即時でない |
sendMessage
またはsendMessageData
は、iPhoneアプリとWatchアプリの間で即時通信が行われますが、やりとりすることができるデータの上限サイズは非常に小さいです。transferUserInfo
とtransferFile
は、iPhoneアプリとWatchアプリの間ですぐに通信することはできません。 ただし、transferUserInfo
の通信制限サイズは大きくなります。今回はカメラのライブビューをWatchアプリにリアルタイムで表示したいので、sendMessage
またはsendMessageData
を使用します。以下のサンプルコードはsendMessage
を使用して画像データをWatchアプリに送信しています。
画像データを受信してWatchアプリに表示
Watchアプリ側にデータが到着すると、次のデリゲートメソッドがコールされます。
func session(WCSession, didReceiveMessage: [String : Any])
上記のメソッドで受信したデータをUIImageに変換し、WKInterfaceImageImageオブジェクトに設定すればiPhoneのカメラ映像をWatchアプリに表示することができます。
Discussion