キャッチアップ! Windows Azure メディアサービス

第2回.NET DeveloperのためのMicrosoft Azureメディアサービスを使ったアプリケーション開発

なぜAPIなのか?

読者の皆さんの周囲でも動画を扱う機会がだいぶ増えてきていると思います。高性能なモバイルデバイスの普及で、誰でも簡単に動画撮影ができるようになってきたことが、その背景として挙げられます。また、4Gなどのインターネット回線の進化も大きな要因の1つでしょう。

動画を効率的にストリーミング配信する場合には、取り込み、エンコード、暗号化などのワークフローを組み上げる必要があります。これらは多くの場合、コンテンツ管理システムから制御されます。

商用サービス規模になると、コンテンツ管理システムは、B2C、B2Eだけでなく、B2B用のポータル、会員管理、課金、など各種システムと連携しています。つまり、HTML 1-2枚のキャンペーンサイトとは、バックエンドシステムの複雑性が増すのに、ビジネス上のパートナーリングと共に柔軟性への要求は高まるばかりです。

現在のコンテンツ管理システムと、動画配信システムの連携は、サーバやファイルの物理的な場所に依存しているケースが多く、そのためワークフローの変更と、それを簡単に実作業として行うのは大変です。

Microsoft Azureメディアサービスは、そうした問題に対応しています。

そのほとんどの機能をREST APIとして公開しています。ですので、ワークフローを柔軟に組むことができます。また、背後の物理的なインフラや、ジョブスケジューラなどを意識する必要はありません。また、そのアプリケーションの稼働場所も、Webサーバだけでなく、オンプレミスのサーバでも、PC、スマートフォンのアプリケーションでも、どこからでも呼び出せるようになっています。

つまり、スマートフォンからの動画のアップロードとプレビュー再生を制御するWebサイトのようなものから、映像コンテンツの制作から、パートナー会社とのレビューなどの共同作業。コンテンツ販売や、DRMを必要とするような配信まで、単一のプラットフォームで実にさまざまなシナリオに対応しているのです。

すでに、2014年のソチオリンピックでは、その大規模ライブ配信も無事のりきり、アメリカ対カナダのホッケーの準決勝では、210万人という史上最高の同時視聴者にも柔軟に対応してきました。

Media ServicesのAPI

ここでは、Media ServicesのAPIについて見ていきます。

図1 Azureメディアサービスの概要
図1 Azureメディアサービスの概要

すべての基盤は、図1で一番下にある世界各国にあるMicrosoft Azureのデータセンターと、その中のストレージ、コンピュートなどです。一般的には、動画配信のアプリケーションを組むと言えば、ここにエンコーダーや、ストリーミングサーバなどをインストールし、ジョブスケジューリングや高可用性のための監視ツールもインストール・構成をします。

メディアサービスでは、この部分が全て実装済みで、Microsoftによって維持・管理されており、皆さんがその作業をする必要性はありません。さらに外部から制御できるようにREST APIサーバ群を、上位層にもっています。

API呼び出しの内部では、実にさまざまな処理が行われています。

図2 Azureメディアサービスのアーキテクチャ
図2 Azureメディアサービスのアーキテクチャ

REST APIは、呼び出しプラットフォームを選びませんが、実際のコーディング作業はそれなりに増えます。そのため、REST APIをラッピングした以下のSDKが提供されています。

ここでは、それぞれのSDKの参考情報を挙げておきます。

.NET
https://www.nuget.org/packages/windowsazure.mediaservices
https://github.com/Azure/azure-sdk-for-media-services
Java
http://msdn.microsoft.com/en-us/library/azure/hh690946.aspx
PHP
https://github.com/Azure/azure-sdk-for-php
Node.js
https://github.com/fritzy/node-azure-media

オブジェクトモデル

すべてはCloudMediaContextオブジェクトから始まります。

図3 Media Services SDK for .NETの構成
図3 Media Services SDK for .NETの構成

以下の3つのオブジェクトで、映像配信のための操作をします。

  • ファイルをアップロードすることは、Assetの作成
  • エンコードなどをするためには、Jobの作成
  • 配信をするためには、Locatorの作成

2つの.NET SDK

.NET SDKでは、Media Servicesの機能のほとんどをカバーしているだけではなく、LINQなど最新の.NET環境で開発ができるようになっています。

.NET SDKの関連性
.NET SDKの関連性

Media Services .NET SDKが当初より提供されていたものです。REST API形式に比較的忠実ですので、詳細なコントロールができました。ですが、単純なファイルのアップロードだけでも、それなりのコードを記述する必要がありました。

リスト ファイルを非同期でアップロードするサンプルコード(Media Services .NET SDK)
/// 空のAsset作成
var ingestAsset = Context.Assets.Create(
    targetFile.Name,
    AssetCreationOptions.None
);
/// 空のAssetFile作成
var ingestAssetFile = ingestAsset.AssetFiles.Create(
        targetFile.Name);

 /// ファイル転送モニタリングオブジェクト作成
BlobTransferClient transferClient = new BlobTransferClient();
transferClient.TransferProgressChanged += (s, e) =>
{
    Console.WriteLine(" {0}: 経過 {1}%", e.LocalFile, e.ProgressPercentage);
};

/// ファイルがアップロード完了する間だけ、公開ポイントを作成
var uploadAccessPolicy = Context.AccessPolicies.Create(targetFile.Name,
                        TimeSpan.FromHours(3),
        AccessPermissions.Write | AccessPermissions.List);
var locator = Context.Locators.CreateLocator(LocatorType.Sas,
                ingestAsset,
                uploadAccessPolicy);

/// ファイルのアップロードを実行
var uploadTask = ingestAssetFile.UploadAsync(
        targetFile.FullName,
        transferClient,
        locator,
        System.Threading.CancellationToken.None);

ここでは、7ステップあります。

.NET SDKをさらに抽象化したものが、.NET SDK Extensionsになります。

同じ、ファイルアップロードのサンプルコードを見てみましょう。

ファイルを非同期でアップロードするサンプルコード(Media Services .NET SDK Extensions)
var asset = context.Assets.CreateFromFile(
    @"C:\Video\azure.wmv",
    AssetCreationOptions.None,
    (a, p) =>
    {
        Console.WriteLine("  経過 {0}%", p.Progress);
    });

なんと、1ステップになります。

注目をすべき点は、既存のAssetsという.NET SDKのコレクションオブジェクトはそのままで、.NET SDK Extensionでメソッドが追加されています。双方を切り替えることなく使えますので、まずは.NET SDK Extensionsのメソッドで試し、できなかった場合に、.NET SDKで、という方策で試すことができます。

Media Services .NET SDK extensionsでのVODアプリ開発

ここでは、ビデオ オン デマンド(VOD)の典型的なシナリオフローの開発について見ていきます。

Azureメディアサービスへの接続

前回もご紹介したコードですので、詳細は割愛いたします。

var context = new CloudMediaContext(
        "accountName",
        "accountKey"
        );

ファイルのアップロード

指定したファイルをアップロードする、という単純なステップになります。

var asset = context.Assets.CreateFromFile(
    @"C:\Video\azure.wmv",
    AssetCreationOptions.None,
    (a, p) =>
    {
        Console.WriteLine("  経過 {0}%", p.Progress);
    });

とくに重要な引数を説明します。

 とくに重要な引数
引数説明
Asset
Creation
Options
ストレージ内でファイルを暗号化して保持するかどうかを指定します。Common
Encryption
Protected
PlayReadyなどのDRMなどで保護済みのもの
Envelope
Encryption
Protected
AESなどの暗号化で保護されているもの
None暗号化しない
Storage
Encrypted
Azureで管理しているストレージの暗号化機能を使う
APIリファレンス
http://msdn.microsoft.com/ja-jp/library/microsoft.windowsazure.mediaservices.client.assetcreationoptions(v=azure.10).aspx

エンコード(トランスコード)実行

エンコード時には、Jobを作成します。Jobの中には、1つ以上のTaskを設定します。Jobの単位で実行、キャンセルなどを行います。Taskは入出力ファイルの関連性を指定すれば、直列実行しますし、そうでなければ並列に実行されます。

// 1. ジョブ作成
var job = context.Jobs.CreateWithSingleTask(
    MediaProcessorNames.WindowsAzureMediaEncoder,
    MediaEncoderTaskPresetStrings.H264AdaptiveBitrateMP4SetSD16x9,
    asset,
    asset.Name + "- output",
    AssetCreationOptions.None);

Media Services .NET SDK Extensionsでは、登録済みの最新のMedia Processorと、同じく登録済みのタスクプリセットを利用できるよう、列挙型が定義されています。

MediaProcessorNames:

 MediaProcessorの一覧
名前プロセッサ ID説明
Azure Media Encodernb:mpid:UUID:70bdc2c3-ebf4-42a9-8542-5afc1e55d217Media Encoderを使用してエンコードタスクを実行できます。サムネイル作成、オーバーレイ、ファイルの結合なども行えます。
Azure Media Packagernb:mpid:UUID:A2F9AFE9-7146-4882-A5F7-DA4A85E06A93.mp4からスムーズ ストリーミング形式への変換や、スムーズ ストリーミング形式からApple HTTP Live Streaming(HLS) 形式に変換を行います。
Azure Media Packagerのタスクプリセット
Azure Media Encryptornb:mpid:UUID:38A620D8-B8DC-4E39-BB2E-7D589587232BPlayReady Protectionを使用して、暗号化することができます
Azure Media Encryptorのタスクプリセット
Storage Decryptionnb:mpid:UUID:aec03716-7c5e-4f68-b592-f4850eba9f10ストレージ暗号化を使用して暗号化されたメディア資産を解読することができます
Media Services SDK for .NETを使って資産を処理する
http://msdn.microsoft.com/ja-jp/library/jj129580.aspx

MediaEncoderTaskPresetStrings

個々のエンコード設定については、以下をご参考にしてください。この設定次第で、画質・音質や、作成されるファイルサイズ、数。およびエンコード時間が大幅に変わりますので、良く考慮してください。

Media Services Encoder用のタスクプリセット
http://msdn.microsoft.com/ja-jp/library/dn619392.aspx
// 2. ジョブ実行.
job.Submit();
job = job.StartExecutionProgressTask(
    j =>
    {
        Console.WriteLine("   状態: {0}", j.State);
        Console.WriteLine("   経過: {0:0.##}%", j.GetOverallProgress());
    },
    System.Threading.CancellationToken.None).Result;

JobはSubmitをするまでは実行されません。

また、本番環境で使う際には、以下に注意ください。

  • 取得間隔が一定ではない:サンプルは、Azure Media ServicesのAPIサーバへポーリングをしており、その結果として変更があった場合のみ状態取得ができます。
  • 大量アクセス時には、パフォーマンス劣化の可能性がある:APIサーバも十分には用意していますが、さらなるスケールアウトのためには、Azure Queueストレージも利用できます。詳細は以下をご確認ください。
Media Services ジョブ通知の処理
http://msdn.microsoft.com/ja-jp/library/dn261241.aspx

配信準備の設定

ストリーミングを行うためには、コンテンツの公開期間も設定する必要があります。その期間を超えると自動的にコンテンツにアクセスできなくなります。

context.Locators.CreateLocator(
LocatorType.OnDemandOrigin,
outputAsset,
context.AccessPolicies.Create(
        "Streaming Access Policy",
        TimeSpan.FromDays(30),
        AccessPermissions.Read
)
);

ストリーミングサーバの要求後、約30秒ほどAzure内部での準備が完了しますので、配信ができるようになります。それぞれのストリーミング方式用に、ExtensionsではAssetに以下のURL取得メソッドを追加してくれています。

 配信方式とメソッド
配信方式メソッド
SmoothAsset.GetSmoothStreamingUri().AbsoluteUri
HLSAsset.GetHlsUri().AbsoluteUri
MPEG-DASHAsset.GetMpegDashUri().AbsoluteUri

MPEG-DASHは、2014年4月より、正式サービスインとなりました。

まとめ

.NETを使うことで、非常に少ないコード量で、多くの動画管理・配信の処理が行えるようになっています。そして、Azure側の機能強化の恩恵を最も受けられる環境とも言えます。とはいえ、実際の既存環境や、皆さんのスキルセットが.NET以外の場合も多々あると思いますので、そのために、Java/PHP/Node.jsをはじめ、各種SDKの充実を図るようにしてまいります。

まずは手軽に動画配信を楽しんでください。

参考
クイックスタート:Media Services .NET SDK Extensions の使用
GitHub:Media Services .NET SDK Extensions:ソースコードとサンプルコード

おすすめ記事

記事・ニュース一覧