Deep Insider の Tutor コーナー
>>  Deep Insider は本サイトからスピンオフした姉妹サイトです。よろしく! 
特集:Azureメディアサービスを利用したストリーミング配信(後編)

特集:Azureメディアサービスを利用したストリーミング配信(後編)

Azureメディアサービスを利用したアプリケーション開発

2013年10月8日

デバイスに向けた動画配信サービスを容易に構築できる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だ)。

メディア・サービスの参照設定
メディア・サービスの参照設定

Mainメソッドとアクセス・キーの設定

 次に、管理ポータルから、前回作成したメディア・サービスのアカウント名とアクセス・キーを(次の画像の手順で)取得する。

メディア・サービスのアカウント名とアクセス・キー

 取得したアカウント名とアクセス・キーを利用して、WAMediaServiceSampleAppのサンプル・アプリケーションを修正する。この時点でサンプル・アプリケーションは実行可能だが、実行前にサンプル・アプリケーションの処理について記載する。

 まず、Visual StudioでProgram.csファイルを開き、ProgramクラスのMainメソッドのコード(下記のコード)を参照してみよう。

C#
// メディア・サービスのアカウント名とキー名 ― 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();
}
ProgramクラスのMainメソッドのコード

 このコードを見ると、App.configファイルからメディア・サービスの「アカウント名」「アクセス・キー」「動画ファイルのパス」「エンコード済み動画ファイルのURLを出力するテキスト・ファイルのパス」を取得していることが分かる。ここで、App.configファイルを開いて、先ほど取得したメディア・サービスのアカウント名やアクセス・キーを記載しよう。「動画ファイルのパス」にはアップロードしたいローカル・ファイルのパスを、また「URL出力用のテキスト・ファイルのパス」にも出力したいローカル・ファイルのパスを指定すればよい。

 Mainメソッド内では、メディア・サービスのアカウント名とアクセス・キーを基に、メディア・サービスにアクセスするために利用するCloudMediaContextクラスのインスタンスを作成している。さらに、CloudMediaContextオブジェクトを利用した動画のアップロード(=UploadSimpleAssetメソッド)、動画のエンコード(=EncodeSimpleAssetメソッド)、動画の公開(=PublishSimpleAssetメソッド)の呼び出し処理を記載している(いずれのメソッドもProgramクラス内に実装している)。

  • *今回はコメントアウトしているが、動画ファイルを基にしたサムネイル画像をエンコーディングすることも可能だ。必要な場合は、別途、サンプル・アプリケーションのコード内容を参照してほしい。

動画のアップロード処理

 次に、動画のアップロード処理を記載したProgramクラスのUploadSimpleAssetメソッドのコード内容(下記のコード)について紹介する。

C#
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);
}
ProgramクラスのUploadSimpleAssetメソッドのコード

 上記のコードでは、動画ファイルを格納するための「アセット」と呼ばれる論理領域を作成し、その領域に格納するアセット・ファイルを作成して、そこに対して動画ファイルをアップロードしている。後述するが、IAssetFileインターフェイス(Microsoft.WindowsAzure.MediaServices.Client名前空間)のUploadProgressChangedイベントにイベント・ハンドラとなるメソッドを登録することで、動画アップロードの進捗(しんちょく)を表示することも可能だ。

動画のエンコード処理

 次に、動画ファイルのエンコード処理を記載したProgramクラスのEncodeSimpleAssetメソッドのコード内容(下記のコード)について紹介する。

C#
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クラスのEncodeSimpleAssetメソッドのコード

 後述するProgramクラスのGetMediaProcessorメソッドを利用して動画ファイルのエンコーディングに利用するエンコーダーのインスタンスを取得している。また、動画エンコーディング用のジョブを作成し、Smooth Streaming向け動画ファイルを作成するタスクを登録している。今回利用する「VC1 Smooth Streaming 720p」プリセットのほか、さまざまな動画エンコーディング形式に対応している。異なるエンコーディング形式を指定したい場合、「MSDN: Windows Azure Media Encoder用のタスク プリセット文字列」を参照していただきたい。

 次に、IJobインターフェイス(Microsoft.WindowsAzure.MediaServices.Client名前空間)のSubmitメソッドを利用して動画エンコーディングのジョブを実行する。ジョブの状態は、

  1. Scheduled
  2. Queued
  3. Processing
  4. Finished

と遷移し、ジョブの状態がFinishedになれば動画のエンコーディングは完了となる。動画ファイルの大きさによるが、エンコーディングには数分かかるので注意が必要だ。

 GetMediaProcessorメソッドのコード内容(下記のコード)についても紹介しておこう。

C#
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;
}
ProgramクラスのGetMediaProcessorメソッドのコード

 CloudMediaContextオブジェクトのMediaProcessorsプロパティから、エンコーディング用のインスタンスを名前で指定して取得している。今回利用したWindows Azure Media Encoderのほかにも、動画ファイルに対する暗号化に利用できるWindows Azure Media Encryptorなども存在する。詳細は別途「MSDN: Media Services SDK for .NETを使って資産を処理する - メディア プロセッサへのアクセス」を参照していただきたい。

動画ファイルの公開

 最後に、ProgramクラスのPublishSimpleAssetメソッドのコード内容(下記のコード)について紹介する。

 メディア・サービスは動画ファイルをブロブ・ストレージに格納するため、ブロブ・ストレージの機能であるShared Access Signature*1(以降、SAS)を利用して動画ファイルの公開を制御する。

C#
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);
    }
  }
}
ProgramクラスのPublishSimpleAssetメソッドのコード

 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を作成する。

C#
// ロケーターの割り当てた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();
}
ProgramクラスのBuildFileSasUrlメソッドのコード

 このBuildFileSasUrlメソッドでは、ストリーミング配信でない場合は直接、動画ファイル名を指定しているが、ストリーミング配信の場合はマニフェスト・ファイルを指定していることが理解できる。ProgramクラスのWriteToFileメソッドは単純な処理のため特に解説はしない。

プログラムの実行と結果

 Visual Studioから作成したアプリケーションを実行してみよう。次の画面に示すように、起動したコンソールから各メソッドでの処理結果を確認できる。

Azureメディア・サービスSDKを利用したアプリケーションの実行結果

 最後に、管理ポータル上で、動画ファイルの公開URLを確認する(次の画面を参照)。

 ストリーミング形式の動画ファイルであるため、「http://<メディア・サービスのアカウント名>.origin.mediaservices.windows.net」形式のURLであることが確認できる。

管理ポータルからアプリケーションの実行結果を確認する

動画再生用のアプリケーション開発

 動画再生のアプリケーションは、Windows 8で利用可能なWindowsストア・アプリとして作成する。Windowsストア・アプリでストリーミング再生を利用する場合、以下のライブラリをインストールする必要がある。まず、以下のリンク先からライブラリを取得してアプリケーションの開発環境を構築する。

  1. Windows 8 SDK
  2. Microsoft Smooth Streaming Client SDK for Windows 8
  3. Player Framework for Windows and WP

 また、Player Framework*2はWindows 8/Windows Phone/Silverlight /HTML5向けに提供されている。今回作成するWindowsストア・アプリだけでなく、多様なデバイス・ブラウザー向けに利用できる。クライアント側のライブラリであるため、Azureメディア・サービスに依存せずに利用することが可能だ。

 ライブラリのインストール完了後、Visual Studioを起動してWindowsストア・アプリのソリューションを新規作成する。ソリューションの作成後、ソリューション・エクスプローラーからMainPage.xamlファイルを開き、以下のコードを追記する。

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>
MainPage.xamlファイルのコード

 次に、ソリューション・エクスプローラ-上で、プロジェクトに対してコンポーネントの参照を追加する。以下の画像を参考にしてほしい。

[参照設定]から参照を追加する

 プロジェクトの[プロパティ]から[ビルド]タブを選択し、[プラットフォーム ターゲット]で「x64」(32bit環境を利用している場合は「x86」)を選択する。

プラットフォーム・ターゲットの変更

 アプリケーションのビルドを実行後、アプリケーションを実行し、以下のように動画が再生されればアプリケーションの作成は完了だ。

動画再生用のアプリケーションの実行結果

まとめ

 前後編で紹介したメディア・サービスの機能を利用することで、1つの動画ファイルからさまざまなデバイスやブラウザーに対応した動画を作成して公開できることが理解できたと思う。別途、動画配信サービスを構築する際のTIPSをまとめたスライドをSlideShare に公開しているため、必要な場合はこちらも参照していただきたい。

クラウドサービスを使って作る動画サイト?

 また、今回紹介した機能以外にも、動的に動画のエンコーディングを行う「Dynamic Package」、HTTPベースでストリーミング再生を行う「MPEG-DASH」、Microsoft PlayReadyを利用したデジタル著作権管理(DRM)もメディア・サービスの機能として利用可能だ。

 本稿のほかにも「はじめての Windows Azureメディア サービス」がMSDNで公開されているため、別途参照してほしい。

特集:Azureメディアサービスを利用したストリーミング配信(後編)
1. 動画配信サービスの課題と、Azureメディアサービスの機能概要

デバイスに向けた動画配信サービスを容易に構築できるAzureメディアサービスを紹介。今回は、動画配信サービス構築時の課題とそれを解決するための機能を説明する。

特集:Azureメディアサービスを利用したストリーミング配信(後編)
2. 【現在、表示中】≫ Azureメディアサービスを利用したアプリケーション開発

デバイスに向けた動画配信サービスを容易に構築できるAzureメディアサービスを紹介。今回は、サンプル・アプリケーションを開発してメディア・サービスの機能について学習する。

サイトからのお知らせ

Twitterでつぶやこう!