特集:Azureメディアサービスを利用したストリーミング配信(後編)
Azureメディアサービスを利用したアプリケーション開発
デバイスに向けた動画配信サービスを容易に構築できるAzureメディアサービスを紹介。今回は、サンプル・アプリケーションを開発してメディア・サービスの機能について学習する。
前編では、動画配信サービス構築時の課題を解説することで「Microsoft Azure(旧称:Windows Azure)メディア・サービス」(以下、「メディア・サービス」と記載する)を利用する必要性を述べ、メディア・サービスの機能について紹介した。後編である今回は、サンプル・アプリケーションを開発してメディア・サービスの機能について学習する。なお、コードはC#で記述する。
また、本記事で説明するアプリケーションを利用する場合、事前にAzureのサブスクリプションを契約する必要がある。
- *注Windows、Microsoft Azureは、Microsoft Corporationの商標または登録商標です。
それでは、メディア・サービスを利用した動画ファイルのアップロードから配信までの処理を行うアプリケーションと、配信した動画ファイルを再生するアプリケーションを作成していこう。これらのアプリケーションの動作イメージは以下になる。
メディア・サービスを利用したアプリケーションは、メディア・サービスSDKを利用しており、動画ファイルを再生するアプリケーションは「Player Framework」と呼ばれるライブラリを利用する。
Azureメディア・サービスSDKを利用したアプリケーション開発
.NET Framework向けのメディア・サービスSDKを利用し、メディア・サービスに動画ファイルをアップロード、エンコーディング、配信するアプリケーションを作成する。今回利用するサンプルコードは、「GitHub - WAMediaServiceSampleApp」として公開している。こちらのソース・コードを基にメディア・サービスを利用する方法を紹介する。
ベースとなるサンプル・アプリケーションの準備
まず、GitHubからWAMediaServiceSampleAppソリューションをダウンロードし、Visual Studioからソリューションを開き、ソリューションをリビルドすることでアセンブリの依存関係を解決する(※リビルドを行ってもアセンブリの依存関係が解決できない場合は、Visual Studio 2012の[オプション]ダイアログで、[パッケージ マネージャー]カテゴリの[ビルド中に足りないパッケージをダウンロードすることを NuGet に許可]チェックボックスにチェックを入れて、もう一度試してほしい。次の画面のようになればOKだ)。
- *本稿では特に明記しないが、アセンブリの参照はNuGetを利用して依存関係が解決されている。NuGetについては「.NETで開発モジュール導入が楽々に! NuGet入門」を参照すること。
Mainメソッドとアクセス・キーの設定
次に、管理ポータルから、前回作成したメディア・サービスのアカウント名とアクセス・キーを(次の画像の手順で)取得する。
取得したアカウント名とアクセス・キーを利用して、WAMediaServiceSampleAppのサンプル・アプリケーションを修正する。この時点でサンプル・アプリケーションは実行可能だが、実行前にサンプル・アプリケーションの処理について記載する。
まず、Visual StudioでProgram.csファイルを開き、ProgramクラスのMainメソッドのコード(下記のコード)を参照してみよう。
// メディア・サービスのアカウント名とキー名 ― App.configファイルを編集してください
private static string _accountName = ConfigurationManager.AppSettings["AccountName"];
private static string _accountKey = ConfigurationManager.AppSettings["AccountKey"];
// 動画ファイル・パス、動画公開URLを記載するファイル・パス ― App.configファイルを編集してください
private static string _moviefilePath = ConfigurationManager.AppSettings["MovieFilePath"];
private static string _urlfilePath = ConfigurationManager.AppSettings["UrlFilePath"];
static void Main(string[] args)
{
// 管理ポータルに表示されるアセット名を指定します
string assetName = "新規動画アセット";
Console.WriteLine("------------ アプリケーション開始 ------------");
CloudMediaContext context = new CloudMediaContext(_accountName, _accountKey);
// 1動画をアップロードし、エンコードした後に公開します(※注 エンコード完了には時間がかかります)
Console.WriteLine("1動画のアップロード~公開迄を実施");
UploadSimpleAsset(context, assetName, _moviefilePath);
EncodeSimpleAsset(context, assetName);
PublishSimpleAsset(context, assetName, _urlfilePath);
Console.WriteLine("");
// 2既存のアセットに対するサムネイルの作成&公開します(※注 エンコード完了には時間がかかります)
//Console.WriteLine("2アップロードした動画からサムネイルの生成と公開を実施");
//EncodeToThumbnails(context, assetName);
//PublishThumbnails(context, assetName, _urlfilePath);
Console.WriteLine("------------ アプリケーション終了 ------------");
Console.ReadLine();
}
|
このコードを見ると、App.configファイルからメディア・サービスの「アカウント名」「アクセス・キー」「動画ファイルのパス」「エンコード済み動画ファイルのURLを出力するテキスト・ファイルのパス」を取得していることが分かる。ここで、App.configファイルを開いて、先ほど取得したメディア・サービスのアカウント名やアクセス・キーを記載しよう。「動画ファイルのパス」にはアップロードしたいローカル・ファイルのパスを、また「URL出力用のテキスト・ファイルのパス」にも出力したいローカル・ファイルのパスを指定すればよい。
Mainメソッド内では、メディア・サービスのアカウント名とアクセス・キーを基に、メディア・サービスにアクセスするために利用するCloudMediaContextクラスのインスタンスを作成している。さらに、CloudMediaContextオブジェクトを利用した動画のアップロード(=UploadSimpleAssetメソッド)、動画のエンコード(=EncodeSimpleAssetメソッド)、動画の公開(=PublishSimpleAssetメソッド)の呼び出し処理を記載している(いずれのメソッドもProgramクラス内に実装している)。
- *今回はコメントアウトしているが、動画ファイルを基にしたサムネイル画像をエンコーディングすることも可能だ。必要な場合は、別途、サンプル・アプリケーションのコード内容を参照してほしい。
動画のアップロード処理
次に、動画のアップロード処理を記載したProgramクラスのUploadSimpleAssetメソッドのコード内容(下記のコード)について紹介する。
private static void UploadSimpleAsset(CloudMediaContext context, string assetName, string moviefilePath)
{
// アセットのインスタンスを作成時、ストレージ暗号化はしません
var asset = context.Assets.Create(assetName, AssetCreationOptions.None);
// 作成したアセットに格納するアセット・ファイルをファイル名から作成します
var assetFile = asset.AssetFiles.Create(Path.GetFileName(moviefilePath));
// アップロード進捗(しんちょく)を確認するためのハンドラを追加します
assetFile.UploadProgressChanged += (sender, e) =>
Console.WriteLine("★ {0}% uploaded. {1}/{2} bytes",
e.Progress,
e.BytesUploaded,
e.TotalBytes);
Console.WriteLine("アップロード開始");
assetFile.Upload(moviefilePath);
Console.WriteLine("アップロード終了");
}
static void AssetFile_UploadProgressChanged(object sender, UploadProgressChangedEventArgs e)
{
// 現在のファイル・アップロード状況を出力します
Console.WriteLine("★{1}/{2} bytes の {0}% アップロード ", e.Progress, e.BytesUploaded, e.TotalBytes);
}
|
上記のコードでは、動画ファイルを格納するための「アセット」と呼ばれる論理領域を作成し、その領域に格納するアセット・ファイルを作成して、そこに対して動画ファイルをアップロードしている。後述するが、IAssetFileインターフェイス(Microsoft.WindowsAzure.MediaServices.Client名前空間)のUploadProgressChangedイベントにイベント・ハンドラとなるメソッドを登録することで、動画アップロードの進捗(しんちょく)を表示することも可能だ。
動画のエンコード処理
次に、動画ファイルのエンコード処理を記載したProgramクラスのEncodeSimpleAssetメソッドのコード内容(下記のコード)について紹介する。
private static void EncodeSimpleAsset(CloudMediaContext context, string assetName)
{
var asset = context.Assets.Where(_ => _.Name == assetName).FirstOrDefault();
Console.WriteLine("ジョブの作成を開始");
var job = context.Jobs.Create("動画 Encoding Job");
var task = job.Tasks.AddNew("動画 Encoding Task",
GetMediaProcessor("Windows Azure Media Encoder", context),
"VC1 Smooth Streaming 720p",
// サンプルはSmooth Streamingの動画をエンコードします
// 引数を以下のMSDNを参考に変更することで、ほかの形式の動画ファイルにエンコードを変更可能
// http://msdn.microsoft.com/en-us/library/windowsazure/jj129582.aspx
TaskOptions.None);
task.InputAssets.Add(asset);
task.OutputAssets.AddNew(assetName + " - VC1 Smooth Streaming 720p", AssetCreationOptions.None);
// ジョブを実行します
Console.WriteLine("ジョブの実行");
job.Submit();
// ジョブの処理中のステータスを出力します
bool isJobComplete = false;
while (isJobComplete == false)
{
switch (job.State)
{
case JobState.Scheduled:
case JobState.Queued:
case JobState.Processing:
job = context.Jobs.Where(_ => _.Id == job.Id).FirstOrDefault();
Console.WriteLine("★ジョブ名={0}, 状態={1}", job.Name, job.State);
Thread.Sleep(10000);
break;
case JobState.Finished:
Console.WriteLine("★ジョブ名={0}, 状態={1}", job.Name, job.State);
isJobComplete = true;
break;
}
}
}
|
後述するProgramクラスのGetMediaProcessorメソッドを利用して動画ファイルのエンコーディングに利用するエンコーダーのインスタンスを取得している。また、動画エンコーディング用のジョブを作成し、Smooth Streaming向け動画ファイルを作成するタスクを登録している。今回利用する「VC1 Smooth Streaming 720p」プリセットのほか、さまざまな動画エンコーディング形式に対応している。異なるエンコーディング形式を指定したい場合、「MSDN: Windows Azure Media Encoder用のタスク プリセット文字列」を参照していただきたい。
次に、IJobインターフェイス(Microsoft.WindowsAzure.MediaServices.Client名前空間)のSubmitメソッドを利用して動画エンコーディングのジョブを実行する。ジョブの状態は、
- Scheduled
- Queued
- Processing
- Finished
と遷移し、ジョブの状態がFinishedになれば動画のエンコーディングは完了となる。動画ファイルの大きさによるが、エンコーディングには数分かかるので注意が必要だ。
GetMediaProcessorメソッドのコード内容(下記のコード)についても紹介しておこう。
private static IMediaProcessor GetMediaProcessor(string mediaProcessor, CloudMediaContext context)
{
// Query for a media processor to get a reference.
var theProcessor =
from p in context.MediaProcessors
where p.Name == mediaProcessor
select p;
// Cast the reference to an IMediaprocessor.
IMediaProcessor processor = theProcessor.First();
if (processor == null)
{
throw new ArgumentException(string.Format(System.Globalization.CultureInfo.CurrentCulture,
"Unknown processor",
mediaProcessor));
}
return processor;
}
|
CloudMediaContextオブジェクトのMediaProcessorsプロパティから、エンコーディング用のインスタンスを名前で指定して取得している。今回利用したWindows Azure Media Encoderのほかにも、動画ファイルに対する暗号化に利用できるWindows Azure Media Encryptorなども存在する。詳細は別途「MSDN: Media Services SDK for .NETを使って資産を処理する - メディア プロセッサへのアクセス」を参照していただきたい。
動画ファイルの公開
最後に、ProgramクラスのPublishSimpleAssetメソッドのコード内容(下記のコード)について紹介する。
メディア・サービスは動画ファイルをブロブ・ストレージに格納するため、ブロブ・ストレージの機能であるShared Access Signature*1(以降、SAS)を利用して動画ファイルの公開を制御する。
- *1Shared Access Signature(SAS)については、Windows Azure Storage Team Blogの「Introducing Table SAS (Shared Access Signature), Queue SAS and update to Blob SAS(英語)」に詳細が記載されている。
private static void PublishSimpleAsset(CloudMediaContext context, string assetName, string urlfilePath)
{
// 動画ファイルの公開URLを記載するファイルを指定します
string outFilePath = Path.GetFullPath(urlfilePath);
// assetNameで始まるアセットを取得します
var assets = context.Assets.Where(_ => _.Name.StartsWith(assetName));
// 1つのアセットに割り当てられるロケーターは10個までなので、古いロケーター情報を削除します
Console.WriteLine("古いlocatorを削除");
foreach (var locator in assets.ToList().SelectMany(_ => _.Locators))
{
locator.Delete();
}
// 公開用ロケーターを割り当てます
Console.WriteLine("公開用Locatorの割り当て");
IAccessPolicy accessPolicy =
context.AccessPolicies.Create("30日読みとり許可", TimeSpan.FromDays(30), AccessPermissions.Read);
// 公開用ロケーターを動画に割り当て、公開した動画のURLをファイルに出力します
foreach (var asset in assets)
{
List<String> fileSasUrlList = new List<String>();
foreach (IAssetFile file in asset.AssetFiles)
{
ILocator locator = null;
if (file.Name.ToLower().EndsWith(".ism"))
{
locator = context.Locators.CreateLocator(LocatorType.OnDemandOrigin, asset, accessPolicy, DateTime.UtcNow.AddDays(-1));
}
else if (file.Name.ToLower().EndsWith(".jpg") || file.Name.ToLower().EndsWith(".mp4"))
{
locator = context.Locators.CreateLocator(LocatorType.Sas, asset, accessPolicy, DateTime.UtcNow.AddDays(-1));
}
else
{
continue;
}
string sasUrl = BuildFileSasUrl(file, locator);
fileSasUrlList.Add(sasUrl);
WriteToFile(outFilePath, sasUrl);
}
}
}
|
AccessPolicyBaseCollectionクラス(Microsoft.WindowsAzure.MediaServices.Client名前空間)のオブジェクト(=CloudMediaContextオブジェクトのAccessPoliciesプロパティ)のCreateメソッドを利用して、公開する動画ファイルに付与するロケーターのインスタンスを作成し、LocatorBaseCollectionクラス(Microsoft.WindowsAzure.MediaServices.Client名前空間)のオブジェクト(=CloudMediaContextオブジェクトのLocatorsプロパティ)のCreateLocatorメソッドを利用して動画ファイルに対してロケーターのインスタンスを付与している。
ロケーターのインスタンスを付与する際、mp4形式の動画ファイルは直接、ブロブ・ストレージにアクセス可能な「https://<ブロブ・ストレージのアカウント名>.blob.core.windows.net」のURL上に発行される。一方、ストリーミング形式での配信が必要な場合はサーバー側にもストリーミング配信用の機能が必要なため、ロケーター作成時に「LocatorType.OnDemandOrigin」と指定することで「http://<メディア・サービスのアカウント名>.origin.mediaservices.windows.net」のURLを発行する。
次に紹介するProgramクラスのBuildFileSasUrlメソッドにて、動画配信の形式に応じた発行URLを作成する。
// ロケーターの割り当てたURLを取得する
static string BuildFileSasUrl(IAssetFile file, ILocator locator)
{
// locatorのパスを得るため、SAS URLにファイル名を結合する
if (locator.Type == LocatorType.OnDemandOrigin)
{
return new Uri(locator.Path + file.Name + "/Manifest").ToString();
}
else if (locator.Type == LocatorType.None || locator.Type == LocatorType.Sas)
{
var uriBuilder = new UriBuilder(locator.Path);
uriBuilder.Path = uriBuilder.Path + "/" + file.Name;
// SAS URLを返す
return uriBuilder.Uri.AbsoluteUri;
}
return string.Empty;
}
// URL情報をファイルに出力する
static void WriteToFile(string outFilePath, string fileContent)
{
if (string.IsNullOrWhiteSpace(fileContent))
{
return;
}
StreamWriter sr = File.AppendText(outFilePath);
sr.WriteLine(fileContent);
sr.Close();
}
|
このBuildFileSasUrlメソッドでは、ストリーミング配信でない場合は直接、動画ファイル名を指定しているが、ストリーミング配信の場合はマニフェスト・ファイルを指定していることが理解できる。ProgramクラスのWriteToFileメソッドは単純な処理のため特に解説はしない。
プログラムの実行と結果
Visual Studioから作成したアプリケーションを実行してみよう。次の画面に示すように、起動したコンソールから各メソッドでの処理結果を確認できる。
最後に、管理ポータル上で、動画ファイルの公開URLを確認する(次の画面を参照)。
ストリーミング形式の動画ファイルであるため、「http://<メディア・サービスのアカウント名>.origin.mediaservices.windows.net」形式のURLであることが確認できる。
動画再生用のアプリケーション開発
動画再生のアプリケーションは、Windows 8で利用可能なWindowsストア・アプリとして作成する。Windowsストア・アプリでストリーミング再生を利用する場合、以下のライブラリをインストールする必要がある。まず、以下のリンク先からライブラリを取得してアプリケーションの開発環境を構築する。
- Windows 8 SDK
- Microsoft Smooth Streaming Client SDK for Windows 8
- Player Framework for Windows and WP
また、Player Framework*2はWindows 8/Windows Phone/Silverlight /HTML5向けに提供されている。今回作成するWindowsストア・アプリだけでなく、多様なデバイス・ブラウザー向けに利用できる。クライアント側のライブラリであるため、Azureメディア・サービスに依存せずに利用することが可能だ。
ライブラリのインストール完了後、Visual Studioを起動してWindowsストア・アプリのソリューションを新規作成する。ソリューションの作成後、ソリューション・エクスプローラーからMainPage.xamlファイルを開き、以下のコードを追記する。
<Page
x:Class="StremApp1.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:StremApp1"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:mmppf="using:Microsoft.PlayerFramework"
xmlns:adaptive="using:Microsoft.PlayerFramework.Adaptive"
mc:Ignorable="d">
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
<mmppf:MediaPlayer AutoPlay="True" Source="<メディア・サービスで公開した動画のURL>">
<mmppf:MediaPlayer.Plugins>
<adaptive:AdaptivePlugin />
</mmppf:MediaPlayer.Plugins>
</mmppf:MediaPlayer>
</Grid>
</Page>
|
次に、ソリューション・エクスプローラ-上で、プロジェクトに対してコンポーネントの参照を追加する。以下の画像を参考にしてほしい。
プロジェクトの[プロパティ]から[ビルド]タブを選択し、[プラットフォーム ターゲット]で「x64」(32bit環境を利用している場合は「x86」)を選択する。
アプリケーションのビルドを実行後、アプリケーションを実行し、以下のように動画が再生されればアプリケーションの作成は完了だ。
- *2Windowsストア・アプリ向けにストリーミング再生用のアプリケーションを作成する手順は、「MSDN: Getting Started Guide - Player Framework for Xaml-based Windows store applications(英語)」に記載されているため、別途ご参照いただきたい。
まとめ
前後編で紹介したメディア・サービスの機能を利用することで、1つの動画ファイルからさまざまなデバイスやブラウザーに対応した動画を作成して公開できることが理解できたと思う。別途、動画配信サービスを構築する際のTIPSをまとめたスライドをSlideShare に公開しているため、必要な場合はこちらも参照していただきたい。
クラウドサービスを使って作る動画サイト?
また、今回紹介した機能以外にも、動的に動画のエンコーディングを行う「Dynamic Package」、HTTPベースでストリーミング再生を行う「MPEG-DASH」、Microsoft PlayReadyを利用したデジタル著作権管理(DRM)もメディア・サービスの機能として利用可能だ。
本稿のほかにも「はじめての Windows Azureメディア サービス」がMSDNで公開されているため、別途参照してほしい。
1. 動画配信サービスの課題と、Azureメディアサービスの機能概要
デバイスに向けた動画配信サービスを容易に構築できるAzureメディアサービスを紹介。今回は、動画配信サービス構築時の課題とそれを解決するための機能を説明する。