Unityでスマホの実行画面を録画する

## 背景と実施したこと
Unityで作成したiOSアプリまたはAndroidアプリにおいて、特定のシーンを画面録画したいことってありますよね？
UnityのEditor上ではRecord機能が提供されていますが、実機で画面録画をしようと思うとどうすればいいのかわからない人もいるのではないでしょうか？

今回は、有料のAsset [Native Screen Recorder For Android & iOS](https://assetstore.unity.com/packages/tools/integration/native-screen-recorder-for-android-ios-180403?locale=ja-JP "Native Screen Recorder For Android & iOS")を使ってみたので、その実装の仕方やハマった点などを記載していきます。


使用している技術のver情報は以下の通りです。
Android: 13 & 10
unity: 2022.3.5f1
Native Screen Recorder For Android & iOS: 3.5
※iOSのデバイスでは試していませんが、公式の紹介だとできるっぽいです。


参考にした記事
[【Unity】簡単にビデオ録画ができるアセット NatCorderのメモ](https://qiita.com/Four4_mm/items/4b1ea2c53e25033436ea "【Unity】簡単にビデオ録画ができるアセット NatCorderのメモ")
[【Unity】スマホアプリでカメラロールへの保存・SNSにシェアができるアセット NatShareのメモ
](https://qiita.com/Four4_mm/items/de2afa7fab89bbee8259 "【Unity】スマホアプリでカメラロールへの保存・SNSにシェアができるアセット NatShareのメモ
")

## 概要
+ 有料のAssetを使うと実装がめっちゃ楽。買い切りだし便利だよ。
+ SDKのVer、Target API Levelなどに注意。
+ 再生できないときはSetVideoSizeでフレーム幅・高を変更してみるといいかも。


## アセットのセットアップ
### 今回作るもの
今回はデバイスのカメラで物体を撮りつつ、その映像の下にテキストを動的に表示させるシンプルなアプリを作っていきます。
ユーザの任意のタイミング（今回はボタン押下時）で、画面録画が始まり、カメラで映した物体もその下に表示されたテキストも動画として保存し見返すことができるというのがポイントです。

### 画面録画機能はAndroidもiOSも標準機能
実は画面録画機能自体はiOSもAndroidも標準機能として提供されています。
※下記参考
https://www.android.com/intl/ja_jp/articles/recording/
https://support.apple.com/ja-jp/HT207935

とはいえ、録画を開始する際に毎回録画実行・停止の操作をするのも手間ですし、ホーム画面がちらっと見えたりするのも嫌なわけです。
ファイル名も指定などもできないですし。
そのため、あくまでUnityのアプリの中で画面録画ができるような機能を実現したかったのです。
テンポラリーなら標準機能を使う方がいいですね。

## Assetの紹介
少し前はNatCorder、NatShareというAssetがあったようですが2023年9月現在ではこちらは使えなくなっています。
そのため、適したAssetを探すところから始めました。
Unity Asset Storeで検索するといくつかそれらしいものはHitしますが、最新リリース日が2023年7月7日と比較的新しく、ドキュメント、サポートもしっかりしている「Native Screen Recorder For Android & iOS」というAssetを使うことにしました。お値段は$27.50。個人的には良心的な値段かと思います。
サポートともメール（当然ですが英語）で何度かやりとりしましたが、かなり迅速丁寧でした。

ただお試しとかがないので、いきなりお金払うのはちょっと...という人もいると思います。
そういった方向けになるべく丁寧に解説していきますね。

### セットアップ
※Androidの場合の手順であることを念頭に見てください。
[公式ドキュメント](https://drive.google.com/drive/folders/13f9Uur0Ao3sp0mJJbsyS3HpPddbj2Aib"公式ドキュメント")に従うだけでOKなのですが、一応記載しておきます。
Assetをダウンロード・インポートし以下の通り進めます。

1. Screen RecorderのPrefabを配置
Assets > SunShine Android Native Screen Recorder > Prefab > Screen Recorder
をドラッグ＆ドロップで持ってきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635205/75e8a210-314a-c34d-7fdb-0f395b20ef17.png)

1. manifest fileの編集
Assets > Plugins > Android > AndroidManifest.xmlのauthorityの部分を任意の値に書き換えます。
ユニークな値になるようにアプリの名称やパッケージの名前を入れておくのがお勧めです。
※ユニークな値にしないとアプリのインストール時にこけます。 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635205/9b0675c4-da31-2df0-4065-79c7b3f0ee83.png)

1. SmileSoftScreenRecordController.csの編集
Assets > SunShine Android Native ScreenRecorder > Scripts > SmileSoftScreenRecordController.cs.
の_fileProviderの値を2で変更した内容と同じにします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635205/ca029cb6-48ab-d3e8-3433-d20ba407d727.png)

これで準備は完了です。3分でできます。

## 実装
### 主な関数と実装例
functionはいろいろあるのですが、マストで使うのは以下2つです。

```c#:script.cs
//録画開始
SmileSoftScreenRecordController.instance.StartRecording();
//録画終了
SmileSoftScreenRecordController.instance.StopRecording();
```
ドキュメントにも各functionの使い方の記載はあるのですが、ドキュメントを見つつ同梱されている
Assets/Plugins/SunShine Android Native Screen Recorder/Scripts/ExampleScreenRecorder.cs
のコードを見てどのような使われ方をしているのかを見るのが一番よいです。

また自分の場合は画面録画の前にそもそもカメラを起動する必要があったので、そのパーミッションをコントロールす必要がありました。最終的に以下のような流れになっています。

```c#:script.cs（一部抜粋）
    void Start()
    {
        Permission.RequestUserPermission(Permission.Camera); //権限確認。
        SetUp(); //画面録画のパラメータを設定する。
    }

    public void OnClick()
    {
        // カメラのデバイス名を取得
        WebCamDevice[] devices = WebCamTexture.devices;
        if (devices.Length == 0)
        {
            Debug.LogError("カメラデバイスが見つかりません。");
            return;
        }

        // 最初に見つかったカメラを使用
        webcamTexture = new WebCamTexture(devices[0].name);

        // RawImageにカメラの映像を表示
        rawImage.texture = webcamTexture;

        // カメラを開始
        webcamTexture.Play();

        //録画開始
        SmileSoftScreenRecordController.instance.StartRecording();
    }
       

```

### 出くわした問題と対応
上記の実装でうまくいくかと思いきや、私の場合はうまく録画開始の処理ができませんでした。
正常であれば録画開始のために権限確認のポップアップなどが出るはずでがそれすら出ない始末。
原因がわからず、サポートにメールを送ると以下の返信が。
> Would you please check the following things and let me know the result. 
> 1. Did you accept the notification permission. If you do not see the notification permission popup then please set the target sdk 33 or above.  
> 2. After doing step 1 even if you failed to record the,  please build the example scene in an empty project and test again.
> 3. Did you check the demo apk?

ということでtargetのSDKを確認し、Player SettingのTarget API LevelをAndroid13に変更すると画面録画処理がうまくいきました。
これでOKと思いきや、今度は録画した動画がスマホで再生できないということに気づきました。
ファイルの破損はなさそうで、その証拠にスマホでは再生できないもののPCでは再生できます。
はて？と思い、スマホでも再生可能なMP4ファイルと比較するとフレーム幅、フレーム高がやや高くなっていることに気づきます。
そこで

```c#:script.cs
SmileSoftScreenRecordController.instance.SetVideoSize((int)(822), (int)(1920));
```
という感じでVideoSizeをいじると無事再生できました。
もし再生できない場合はこの値を見てみるのもいいかもです。

## まとめ
以上、Native Screen Recorder For Android & iOSを使った画面録画の方法でした。
どなたかの参考になれば幸いです。