【MATLAB】App Designerのボタンで動画再生をする

# はじめに
　動画再生をできるアプリをMATLABで作成したので、その方法をまとめます。本記事では、動画をボタンで再生・一時停止できるまでを説明します。HTML・CSS・Javascriptはほとんど初めての経験だったので、だいぶ苦労しました。

完成形はこんな感じです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1001284/0d6bb032-d589-521a-2a5d-b85f497c4fc4.png)

# 目的
　・App Designer で作成したアプリで、動画を再生したい。
　・アプリ上に再生ボタンと一時停止ボタンを作成し、動画再生をボタンで操作したい。

# 環境
　MATLAB R2020b

# アプリ上での動画再生について
　App Designerで動画を再生する場合、`uihtml`を使用するのがよいみたいです。MATLABの公式ページで例が紹介されています([HTML ファイルを使用したオーディオおよびビデオの組み込み](https://jp.mathworks.com/help/matlab/ref/uihtml.html#mw_ba2404bf-2886-4627-a95a-20236cacd324))。ただし、再生する動画はogg形式である必要があるようです。mp4形式の動画は再生出来ませんでした（公式の`audio_videoplayers.html`の例ではなぜかmp4の記載がある...いらないのでは...）。私が持っている動画編集ソフトでは、ogv形式の動画しか出力できなかったので、ogv形式の動画を用意しました。
　また、今回はアプリ上で作成したボタンを使用して、動画の再生・一時停止を行いたいと思います。これは、公式ページの[MATLAB でのデータ変化に対する JavaScript の応答のコーディング](https://jp.mathworks.com/help/matlab/ref/uihtml.html#mw_6224b701-5001-4d6e-bf60-2982ce25d302)を参考にしました。

# 作戦
　公式ページにもあるように、MATLABでのデータ変化に対して、Javascriptで何らかの処理を行うことができます。これは、`app.MovieHTML.Data`の値が変化することで、これをトリガーとしてJavascriptでイベントを発生させます。また、`app.MovieHTML.Data`の値はJavascript内で受け取ることができます。
　したがって、アプリのボタンを押すことで`app.MovieHTML.Data`の値を変化させてイベントを発生させ、その値からHTMLに埋め込んだ動画の再生・一時停止を行います。

# 使用するファイル
　今回使用するファイルを挙げます。これらはすべて同じディレクトリに保存します。
　・VideoPlay.mlapp
　・movie.html
　・style.css
　・xylophone_video.oga

# HTML側の作成
　次のようなHTMLファイルを作成します。名前は`movie.html`とします。動画は公式ページの例で使用されている`xylophone_video.oga`をお借りしました。
　`app.MovieHTML.Data`の値は、`htmlComponent.Data`に格納されています。これをJavascriptでは n に代入し、n=1だと再生、n=0だと一時停止を行います。

```html:movie.html
<link rel="stylesheet" type="text/css" href="./style.css">
<html>
    <head>
        <script type="text/javascript">
            function setup(htmlComponent)
            {
                htmlComponent.addEventListener("DataChanged", function(event)
                { 
                    var n = parseInt(htmlComponent.Data);
                    if (n == 1)
                    {
                        document.getElementById("mv").play();
                    }
                    else if (n == 0)
                    {
                        document.getElementById("mv").pause();
                    }
                }
                );
            }
        </script>
    </head>
    <body>
        <div>
            <video id="mv" src="./xylophone_video.oga" type="video/ogg" ></video>
        </div>
    </body>
</html>
```

　動画の大きさなどの設定は、`style.css`に記述します。このCSSでは、アプリのサイズを変更しても、動画全体が常に表示されるようにしています。

```CSS:style.css
html, body {
  height: 100%;
}

video {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    margin: auto;
    height: 100%;
    width: 100%;
    max-width: 90%;
    max-height: 90%;
    padding: 0;
}
```

# アプリ側の作成
　次のように、HTML・再生ボタン・一時停止ボタンを配置します。
　![1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1001284/254571ad-cfc5-be77-a491-8462e88015b0.jpeg)
部品の名称は、
　・HTML：app.MovieHTML
　・再生ボタン：app.PlayButton
　・一時停止ボタン：app.StopButton
としました。

　次に、`app.MovieHTML.Source`に`movie.html`を設定します。この時点で、アプリ上に動画が表示されると思います（再生はされない）。

　動画再生・一時停止をボタンでできるようにします。再生ボタンのコールバック`PlayButtonPushed(app, event)`と、一時停止ボタンのコールバック`StopButtonPushed(app, event)`を次のように設定します。これで、再生ボタンを押すと`app.MovieHTML.Data`に1が代入され、動画再生のイベントが発生します。一時停止も同様です。

```matlab
% Button pushed function: PlayButton
function PlayButtonPushed(app, event)
    app.MovieHTML.Data = 1;
end

% Button pushed function: StopButton
function StopButtonPushed(app, event)
    app.MovieHTML.Data = 0;
end
```

　アプリを実行すれば、再生ボタンで動画を再生、一時停止ボタンで動画を一時停止できると思います。


# 課題
　再生ボタンを押してから動画再生が終了した後、もう一度再生ボタンを押しても最初から動画が再生されません。これは、再生ボタンを押したときに`app.MovieHTML.Data`に1が入っているので、動画終了後に再生ボタンを押しても`app.MovieHTML.Data`の値が変化しないからです。
 したがって、動画終了後、
　一時停止をクリック → 再生ボタンをクリック
すれば、`app.MovieHTML.Data`の値が変化し、動画が最初から再度再生されます。良い解決方法を考え中です。

# おわりに
　アプリのボタンから、動画を再生・一時停止することができました。HTMLは動作が軽いです。次は、アプリの編集フィールドから動画の再生開始位置を指定できるようにしたいと思います。間違っているところや、アドバイスがあれば教えてください。