毎年恒例イベントを Azure Media Services を使ってオンラインで

今年 5 月、私が所属する事業部で毎年会場に集合して催していたキックオフを「オンラインで開催」しました。
ここで、その取り組みついて紹介しようと思います。


# はじめに

私が所属する事業部では、毎年キックオフを開催しています。東京近郊に勤める社員は東京の会場 (毎年会場を借りて) に赴き、地方に勤める社員は各地に設けられたサテライト会場 (主に各地のオフィス) に集まり、そこで東京の会場で行われている模様 (大事なお話など) が中継されて、それを観るという、いわゆる「集合型カンファレンス」で実施していました。

しかし、今年はご存じのとおりコロナ禍の影響で集合型カンファレンスが禁止となったため、すべてオンラインで開催することとなりました。
キックオフの開催内容はプレゼン形式 (スライドと発表者を映す) とし、それをあらかじめ撮影して編集し、決まった日時にその動画を配信するという形に決まりました。プレゼンの撮影、動画の編集、そして動画の配信すべてを専門業者に頼むと**ウン百万円**もかかるそうです。

**「...それくらい自前でなんとかできるっしょ」**

ということで、一部のメンバーに白羽の矢が立ちました。

せっかくの機会なので、「事業部」らしさ (「ヒト」と「プロセス」と「テクノロジー」でデジタル・トランスフォーメーションを促進 ([弊社サイト](https://www.persol-pt.co.jp/service/systemsolution/)より)) が出るような形で、そして当初の予定より (大幅に?) コストを抑えて実現しようと提案し、了承を得ることができました。


# 要件を整理する

まず、要件を以下のように整理しました。

- 事業部の社員「1,000 人程度」がアクセス
- 事業部の全社員が自宅からリモート参加、デバイスはいろいろと想定
    - 社内ネットワークに負荷はかけられない
    - 社内インフラは使わない想定で
- ライブ配信ではなく、撮影→編集→動画配信する
- YouTube などパブリックな場所での公開はダメ！
    - 限定公開 (URL を知っている人だけ限定して公開) でもダメ！
    - 認証は必須！
- 動画配信は「当日 14:00 から 16:00 まで」
- システムダウンはゼッタイダメ！
    - 大事な話を伝える場だから


# 配信方法を検討

手間をかけずに実施できるならそれはそれで良いですよね。なので、それも含めて以下の 3 つの方法で検討します。

- [Zoom](https://zoom.us/) (有償版) で配信
    - :no_good: キャパが足らない (所有するライセンスの都合で)
- [Microsoft Teams ライブイベント](https://docs.microsoft.com/ja-jp/microsoftteams/teams-live-events/what-are-teams-live-events?WT.mc_id=AZ-MVP-5003113)で配信
    - :ok_woman: キャパ MAX 10,000 人　([2020 年 7 月 1 日までは MAX 20,000 人](https://docs.microsoft.com/ja-jp/microsoftteams/teams-live-events/plan-for-teams-live-events?WT.mc_id=AZ-MVP-5003113#teams-live-events-and-skype-meeting-broadcast))
    - :ok_woman: イベントあたり MAX 4 時間　([2020 年 7 月 1 日までは MAX 16 時間](https://docs.microsoft.com/ja-jp/microsoftteams/teams-live-events/plan-for-teams-live-events?WT.mc_id=AZ-MVP-5003113#teams-live-events-and-skype-meeting-broadcast))
    - :question: 事業部 (DX部) らしいやり方？
    - :question: 当日、誰が配信係やるんだ問題、どこでやるんだ問題
        - 動画ファイル (ウインドウ) を共有して、それを再生
            - 詳しい手順は[こちらのドキュメント](https://support.microsoft.com/ja-jp/office/d077fec2-a058-483e-9ab5-1494afda578a)や[動画](https://www.youtube.com/playlist?list=PLNyto1oCyhGJ9VNNolQKkfxEKIY8EhNen)を参照
        - 安定したネットワーク環境の準備
            - 計画については[こちらのドキュメント](https://docs.microsoft.com/ja-jp/microsoftteams/teams-live-events/plan-for-teams-live-events?WT.mc_id=AZ-MVP-5003113)、セットアップについては[こちらのドキュメント](https://docs.microsoft.com/ja-jp/microsoftteams/teams-live-events/set-up-for-teams-live-events?WT.mc_id=AZ-MVP-5003113)を参照
    - :no_good: 認証させる場合のアカウント問題
        - DX部で所有する Office 365 環境ではいろいろ検証を行っているので、その検証の妨げになってはならないし、その検証自体が当日の妨げになってはならない
- [Azure Media Services](https://docs.microsoft.com/ja-jp/azure/media-services/latest/media-services-overview?WT.mc_id=AZ-MVP-5003113) を使った配信
    - :ok_woman::ok_woman: キャパ、開催日時・時間は気にしない
        - システム構成でどうにかなる！
    - :ok_woman::ok_woman: 使った分だけお支払い
        - 当日、必要な分だけスペック上げる！
    - :ok_woman: アカウントは Azure サブスクリプションに紐づく Azure AD テナントで管理
    - :ok_woman::ok_woman: 事業部 (DX部) らしいやり方！

このようにいろいろと検討した結果、「Azure Media Services」をメインにシステムを構築することとしました。


# システム構成と体制

キックオフのシステム構成と体制は、以下の図のとおりです。
キックオフの撮影だけはオフィス (必要最小限のメンバーのみ) で行い、その他の作業は原則在宅勤務なので各々の自宅で行いました。

![勉強会_p9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230264/f0cde261-2c6d-244c-af54-895cefb44741.png)


## Azure Active Directory (ID 管理)

今回のシステムの ID を管理します。まずは 1,000 人ほどの ID を作成しなければなりません。:cold_sweat:
ご心配なく、[Azure ポータル](https://portal.azure.com/)の [Bulk create (ユーザーの一括作成)](https://docs.microsoft.com/ja-jp/azure/active-directory/users-groups-roles/users-bulk-add?WT.mc_id=AZ-MVP-5003113) でカンタンに一括作成できます。

Bulk create は、

- 対象の Azure AD テナントの「[グローバル管理者](https://docs.microsoft.com/ja-jp/azure/active-directory/users-groups-roles/directory-assign-admin-roles?WT.mc_id=AZ-MVP-5003113#global-administrator--company-administrator)」、または「[ユーザー管理者](https://docs.microsoft.com/ja-jp/azure/active-directory/users-groups-roles/directory-assign-admin-roles?WT.mc_id=AZ-MVP-5003113#user-administrator)」ロールが割り当てられたアカウントでサインインする必要がある
- 最大 50,000 ユーザーまで一括作成できる
- ざっくりな手順
    - Azure ポータルから CSV テンプレートをダウンロード
    - CSV 形式のファイルを EXCEL などで開き、必要な項目 (UPN, 表示名は必須) に値を入力して保存
    - Azure ポータルで、編集した CSV 形式のファイルをアップロード
    - しばらく待って、ハイ出来上がり ※最大 1 時間かかる場合がある

作った後は、ID の追加やパスワードのリセットなどの作業が少なからず発生することでしょう。これからシステムを構築する側としては、できれば窓口の役割を担うメンバーにまかせたい。しかし、Azure ポータルの操作はおそらく初めてでしょうし、ID に対する操作以外は触らせたくありません。:cold_sweat:
ご心配なく、窓口の役割を担うメンバーに必要最低限のロールを割り当て、操作手順を伝え、事前に練習してもらえば問題ありません。

![図1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230264/d4f0ca55-11ea-dfde-1f89-dd343129e37d.png)

やって欲しいことの手順は、該当するチュートリアルで初心者でもわかるだろうと確認した上で、以下のドキュメントを示しました。

- [Azure Active Directory を使用してユーザーのパスワードをリセットする > パスワードをリセットするには](https://docs.microsoft.com/ja-jp/azure/active-directory/fundamentals/active-directory-users-reset-password-azure-portal?WT.mc_id=AZ-MVP-5003113#to-reset-a-password)
- [Azure Active Directory を使用してユーザーを追加または削除する > 新しいユーザーの追加](https://docs.microsoft.com/ja-jp/azure/active-directory/fundamentals/add-users-azure-active-directory?WT.mc_id=AZ-MVP-5003113#add-a-new-user)
- [Azure Active Directory を使用してユーザーを追加または削除する > ユーザーの削除](https://docs.microsoft.com/ja-jp/azure/active-directory/fundamentals/add-users-azure-active-directory?WT.mc_id=AZ-MVP-5003113#delete-a-user)

そして、これらを操作する窓口の役割を担うメンバーには「[ユーザー管理者](https://docs.microsoft.com/ja-jp/azure/active-directory/users-groups-roles/directory-assign-admin-roles?WT.mc_id=AZ-MVP-5003113#user-administrator)」ロールを割り当てれば、心配することなくおまかせできます。


## Azure Media Services (動画配信)

Azure Media Services は、動画配信プラットフォームを提供するサービスです。
メディアのアップロードから CDN までのメディア配信のコア機能とインフラ、API を提供します。

![勉強会_p11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230264/44bbeee0-32d8-4610-2c67-11e5c8ac21bb.png)

[ビデオオンデマンド配信](https://docs.microsoft.com/ja-jp/azure/media-services/previous/media-services-portal-vod-get-started?WT.mc_id=AZ-MVP-5003113) の手順に従って、Azure ポータルで操作することでカンタンに動画を配信できます。コンテンツ (メディア) を公開する際、配信期間 (開始と終了の日時) を指定することができます。

[ストリーミングエンドポイント (配信元)](https://docs.microsoft.com/ja-jp/azure/media-services/latest/streaming-endpoint-concept?WT.mc_id=AZ-MVP-5003113) には、Standard と Premium の 2 つのタイプがありますが、ここは迷わず「Standard」を選びましょう。なぜなら、スループットが最大 600 Mbps までオートスケール (スケールアップ) するし、[Azure CDN](https://docs.microsoft.com/ja-jp/azure/media-services/latest/scale-streaming-cdn?WT.mc_id=AZ-MVP-5003113) を組み合わせることによって、さらに実効スループットが大幅に向上します。

![図2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230264/a7681579-e6bc-1694-e7c0-65aa6b217416.png)


## クライアントサイド

クライアントサイドは、Blazor WebAssembly と Azure Media Player を採用しました。

![図3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230264/e95e97f6-c3e0-0e3e-bc69-c1cac1413160.png)


### Azure Media Player

動画を再生するプレイヤーは、[Azure Media Player](https://docs.microsoft.com/ja-jp/azure/media-services/latest/use-azure-media-player?WT.mc_id=AZ-MVP-5003113) を使います。実装については、[デモ ページ](https://aka.ms/azuremediaplayer) からプレイヤー部分のコードを入手できるので、それを動画を再生する Web ページにコピペすればほぼ出来上がり。Azure Media Player を設定および構成する方法の詳しくは[こちらのリファレンス](https://aka.ms/ampdocs)をご参照ください。


### Blazor WebAssembly

社内イベント向けにシステムを構築するので、どうせならいつも使っているようなものでなく、新しいテクノロジーを使ってみようと思い、今回は WebAssembly を使ってクライアントサイドで C# のコードが実行できる Blazor WebAssembly を採用しました。

![図4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230264/c8f7a7a9-6669-ba99-09ba-3a3f660b359e.png)

WebAssembly とは、Web ブラウザーのクライアントサイドスクリプトとして動作するプログラミング言語 (低水準言語) です。ブラウザー上でバイナリフォーマットの形で実行できることが特徴です。(略称 Wasm)
メジャーなブラウザーはサポートしています。

[参考：WebAssembly](https://webassembly.org/)

Blazor とは、C# と .NET Core を用いて Web アプリの開発を可能にする UI フレームワークです。JavaScript を用いず、C# によるプログラミングで [SPA (Single Page Application)](https://docs.microsoft.com/ja-jp/aspnet/core/client-side/spa-services?WT.mc_id=AZ-MVP-5003113&view=aspnetcore-3.1) の Web アプリを開発できるため、.NET の知識や経験を Web アプリに活かせます。

WebAssembly を活用した Blazor を「Blazor WebAssembly」と呼び、先日の「[Microsoft Build 2020](https://mybuild.microsoft.com/)」でフル機能が実装されて本番運用に対応した[「3.2.0」がリリース](https://twitter.com/aspnet/status/1262762290627002377)されました。

[参考：ASP.NET Core Blazor の概要](https://docs.microsoft.com/ja-jp/aspnet/core/blazor/?WT.mc_id=AZ-MVP-5003113&view=aspnetcore-3.1)

クライアントサイドのすべてを Blazor WebAssembly を用いてで実装できれば良かったのですが、ちょっと時間が限られていたこともあり、プレイヤーなど一部は JavaScript で実装しています。ちなみに Blazor WebAssembly で C# コードから JavaScript 関数を呼び出すこともできます。

[参考：ASP.NET Core Blazor で .NET メソッドから JavaScript 関数を呼び出す](https://docs.microsoft.com/ja-jp/aspnet/core/blazor/call-javascript-from-dotnet?WT.mc_id=AZ-MVP-5003113&view=aspnetcore-3.1)

ユーザー認証は Azure AD を用いますが、もちろん Blazor WebAssembly で実装できます。実装方法については、以下のドキュメントに手順が記載されていますので、ご参照ください。

[参考：Secure an ASP.NET Core Blazor WebAssembly standalone app with Azure Active Directory](https://docs.microsoft.com/en-us/aspnet/core/security/blazor/webassembly/standalone-with-azure-active-directory?WT.mc_id=AZ-MVP-5003113&view=aspnetcore-3.1)

デプロイ先は、[Azure App Service (Web Apps)](https://docs.microsoft.com/ja-jp/azure/app-service/overview?WT.mc_id=AZ-MVP-5003113) にしました。プランは、実質、静的コンテンツですので「Standard」で十分でしょう。インスタンス数は利用者が 1,000 人程度なので 1 個で大丈夫かな。
※静的コンテンツなので、[Azure Blob Storage にデプロイする](https://cloudsteady.jp/post/10344/)という手もありますね。ただ、今回は「大事な話を伝える場」なので無難に。
※[Azure Static Web Apps](https://docs.microsoft.com/ja-jp/azure/static-web-apps/overview?WT.mc_id=AZ-MVP-5003113) 使ってみたかった...


## Azure Logic Apps＋SharePoint リスト (ビジネスレイヤー)

サーバーサイドでは、社員が動画を観たという証跡 (簡易的なものですが) を残すことと、Azure Media Services の[マニフェストファイル](https://docs.microsoft.com/ja-jp/azure/media-services/latest/filters-dynamic-manifest-overview?WT.mc_id=AZ-MVP-5003113)の URL を取得する仕事を行います。サクッと [Azure Logic Apps](https://docs.microsoft.com/ja-jp/azure/logic-apps/logic-apps-overview?WT.mc_id=AZ-MVP-5003113) で作ることにしました。データストアは、DB を作るまでもないですし、どなたでも操作できるだろうと、SharePoint リストを使うことにしました。[コネクタ](https://docs.microsoft.com/ja-jp/connectors/sharepointonline/?WT.mc_id=AZ-MVP-5003113)でカンタンに接続できますし。

![図5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230264/606ea26d-0623-ea0f-56be-fdd36864dc46.png)

動画配信する期間が限られていることもあり、一時的にアクセスが集中することが想像できます。ただ、Azure Logic Apps はサーバーレスなサービスなので、スケーリングは Azure におまかせでユーザーが自由に設定することはできません。何かないかと調べたところ、[高スループットモード (プレビュー)](https://docs.microsoft.com/ja-jp/azure/logic-apps/logic-apps-workflow-actions-triggers?WT.mc_id=AZ-MVP-5003113#run-in-high-throughput-mode) というものがありました。これは通常 5 分間に実行されるアクション数に既定の制限 (100,000) が設定されていますが、この制限を可能な限り最大アクション数 (上限 300,000) まで引き上げるという機能です。(「リミッターカット」というところでしょうか)
これだ！ということでオンします。

![図6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230264/c1e07756-0709-04d0-fa24-b0dee8d3b84e.png)


## 監視 (モニター)

キックオフ当日はちゃんと動いてくれるかなとドキドキでオドオドします。 :cold_sweat:
ちゃんと動いていることを確認したいので、Azure ポータルでそれぞれの挙動を監視していました。

- [Application Insights > Live Metrics Stream](https://docs.microsoft.com/ja-jp/azure/azure-monitor/app/live-stream?WT.mc_id=AZ-MVP-5003113)
    - リクエスト数、CPU 使用率、発生した例外などをリアルタイムで監視 :rolling_eyes:
- [Azure Monitor Logs (Log Analytics) > Logic Apps Management ソリューション](https://docs.microsoft.com/ja-jp/azure/logic-apps/monitor-logic-apps-log-analytics?WT.mc_id=AZ-MVP-5003113)
    - Logic Apps の実行状態を監視 :rolling_eyes:
- [Azure AD サインイン レポート](https://docs.microsoft.com/ja-jp/azure/active-directory/reports-monitoring/concept-sign-ins?WT.mc_id=AZ-MVP-5003113#sign-ins-report)
    - みんなサインインできているねと監視 :rolling_eyes:
- [SharePoint リスト > Excel にエクスポート](https://support.office.com/ja-jp/article/bfb2ea48-6118-4fa9-abb6-cced9424e5d9)
    - Excel を開いて、ちょくちょく [データ]タブ > [すべて更新] でリストの内容を見て、みんな観に来ているねと監視 :rolling_eyes:


# アンケート結果

キックオフも無事終わり、後日いっしょに活動していた事業戦略部さんがアンケートをまとめてくれましたので、その一部「Q.リモートによる動画視聴についてお聞かせください。」を紹介します。
※これは弊社内のアンケート結果ですので、ご参考までにご覧いただければと思います。

![勉強会_p21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230264/f773c57c-f76d-cba9-dfe6-84abec0bd804.png)

8 割は「集中して視聴できた」との回答でしたので安心しました。
2 割くらいの「集中して視聴できなかった」内訳を見ると、視聴する側の環境の整備については参加者個人に委ねるざるを得ないですが、**会場での「一体感」や「臨場感」に近づけるための工夫** (拍手とか歓声とかですか？) が必要そうです。たとえば、キックオフを観ながら Teams の特設したチャネルで会話をするみたいな (公式な) 施策があったらより良くできたかもしれませんね。

そのほか、「オンラインのほうが参加率が高い」、「動画が見返せて良い」などといったメリットが得られたようです。


# まとめ

- **改めて、Azure Media Services のコスパを実感** :astonished:
    - 動画配信のところだけで当日のランニングコストを見積もると、(超概算ですが) 3 万円くらいかと。
    - このお値段で、1,000 人程度に向けた動画配信ができるオドロキ！
- **参加者向けのフォローを Azure ポータルを触ったことない方にまかせる** :heart_eyes:
    - 事前に、発生しうる事象とその対処法、やって欲しいことの操作手順を伝え、それを見て自主練習 (体験) させれば問題なくできるとわかりました。
    - Azure ポータルが扱いやすく進化したということでしょうか。
- **新しいテクノロジーにチャレンジ** :dart:
    - 社内イベントなので、ちょっとくらいはチャレンジ要素 (お試しする場) を含めても良いでしょう。
    - ただし、大事な話を伝える場なので、システムダウンはゼッタイダメ！ですが。
- **余分なコストカット** :scissors:
    - そもそも社員なので、新たにかかる人件費はほぼゼロですね。
    - ランニングコストもかかったとしてもせいぜい十数万円くらいでしょう。
- **オンライン開催も「選択肢のひとつ」と、そして専門業者に頼ることなく「自分たちだけでもオンライン開催できる」と示せたのではないのでしょうか** :muscle:


最後まで読んでいただきありがとうございました。
この記事で紹介した内容がみなさんの業務や知識の向上に少しでもお役に立てればと思います。