iOS ReplayKitを調べてみた

iOS ReplayKitを調べた内容を纏めてみました。

# 環境

- macOS Big Sur 11.0 Beta
- Xcode 11.6
- 実機 iOS 13.6

# 機能概要

ReplayKitの主な流れ

- ReplayKitはiOS9から追加
- iOS11からアーキテクチャが変更され、RepalyKit2に
    - iOS11からコントロールセンターの画面収録機能が追加

ReplayKitには、主に２つの機能がある

## 1. 画面録画

### 1.1. Screen Recording（iOS9〜）
- 実行中のアプリを録画し、プレビューコントローラーから写真や共有で保存
![スクリーンショット 2020-08-17 22.45.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237942/15807d06-96f2-d84e-0e44-0844998cdb28.png)


### 1.2. In-App Screen Capture（iOS11〜）
- 実行中のアプリを録画した映像と音声を取得
![スクリーンショット 2020-08-17 22.45.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237942/26538c8a-d66f-6ad3-6703-25eb1144ad8b.png)


## 2. Live Broadcasting

### 2.1. In-App Broadcast（iOS10〜）
- 実行中アプリの映像と音声を配信

### 2.2. Broadcast Pairing（iOS11〜）

### 2.3. iOS System Broadcast（iOS11〜）
- 実行中アプリ以外のiOS画面も配信可能に
- コントロールセンターの画面収録からブロードキャスト配信を行う設定が追加
![_2020-08-17_22.53.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237942/c862cc16-01e8-d21a-9ae1-34c43e787fc2.png)

### 2.4. System Broadcast Picker（iOS12〜）
- 自アプリから画面収録画面を表示
![スクリーンショット 2020-08-17 22.54.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237942/f3aa66ed-5e1b-c71f-fd62-8bdb3b57153c.png)


# 実装方法

## Screen Recording

`RPScreenRecorder` と `RPPreviewViewController` を使用する

ネットに情報が多いので割愛

## In-App Screen Capture

`RPScreenRecorder` を使用する

ネットに情報が多いので割愛

## In-App Broadcast

`RPBroadcastActivityViewController`  を使用する

いまいち使い方はよくわからず

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237942/4077f4d2-1a52-04ad-166d-7f841d70b32b.jpeg" width="200">


## Broadcast Pairing

`RPBroadcastActivityViewController`  を使用する

preferredExtension に `Broadcast Setup UI Extension` のBundle IDを設定するとリストにSetup UIが表示されるが、いまいち使い方はよくわからず

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237942/be3c8fad-be4d-82e3-4250-772da4f7cb60.jpeg" width="200">


## iOS System Broadcast

- File → new → Target から `Broadcast Upload Extension` を追加する
- コントロールセンター → 画面収録 を長押しすると一覧に追加したExtensionが表示され、ブロードキャストを開始ができる
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237942/8bd0871d-2ef4-0c1c-f351-ddf255571dc0.jpeg" width="200">


- ブロードキャストを開始すると `Broadcasst Upload Extension` の processSampleBuffer() で Video / Audio Sample を受信する

## System Broadcast Picker

- 自アプリから画面収録画面を表示するには `RPSystemBroadcastPickerView` を使用する

```swift
let broadcastPicker = RPSystemBroadcastPickerView(frame: CGRect(x: 10, y: 50, width: 100, height: 100))

// 追加したBroadcast Upload ExtensionのBundleIDを設定
broadcastPicker.preferredExtension = kUploadExtension
// マイクのオン/オフ表示を設定
broadcastPicker.showsMicrophoneButton = true

// デフォルト表示の二重丸アイコンを文字列に変更
for subview  in broadcastPicker.subviews {
    let b = subview as! UIButton
        b.setImage(nil, for: .normal)
        b.setTitle("画面共有", for: .normal)
        b.setTitleColor(.black, for: .normal)
}

self.view.addSubview(broadcastPicker)
```

# 対応ソース

[https://github.com/shima-0215/ReplayKitSample](https://github.com/shima-0215/ReplayKitSample)

# ReplayKit対応アプリの動作

## Zoom

ZoomはReplayKitを使用し、画面の共有をおこなう機能を有している

- コントロールセンターの画面収録を長押しし、`zoom` を選択し `ブロードキャストを開始する` をタップするとiOS画面を共有できる（iOS11〜）
- ミーティング中画面の `共有` から `画面` をタップすると画面収録画面が表示され、`zoom` を選択し `ブロードキャストを開始する` をタップするとiOS画面を共有できる（iOS12〜）
    - iOS11の場合、`共有` から`画面` をタップすると、コントロールセンターからのセットアップ方法の画面が表示される

    　　[https://support.zoom.us/hc/ja/articles/115005890803-iOS-Screen-Sharing](https://support.zoom.us/hc/ja/articles/115005890803-iOS-Screen-Sharing)

- ミーティング中以外にコントロールセンターからブロードキャストを開始するとエラーとなる
- 画面の共有中に、他の端末でブロードキャストを開始されると、共有中の端末はエラーとなり終了する（後勝ちで動作）

## その他

- Skype, Teams, LINE, LINE LIVE も対応してそうだが、動作は未確認。

# 今後、調べたいこと

- アプリ本体側で iOS System Broadcast の開始と終了の通知を受け取りたい
    - RPBroadcastController の serviceInfo をKVOで受け取れる？
![スクリーンショット 2020-08-17 23.43.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237942/c653588a-ddcc-6f6e-5b4b-2d6dd43aa04d.png)


- Broadcast Upload Extension からアプリ本体側へ録画データを渡したい
    - App Groups（UserDefaults）経由で渡せばよい？
    - [https://github.com/webex/spark-ios-sdk/wiki/Implementation-broadcast-upload-extension](https://github.com/webex/spark-ios-sdk/wiki/Implementation-broadcast-upload-extension)


# 参考サイト

- WWDC15
    - [Going Social with ReplayKit and Game Center]([https://developer.apple.com/videos/play/wwdc2015/605/](https://developer.apple.com/videos/play/wwdc2015/605/))
- WWDC16
    - [Go Live with ReplayKit]([https://developer.apple.com/videos/play/wwdc2016/601/](https://developer.apple.com/videos/play/wwdc2016/601/))
- WWDC17
    - [What's New with Screen Recording and Live Broadcast]([https://developer.apple.com/videos/play/wwdc2017/606/](https://developer.apple.com/videos/play/wwdc2017/606/))
- WWDC18
    - [Live Screen Broadcast with ReplayKit]([https://developer.apple.com/videos/play/wwdc2018/601/](https://developer.apple.com/videos/play/wwdc2018/601/))
- WWDC20
    - [Capture and stream apps on the Mac with ReplayKit]([https://developer.apple.com/videos/play/wwdc2020/10633/](https://developer.apple.com/videos/play/wwdc2020/10633/))
- [iOSDC2019]([https://fortee.jp/iosdc-japan-2019/proposal/f7084cd9-d65f-41da-94e1-1eda2836e490](https://fortee.jp/iosdc-japan-2019/proposal/f7084cd9-d65f-41da-94e1-1eda2836e490))