超簡単! Azure Media Services のHTMLタグの作り方

Azure Media Servicesを選択頂くと、Azure Media Playerがもれなく無料で使えます。
ここでは、その簡単な使い方をご説明します。

  1. デモサイトに行きます

http://ampdemo.azureedge.net/azuremediaplayer.html


  1. ご自身の動画のURLを貼り付けます。そして [Update Player] を押します。
    動画が再生されるはずです。

動かなかった際に確認する事:

  1. codeを抽出

先のサイトの画面真ん中付近に、 というタブがあります。こちらには [Get Player Code] があります。これは本番で使えるHTMLタグです。

以下の様に表示されます。

  1. HTMLへ埋め込み

    お手持ちの、HTML

    HEAD

    BODY SCRIPT タグ
に、それぞれのコードをコピーください。

サンプルのHTMLファイル

https://github.com/dahatake/Azure-Media-Services-Samples/blob/master/31.%20AzureMediaPlayer_Simple/index.htm

  1. HTMLをブラウザーで起動

ローカルでも、任意のWeb Serverにでも、作成されたHTMLを置いてください。

勿論、Azure Web Appがお勧めですwww。スマートフォンからもアクセスして動作確認をしてください。

視聴数など取りたいでしょうから、Application Insightのタグを埋め込むと最高です! ログデータがAzure Storageに保存され、後から抽出して二次利用がしやすいですから。

Application Insight:

https://azure.microsoft.com/ja-jp/documentation/articles/app-insights-javascript/

Azure Media Player ドキュメント:

http://amp.azure.net/libs/amp/latest/docs/

Azure Media Player Plugin:

http://amp.azure.net/libs/amp/latest/docs/PLUGINS.html

ご参考: ビデオ プレーヤー アプリケーションの開発

https://azure.microsoft.com/ja-jp/documentation/articles/media-services-develop-video-players/

ついに来た! Live/VoD対応 かつ マルチプロトコル対応のラフカット編集ツール [Pre-Release版] (1)

ビデオ編集で、ラフカット編集と、ノーマル編集(?) は、全然出来ることが違います。インターネットのライブ配信中のラフカット編集は、フレーム準拠でなくても、見たい方の要望に応えられる場合が多いです。最近はFacebookやTwitterなどにビデオ投稿ができるようになったこともあり、そこへの短いmp4ファイルのアップロードが出来るだけでも、ライブ中のソーシャル連携が更に面白いものになります。
これまで、Silverlight時代にもあった、Microsoftからのラフカット編集。ついに、Azure Media PlayerのPluginとして、ベータ版といいますか、Pre-Release版が登場してきました。
何回かに分けて、超簡単版について説明をします。

デモサイト: http://ampdemo.azureedge.net/amp_editor.html

サンプルコード: https://github.com/dahatake/Azure-Media-Services-Samples/tree/master/35.%20Rought%20Cut%20Video%20Editor/ASP.NET%20Web%20API

サンプルコードの実行サイト: http://dahatakevideoeditor.azurewebsites.net/index.html

ASP.NET Web APIのものです。画面表示が若干乱れたままですが…

  1. 背景について (この回)
  2. サーバー側 Media Encoder Standard連携API
  3. Video Editor: Video Editor plugin for Azure Media Player

 

そもそもの課題

  • ライブ中の切り出しはそもそも難しかったです。配信データを、ストリーミングサーバー上で保存をしていないといけません
  • これまでも良いツールはありました。が、HLS専用だったり、Smooth Streaming 専用だったり。つまり、ストリーミング プロトコル毎のものしか無かったのです
  • そのツール自身が、作業環境が限定される場合もありました。

 

Azure Media Serviceのアプローチ

Streaming Services

Azure Media Servicesのライブ配信機能では、Azure上に送られてきたデータは、ストリーミングサーバー上でメモリ処理されると平行して、Blob Storageへ書き込みも行っています。

Programの作成時にBlogに保存する映像の尺(時間)を、Archive Windowで指定ができます。以下の例ですと、2時間ですね。

Blobに保存されているデータですが、データが作成され続けるLiveの特徴を吸収するために、映像数秒間の塊のファイルになっています。2秒がデフォルトの動きです。

 

2つのライブ映像の切り出し。Dynamic ManifestとMedia Encoder Standard

Liveを停止させることなく、別のコンテンツを作成させる手段が、Azure Media Servicesにはあります。Dynamic Manifestの作成とMedia Encoder StandardによるTranscodeです。
ライブの場合Dynamic Manifestは、終了点を指定できないので、多くのシナリオでは使えないと思います。
そのため、時間が多少かかってもいいので、Transcodeする方法が良いのではないかと思います。

 

Video Editor (Player付き)

Azure Media Playerに対して、Pluginにて、機能追加ができるようになりました。

 

Gallery: http://aka.ms/ampplugins

Galleryにあるもので、特に注目してもらいたいのは、Playerの状態を知るための Application InsightのPluginです。これによって、PV/UUだけでなく、カスタムイベントを使っての、視聴状態ビットレート、再生させたアクションなど、ユーザーの状態を知ることが出来ます。

 

その一部分として、Pre-Releaseですが、Video Editor が出てきました!!!

Video editor plugin for Azure Media Player (英語): https://azure.microsoft.com/en-us/blog/video-editor-plugin/

上記にもありますが、HTML5ベースで記載されていますので、様々なHTML5動作環境で、ラフカット編集ができるようになっていきます。

 

このツールは個人的にはとても期待をしています。
スポーツの中継を考えてください。プレイが落ち着いた際に、少し前の映像をスローモーションで解説することで、これから起こることの詳細がわかるのは大事ですよね。所謂、関連コンテンツになります。

 

次回以降、ツールの使い方について解説をしていきます。

Azureを使った、シンプルなライブ視聴システムの構築

最近Webinarという名の動画配信形式が使われ始めました。スピーカーがいて、ライブ配信をし、適時質問にも答えていく形ですね。マイクロソフトでも実施をしています。週に1-2度くらいしかやらない場合も多いので、インフラを常時持たない事の出来るAzureが役に立ちます。

Azure Media ServicesもHTML5ベースのPlayerが搭載され、その利用に役に立ちそうですが、幾つか不足している事があります。

  • 視聴者
    • ライブでの質問受付。投稿。話しながらなので、ミリセカンドのリアルタイムでの返答の必要はない。これはSkype for Businessの打ち合わせ中でも、体験できること。
  • サービス提供者
    • 視聴者数の把握。参加者0名ですと、切ないですから。

アイディア

全部作らないといけないか?というと実はそうではなく、Azure の各サービスを見渡すと、以下のサービスが役に立ちます。
いずれも高度な開発ができるプラットフォームですが、ここでは、ビジネスで利用できるための容易に使え、セキュアなPaaSを前提に考えてみます。同時アクセス100名くらいの規模でしたら、大きなシステムを組まなくてもこなせます (絶対ではないですが・・・)。

  • Azure Mobile App
    • https://azure.microsoft.com/ja-jp/services/app-service/mobile/
    • 各種デバイス用のUIと、バックエンドのAPIサービス + データベースとのやり取りを持っています。最初の構築では、「ToDoリスト」を登録するアプリケーションの作成ができるのですが、これはすなわち、「質問投稿」とラベルを変えても利用できます。即時性は無いですが。
  • Visual Studio Application Insight (執筆時点ではプレビューです)

画面構成

画面は、1ページに、以下の構成で作成をしてみます。
この場合は、Azure Mobile Appが作成してくれる「HTML」ページに、Azure Media Playerを加えるだけとなります。勿論、CSSの調整は必要ですが…

構築手順

スイッチャーがあるので、少しデラックスかもしれません。カメラとPC入力があるような場合は、例として下記のようなシステムを組みます。

用意するもの

  • カメラ。マイクですが、カメラの撮影場所ではなく、できたら話している人に近くで音が取れるように。
  • エンコーダー。
  • (おまけ) スイッチャー
  • 映像ケーブル、インターネット接続回線
  • AzureのSubscription (契約ともいいますね)

前日までの準備

  • Azure Mobile Appの作成
  • Application Insightの作成
  • Azure Media Servicesのアカウント作成。
  • ライブ配信用の「チャネル」作成。
  • HTMLページの編集。Azure Media Servicesと、Application Insightの連携
  • Azure Web Appの作成。上記のHTML5のホスティング
  • Azure Media Servicesでのライブ配信確認

そして、実は一番苦労するのが…

  • 収録システムの構築。カメラの台数を慎重に考えてください。1台のカメラで撮影するだけなら簡単です。PCの画面出力もあって複数となると、その切り替え、カメラ映像の一部にスライドを入れるPicture in Picture など、考慮が必要です… これは経験が必要!

本番当日

  • Azure Web App、Mobile App、SQL Databaseのキャパシティを本番用に。
  • Azure Media Servicesの本番設定。

さて、ここから実際の構築手順を見ていきます。

前日までの準備: 実際の手順

  1. Azure Mobile Appの作成

こちらの手順に従って[HTML5アプリ]を作成してください。
https://azure.microsoft.com/ja-jp/documentation/articles/app-service-mobile-dotnet-backend-html-get-started-preview/

途中、Visual Studioで変更設定を行います。Windowsをお持ちでない方は、Azure上にVisual Studioインストール済みの仮想マシンがありますので、そちらをご利用ください。

  1. Application Insightの作成

こちらも手順通りで作成してください。HTML 1ページですから、[Webページ]のものになります。
実作業が、JavaScriptのコードのコピーアンドペーストだけになります。
https://azure.microsoft.com/ja-jp/documentation/articles/app-insights-javascript/

  1. Azure Media Servicesの作成

同じく、以下を参考に作成してください。
https://azure.microsoft.com/ja-jp/documentation/articles/media-services-create-account/

  1. ライブ用のチャネルを作成

Azure Media Servicesでは、2つの種類のチャネルを用意しています。
作成して[開始]すると、課金されますので、そのタイミングは注意してください。

料金がかなり異なります。ライブエンコーダーは、画質をあげたくて、オンプレミスのエンコーダーの能力があまり無い時に使ってください。視聴端末にPCがある場合は、コストパフォーマンスを考えると高いと思われますが、ライブエンコーダーがお勧めです。視聴者に画面の文字等がきちんと映るように。

料金の詳細はこちらの[ライブ ビデオ]を参照してください。
https://azure.microsoft.com/ja-jp/pricing/details/media-services/

通常のチャネル:    約100円 / 1時間

ライブエンコーダー:    約4,000円 / 1時間

上記を考慮した上で、チャネルを作成します。

通常のチャネル:    https://azure.microsoft.com/ja-jp/documentation/articles/media-services-manage-channels-overview/

ライブエンコーダー:    https://azure.microsoft.com/ja-jp/documentation/articles/media-services-portal-creating-live-encoder-enabled-channel/

  1. HTMLページの編集

Azure Mobile AppのHTMLをベースにします。Azure Media Playerの文字列を以下より取得して作成します。

Azure Media Player のドキュメント (英語):    http://amp.azure.net/libs/amp/latest/docs/

こちらの[Quick Start]にある、以下の2つを行います。

  • Js/css ライブラリへの参照
  • videoタグへの設定

そして、Application InsightのJava Script文字列も取得します。

以下、サンプルのHTMLです。

———————————————————————————————-

<!DOCTYPE html>

<html>

<head>

<meta charset=”utf-8″ />

<meta http-equiv=”Content-Type” content=”text/html; charset=utf-8″ />

<meta http-equiv=”Pragma” content=”no-cache” />

<meta http-equiv=”Cache-Control” content=”no-cache” />

<meta http-equiv=”Expires” content=”Thu, 01 Dec 1994 16:00:00 GMT” />

<meta name=”viewport” content=”width=device-width,initial-scale=1.0″ />

<title>タイトル</title>

<link rel=”stylesheet” href=”styles.css” />

<meta name=”viewport” content=”width=device-width, initial-scale=1.0″ />

<!–[if lt IE 9]>https://cdnjs.cloudflare.com/ajax/libs/html5shiv/3.6.1/html5shiv.js<![endif]–>

<link href=”//amp.azure.net/libs/amp/latest/skins/amp-default/azuremediaplayer.min.css” rel=”stylesheet”>

//amp.azure.net/libs/amp/latest/azuremediaplayer.min.js

http://smartRollover.js

</head>

<body>

タイトル

    autoplay controls width=”760px” height=”400″ align=”center”poster=”images/img_01.jpg” data-setup='{“nativeControlsForTouch”: false,

“language”:”ja”}’>

To view this video please enable JavaScript, and consider upgrading to a web browser that supports HTML5 video

    コメントの追加

    </form>

    <p id=”summary”>読み込み中…</p>

    </article>

    </div>

    <footer> <a href=”http://www.windowsazure.com/en-us/develop/mobile/”&gt; Learn more about Microsoft Azure Mobile Services </a>

    <ul id=”errorlog”>

    </ul>

    </footer>

    </div>

    https://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.9.1.min.js

    http://ajax.aspnetcdn.com/ajax/mobileservices/MobileServices.Web-1.2.5.min.js

    http://page.js

    <!–

    アプリケーションに関するエンド ユーザーの利用状況分析を収集するには、

    追跡する各ページに以下のスクリプトを挿入します。

    このコードを、終了 </head> タグの直前と、

    andその他のすべてのスクリプトの前に配置します。最初のデータが数秒後に

    自動的に表示されます。

    –>

    var appInsights=window.appInsights||function(config){

    function r(config){t[config]=function(){var i=arguments;t.queue.push(function(){t[config].apply(t,i)})}}var t={config:config},u=document,e=window,o=”script”,s=u.createElement(o),i,f;for(s.src=config.url||”//az416426.vo.msecnd.net/scripts/a/ai.0.js”,u.getElementsByTagName(o)[0].parentNode.appendChild(s),t.cookie=u.cookie,t.queue=[],i=[“Event”,”Exception”,”Metric”,”PageView”,”Trace”];i.length;)r(“track”+i.pop());return r(“setAuthenticatedUserContext”),r(“clearAuthenticatedUserContext”),config.disableExceptionTracking||(i=”onerror”,r(“_”+i),f=e[i],e[i]=function(config,r,u,e,o){var s=f&&f(config,r,u,e,o);return s!==!0&&t[“_”+i](config,r,u,e,o),s}),t

    }({

    instrumentationKey:”fa12e109-658e-4b57-b60e-76d064e7a878”

    });

    window.appInsights=appInsights;

    appInsights.trackPageView();

    </body>

    </html>

    ———————————————————————————————-

    1. Azure Web Appの作成

    作成した、HTMLファイルをホスティングします。
    方法はいくつかありますが、ここではFTPアップロードの手順と、Visual Studio “Monaco”の方法を提示します。

    FTP upload:
    https://daiyuhatakeyama.wordpress.com/2013/11/25/windows-azure-website-%e3%81%b8%e3%81%aephp%e3%82%a2%e3%83%97%e3%83%aa%e3%82%b1%e3%83%bc%e3%82%b7%e3%83%a7%e3%83%b3%e4%bd%9c%e6%88%90%e6%89%8b%e9%a0%86/

    [de:code 2014] Visual Studio Online “Monaco” の全貌 ~ あのエリック・ガンマが作った最新開発環境のすべて ~

    https://channel9.msdn.com/events/de-code/2014/TL-009

    さて、ここまで来ると視聴ページができて、Mobileサービスを使った投稿の動作確認もできていると思います。

    よくある問題:

    ・Mobile Servicesで投稿ができない

    CROSの設定をしてください。具体的には、Azure Web Appでページホスティングをしていますので、「*.azurewebsite.net 」の様に指定をします。

    1. Azure Media Servicesでのライブ配信確認

    収録システムで、実際にライブ配信ができているか、確認を行います。
    先のAzure Media Servicesでのチャネル作成の手順の最後でも良いですし、以下も参考にしてください。

    https://daiyuhatakeyama.wordpress.com/2014/09/11/azure-media-services-live-streaming-%e3%81%aa%e3%81%a9%e3%81%8cpublic-preview%e3%81%ab%e3%81%aa%e3%82%8a%e3%81%be%e3%81%97%e3%81%9f/

    無事に映像が出ていれば、OKです。

    当日朝の作業

    1. Azure Web App、Mobile App、SQL Databaseのキャパシティを本番用に。

    いずれも、「無料」モードですと、アクセスできる数に上限があります。スケーリング設定を行いましょう。

    Azure Web App、Mobile App:

    https://azure.microsoft.com/ja-jp/documentation/articles/web-sites-scale/

    Webの高速化には、Redis Cacheも併用を。今回の規模では不要だと思います。

    https://azure.microsoft.com/ja-jp/documentation/services/redis-cache/

    SQL Database:
    https://azure.microsoft.com/ja-jp/documentation/articles/sql-database-scale-up/

    データ量も、同時書き込みも多くなる場合には、こちらをご参考にしてください。
    Azure SQL データベースのパフォーマンス ガイダンス: https://msdn.microsoft.com/library/azure/dn369873.aspx

    1. Azure Media Servicesの本番設定

    Streaming Unitの数を2以上にし (念のため、です)、Streaming Unit上でのCDNを有効化します。設定完了に90分はかかりますので、前日には設定完了している事が望ましいです。
    https://azure.microsoft.com/ja-jp/documentation/articles/media-services-manage-origins/#enable_cdn

    実際のライブ配信時には、手順の指さし確認が大事です。以下大まかなものですが、ご参考にしてください。

    Azure Media Servicesを使ったライブ配信ご参考:

    < https://channel9.msdn.com/Events/de-code/decode-2015/DEV-014>

    サンプルコード

    ここまでお読みいただけるとご理解いただけると思いますが、大したものはありません…

    https://github.com/dahatake/Azure-Media-Services-Samples

    今後について

    今回は手順をドキュメントとしてご紹介しました。これが、何度か実際に行えて手順としての妥当性確認が終わると、今度は「自動化」という事につながります。現在、Azureのインフラは、Azure Resource Managerベースに置き換えられていっていますが、Azure Mobile App、Azure Media Services、Application Insightがその対応を終えると、この手順はテンプレートから実施、という道が見えてきます。パラメーターセットを都度行うだけですね。

    お時間あれば、ご一読ください。

    Azure Resource Managerの概要: https://azure.microsoft.com/ja-jp/documentation/articles/resource-group-overview/

    Azure Resource Managerの本質とhow: https://docs.com/user313939/1c4aec6f-3d43-48e5-b839-51f4f6124155/azure-resource-manager-how

    Apple ProRes のサポート

    Azure Media Servicesのエンコーダー (厳密にはトランスコーダーですが)で、サービス開始当初からご要望があった、Apple ProResがエンコード対象となりました。Media Encoder Standardでのサポートとなります。つまり、通常料金の中で、配信用のファイルを作成できます。

    Announcing support for Apple ProRes videos in Azure Media Services (英語):

    http://azure.microsoft.com/en-us/blog/announcing-support-for-apple-prores-videos-in-azure-media-services/

    Media Encoder Standardは、実に多くのファイルをサポートするようになりました。

    Media Encoder Standard Formats and Codecs (英語):

    https://azure.microsoft.com/en-us/documentation/articles/media-services-media-encoder-standard-formats/

    どうぞ、皆さんのお手持ちのビデオファイルで検証ください。

    Media Encoder Standardを使用したエンコード:

    https://azure.microsoft.com/ja-jp/documentation/articles/media-services-dotnet-encode-with-media-encoder-standard/

    ファイル数が少ない場合はAzure Media Services Explorerが便利です。

    https://github.com/Azure/Azure-Media-Services-Explorer

    Azure Media Services のサンプルコード

    しばらくBlog更新できてなくてすいません。

    手持ちの簡単なサンプルコードを今後公開していきます。そのままお客様内のシステムに組み込めるものではないのですが、お試しという意味では使えます。

    Github: Azure Media Services サンプルコード:

    https://github.com/dahatake/Azure-Media-Services-Samples

    技術検証時に、バックエンドのワークフロー化は不要、ということであれば、素直にAzure Media Services Explorerツールをご利用ください。こちらは、REST APIのほぼ全ての機能が非常にタイムリーに実装されています。Open Sourceで製品ではない点だけご了承をいただければと思います。

    Azure Media Services Explorer:

    https://github.com/Azure/Azure-Media-Services-Explorer

    「.NETだけじゃない」と思われると思います。

    もちろん、時間のある限り、Java/PHP版なども公開していきます。多くなりすぎないよう・・・

    Azureのチュートリアル、自習書ですが、azure.comの中の [ドキュメント] にかなり揃っています。合わせてご利用ください。

    遂に来た! Azure Media ServicesとAzure CDN 連携

    先日以下のBlogで、アナウンスがありましたが、Azure Media ServicesとAzure CDNの統合が出てきました。

    Microsoft Azure enabling business transformation with updated search and NoSQL data services, encoders for Media Services and more:
    http://azure.microsoft.com/blog/2015/03/05/microsoft-azure-enabling-business-transformation-with-updated-search-and-nosql-data-services-encoders-for-media-services-and-more/

    以下が、Azure Media Servicesの製品サイトでのものになります。

    Azure CDN: February 2015 Release:
    http://azure.microsoft.com/en-us/documentation/articles/media-services-release-notes/#february_changes_15

     

    Azure CDNには以下のメリットがあります。

    • 大規模: 同じ映像(ファイル)へのリクエストは、CDN内でキャッシュされ、CDNより返信。つまり、オリジンであるAzure Media Services側にリクエストが来ません
    • 国を超える: 全世界にあるCDNノードへファイルは複製されます。クライアントは一番近いノードにアクセスをします。

     

    Azure CDN:
    http://azure.microsoft.com/ja-jp/services/cdn/

     

    幾つかのポイントを

    • 執筆時(3月9日)では、Japan Westで、この機能を体験できます! Japan Eastはまだです。
    • Azure CDNは、Azure Media Servicesのストリーミングエンドポイントに設定します。つまり、VoDもLiveも同じ扱いです。
    • Azure CDNを設定するには、ストリーミングユニットを「1以上」にします。プレミアムモードですね。つまり課金されます。
    • Azure管理ポータルのAzure CDNを作成する画面には、Azure Media Serviceは出てきません。新しいポータルにも出てきません。

     

    ここでは、その手順をご紹介します。

    1. Azure Media Servicesのアカウントで[ストリーミング エンドポイント] に移動します。

      「CDNを有効にする」のコマンドが画面下にあるのが確認できます。

    2. ストリーミングエンドポイントの「→」をクリックして、設定画面に移動します。
    3. [ストリーミング容量]の[ストリーミングエンドポイント]を「1」以上にして、[保存]を押します。数分で処理が有効化されます。
    4. 処理が完了したら、大きな左矢印をクリックして、前の画面に戻ります。
    5. CDN設定を変更するために、一旦ストリーミングエンドポイントを止めます。この間、サービス停止になりますので、ご注意ください。
      画面下の[停止]を押します。

    6. ストリーミングエンドポイントが停止していると、画面下の「CDNを有効にする」が押せるようになります。ここを押します。この処理はすぐに終わります。
    7. [開始]ボタンを押して、ストリーミングエンドポイントを開始させます。
      ここは10-20分くらい時間がかかるようです。実際の設定までは90分待ってください。60分ではないので、ご注意ください。
    8. 完了しても、味気ない状態です。
      ですが、nslookupで確認すると、確かにAzure CDN連携しているものと、そうでないものとで、CNAMEが別なのが確認できます。

     

    通常は、CDN設定を行うと、Player側は、CDNのURLを指定します。ですが、Azure Media Servicesの場合は連携がされているので、CDN設定しようが、しまいが、同じURLというのが面白いところです。
    是非、皆さんの配信にもCDNのパワーを付与してください。

    非公式: LiveShell.ProからAzure Media Servicesへライブ配信

    Azure Media Servicesのライブ機能では、RTMPエンコーダーからの配信ができます。
    ここでは、Cerevoさんから出ているコンパクトかつパワフルなハードウェアエンコーダーである「LiveShell.Pro」からAzure Media Servicesへのライブ配信の手順をまとめてみます。

    Cerevoさん: LiveShell.Pro 製品サイト

    http://static-shell.cerevo.com/pro/ja/product.html

    LiveShell.Proの興味深い機能は以下です。

    • 持ち運びが容易な720pでの長時間の安定配信
      • 720pのNote PCでの安定稼働には、それなりのスペックが必要
    • HDMI入力
      • 絵と音がずれることが激減!
    • Ethernet / Wireless ネットワークへの直接接続
      • これによって、Azureへ直接接続
    • 設定用のWeb管理画面
      • 長い文字入力の手間が減る

     

    ご注意点

    • このドキュメントの構成は、配線も1つですし、今回はWifiルーターで接続をしていますので、大事なライブ配信で使うには力不足です。
      ですが、拡充していけば、大型イベントなどでもご利用いただけると思います。LiveShell.ProもAzureも冗長化するのに、それほど大きな投資にはならないと思いますので。
    • Cerevoさんから「これで動きます!サポートもします!」とお言葉を頂いたわけではないので、「非公式」と冠をつけております。

     

    システム構成

    全体構成は以下となります。

    Azure Media Servicesの用語 (上記の図)

    • チャネル
      • Azure側での、エンコーダーからのストリーミングデータの受け取りを行う
      • 映像のプレビュー機能
      • “実行”状態時のみ、課金される
      • オンプレミスのエンコーダーから設定を変更した場合は「リセット」を推奨。
        リセットを行うと、プログラムも再作成が必要
    • プログラム
      • Azure側で、ストリーミングの外部への公開と、Azure内でのBlobストレージへの保存を行う
      • プログラムの開始/終了で、ライブ配信の開始/終了のタイミングを制御

    この図では、CDNが入っていませんが、Azure CDNも近いうちに連携して使えるようになります。

    この構成では、セミナーでのPCスクリーンアウトをキャプチャすることを想定して、PCの出力を、LiveShell.Proの出力に直接つないでいます。
    セミナーでの配信の場合は、PCの「画面の絵」と「音声」を以下の2つには出力したいと思います。

    • プロジェクター: こちらがメインですね。
    • ライブ配信先: こちらは補助的です。

    その場合は、「分配器」をPCとLiveShell.Proの間に入れることで、実現ができると思います (まだ試していませんが…)。

     

    事前準備

     

    配信手順

    PC周辺の配線

    あくまでイメージです。

    PCから出ているケーブル

    DisplayLink社のドライバーが入っているUSBからのモニター出力のケーブルになります。HDMIは、絵と音を1つのケーブルで出力してくれますから、これでPCの絵と音を送出できます。これは簡単ですね!
    ただし、ほとんどのPCにはDisplayLink社のドライバーが入っていないと思いますので、公式ドライバーをインストールしてください。
    http://www.displaylink.com/support/downloads.php

     

    エンコーダー

    灰色の小型ハードウェアがLiveShell.Proになります。その上にあるのはWifiルーターです。今回は、LiveShell.Proから、Wifiルーターに無線で飛ばし、それをWifiルーターの4GネットワークでAzureに接続をしています。

    ある一定以上のネットワークを配信用に確保するのは、本当に難しいです。有線LANでの接続を推奨します。LiveShell.Proの設定も有線LANの方が簡単です。
    無線の場合は、他の無線や3G/4G網と混線しないように、5Ghz対の利用などの工夫が必要になる場合もあると思います。

     

    PCの設定

    PCのマイクの音を送るために、PCのサウンド設定を行います。

    ここでは、PC音声の再生の出力先を、DisplayLinkのHDMIアダプターにします。

    「マイク」の設定を変更します。
    ここでは、PCのマイクを選択して[プロパティ]をクリックします。

     

    これで、PCの絵と音が、HDMIアダプターに流れていきます。

    セミナーなどではキーボードのタイプ音も入っちゃいますし、演台から人が移動してしまうと、聞きづらくなると思います。マイクの音が取れるとベストですが・・・

     

    LiveShell.Proアカウントのセットアップ

    Cerevoさんの方で、マニュアルを用意されています。以下を注意深く参照して、セットアップを行ってください。

    LiveShell.Pro マニュアル:

    http://shellprodoc-ja.cerevo.com/home

    主なご注意点:

    • LiveShell.Proのインターネット接続ですが、Proxy設定が必要だったり、そこにWeb認証設定が必要だったりすると、うまくいきません。
      http://shellprodoc-ja.cerevo.com/home/2
      • 有線LAN設定を行う場合、LiveShell.Proと、LiveShell.ProのDashboardアカウントのひも付けを「PIN」にて行います。ですが、LiveShell.Proがインターネット接続できないと、この「PIN」が表示されずセットアップが先に進みません。
      • 無線LAN設定を行う場合は、PCからのマイクアウトで行いますが、業務PCのマイクはミュートになっている場合が多いです。この瞬間は音声を出すことをお忘れなく。
    • Azure Media ServicesはLiveShell.Proの標準サービスではありません。そのためドキュメント内では「その他の配信サービス」という項目に読み替えて設定を行います。
      RTMPサーバーのURLが必要になる事もあります。その場合は、Azure Media Servicesのチャネルの作成を先に行ってください。
    • 3G\4Gや無線での視聴環境を考慮すると、複数のBitrateのデータを使うAdaptive Bitrate Streamingの利用をお勧めしています。LiveShell.Proからは、単一のビットレートのデータ配信しかできませんので、結果としてAzureからも単一ビットレートでの配信となります。

     

    Azure Media Servicesへの配信

    LiveShell.Proの設定が終わると、以下の様なLiveShell.ProのDashboardにリモートからログインして、各種設定がWebブラウザーを使って行えます。

    LiveShell.Proは、設定したRTMPサーバーへの接続を何度も試みてくれます。先の画面では[Others] と出ている先のURLが、Azure Media Servicesのチャネルの[取り込み用URL]になります。

     

    1. LiveShell.Proでの配信設定

    Azure Media ServicesにRTMP配信する際には、事前定義のプリセットではマルチデバイスに正しく配信されませんので画面右上の [CUSTOM]から、配信設定を変更します。

     

    • 「iフレーム挿入間隔」を2秒に1度にすることが推奨されます。
      http://blogs.msdn.com/b/windowsazurej/archive/2014/10/09/blog-azure-media-services-rtmp-support-and-live-encoders.aspx
    • H.264の[プロファイル]ですが、配信先のスマートフォンのバージョンが古い場合は、「High」プロファイルに対応していないものもあります。そのため「Main」に変更をしています。
    • [平均ビットレート]は、エンコーダーからの回線の状況や、配信対象のデバイスを考慮して適時変更してください。幾つかネットワークのアップストリーム帯域を確認するツール、Webサイトがありますから、それらで確認する事をお勧めします。
      また、スマートフォンに常時2Mbpsの映像を流し続けますと・・・あっという間に1ヶ月のパケット利用量を消費してしまう可能性がありますので、3G/4Gのネットワークで視聴をしてもらう際には、配信側で低めに設定するのが良いと思います。

     

    以下、今回のLiveShell.Proのエンコード設定です。

     

    これで、Azure側へ送る準備が出来ました。

     

    1. チャネルの作成

    Azure Media Servicesにチャネルを作成します。

    1. Azure Media Servicesの画面の中で[チャネル]タブをクリックします。
    2. [新しいチャネルの追加]をクリックします。

    1. 新しいチャネルのパラメーターを設定して、画面右下のチェックをクリックします。
      ここで重要な事は [ビデオの取り込みをコンピューターの現在のIPアドレスに制限する]のチェックボックスを外す事です。LiveShell.Proから配信しますので・・・

       

    2. 数分でチャネルが作成されます。上記設定では「開始」も同時に行っていますので、状態が[開始中] -> [準備完了]となったら配信準備が完了です。
      チャネルが作成されると、「取り込みURL」が作成されます。これが、LiveShell.Proの「配信先URL」になります。

       

    3. LiveShell.Proの配信先URLの設定

    4. LiveShell.ProのDashboardに戻り、画面右上の[設定]を押します。
    5. 画面右下の[変更]を押します。

    6. [配信先URL]に、Azure Media Servicesのチャネルの[取り込みURL]を設定します。

       

      LiveShell.Proで配信を開始していない場合は、[配信開始]を押します。

       

      配信が始まると…

    • LiveShell.Proの画面は、[RTMP用の閲覧用URLを設定して視聴してください]という表示がされます。
      Azure Media ServicesからRTMP配信はできませんので、このままにしてください。

    • LiveShell.Proのハードウェアのコンソールは、配信ビットレートをリアルタイムで表示してくれます。

    • Azure Media Servicesの管理画面では、プレビューの映像が確認できます。

       

       

      これで、Azureに正しく映像が届いていることが確認できます。

      ただ、この時点では「本番」に配信はされていません。

     

    1. 本番に配信をする

    といっても、手順は一つです。

    1. Azure管理画面の[ストリーミングの開始]を押す

      この場合は、1時間分の映像と音声がAzure上に保存されます。ライブ配信中に1時間分は過去に戻ることができます。内部では「プログラム」が作成されています。このプログラムの時間は5分から25時間まで設定できます。
      個別設定をする場合は、チャネルの名前の「→」をクリックします。

      そうしますと、プログラムの状況を確認いただけます。

      チャネル、プログラム双方ともに「開始」中の状態のものを作成できる上限値が決まっています。
      執筆時点では、以下の通りです。

    • チャネルは5つ。
    • プログラムは3つ。(作成自身は50できますが)

    http://azure.microsoft.com/ja-jp/documentation/articles/media-services-quotas-and-limitations/

    1. Playerで動作確認をする

      [発行されたURL]は、Smooth Streaming用のものです。
      Azure Media Servicesには、MPEG-DASH / HLS などの様々な配信プロトコルに動的に対応できるDynamic Packagingという機能があります。URL文字列の最後に 「(format=xxx)」を付与するだけで、プロトコル変換をしてくれます。

      https://msdn.microsoft.com/ja-jp/library/jj889436.aspx

       

      例えば( format=mpd-time-csf) という文字列で、MPEG-DASHへ変換をしてくれますので、dashif.orgの以下のサイトでも視聴ができます。

       

      http://dashif.org/reference/players/javascript/index.html

       

    Azure Media Servicesのチャネルでは、以下の場合「リセット」が必要になります。

    • 配信設定を変更した場合: ビットレート、フレームレートなど

    RTMPエンコーダーからの接続が切れても、一定の時間以上は待ってくれます。ですので、LiveShell.Proが再接続をしてくると自動的に配信を開始してくれます。

     

    まとめ

    Azure Media Servicesでは、Smooth StreamingとRTMP対応のエンコーダーと連携して配信が出来ます。プロフェッショナルで使う大型のものから、PCベースでのソフトウェアエンコーダー。そして、今回ご紹介したLiveShell.Proの様にモバイル性の高いものまで幅広いです。
    今後も機能強化が予定されていますので、皆さんのライブ配信を更に良いものに出来ればと思います。

    Wirecast v6にMicrosoft Azure Media Services 用のプリセット追加

    Azure Media ServicesのLive配信 (現在public preview)で、RTMPがサポートされています。その中でTelestream社のWirecastとのパートナーシップがアナウンスされていました。
    これまでのWirecastでは、Azure Media ServicesのRTMP取り込みのための設定変更が必要でした。

     

    先日公開された、Wirecast 6から、設定済みのものがプリセットとして追加されています。初期設定では、配信先として表示されませんので、ご注意ください。

     

    • 出力設定の中で[More]を押します。

    ありましたね!

    これで、配信先に「Microsoft Azure Media Services」が表示されます。

     

    設定内容は、以下の様になっています。
    Addressに、Azure Media Servicesの「取り込みURL」を設定してください。

    エンコーディング設定で幾つか定義済みのものがあります。

     

    これで、マルチビットレートの設定も簡単です。

     

    Telestream Wirecast:

    http://www.telestream.net/wirecast/overview.htm

     

    是非、お試しください。

    2つのAzure Media Services のエンコーダー

    2014/10/1から、Azure Media Encoderの料金が新しくなりました。エンコード後のファイルサイズのみが課金対象となっています。

     

    Azure Media Service 価格表 : http://azure.microsoft.com/ja-jp/pricing/details/media-services/

     

    この「エンコーダー」が何を意味するかといえば、Azure Media Encoderです。
    従来は、Windows Azure Media Encoderという名称でした。Windows Azure Media Encoderは、2015年9月15日までの提供となります。

    Azure Media Encoder Windows Azure Media Encoder
    Version 4.0 2.3, 3.12
    課金対象サイズ 出力のみ 入力 + 出力

     

    執筆時点、Azure Media ServicesのMedia Processorには、以下の種類とバージョンがあります。

     

    上記の確認用のサンプルコードです。

    ——————————————————————
    var context = new CloudMediaContext(

    “<Azure Media Account Name>”,

    “<Azure Media Account Key>”

    );

     

    foreach (var item in context.MediaProcessors)

    {

    Console.WriteLine(“{0}: {1}”,

    item.Name,

    item.Version);

    }

     

    Console.WriteLine(“リストアップ完了しました。Enter Keyを押してください。”);

    Console.ReadLine();

    ——————————————————————

    新しいエンコーダーを使うためには、Azure Media Processorの指定文字列の変更をお願いします。

     

    Windows Azure Media Services .NET Extensionsに含まれている、MediaProcessorNames 列挙子には、まだ反映されていませんので、ご注意ください。

     

    ご参考: http://azure.microsoft.com/blog/2014/10/01/lower-your-encoding-costs-with-azure-media-encoder/

    Azure Media Indexer と Microsoft Translator を使って、英語の動画に、日本語字幕を付ける!!

    IT関連の最新情報は、どうしても英語のものが多いですよね。英語に行くと、有償セッションのビデオ動画があったりするのですが、日本語のものはどうしても人が翻訳して、映像のシーンを指定して字幕を付けるので、どうしても時間とお金がかかります。結果としては、多くの情報は日本語になりません。
    また、日本語と英語、くらいの数の翻訳であればまだいいのですが、フランス語、ドイツ語など増やそうと思ったら大変です。
    Azure Media Servicesがそのお手伝いをします。

    9月のアップデートの中に、Azure Media Indexerという機能が追加され、サービスインをしました。
    動画の中の主に話している「声」を抽出して、テキストのファイルにしてくれます。しかもそのテキストのファイルは、業界標準の字幕のファイルフォーマットそのままだったりしますので、簡単に字幕付きのビデオプレイヤーを作成できるのです。TTMLの場合は、声と時間が紐づいていますから、動画を扱う上では大変相性が良いです。

    Timed Text Markup Language (TTML):
    http://en.wikipedia.org/wiki/Timed_text#Markup_language_specifications

     

     

    このサンプルを実行した結果は、このサイトで体験いただけます。

    http://dahatakettml.azureedge.net/

    ※ このサイトは未来永劫動いているわけではありませんので、ご注意ください…

     

    出力ファイル

    • 字幕:        TTML or SAMI
    • 音声検索:     SQL Serverのフルテキストサーチ用
    • キーワード:     ビデオの中でのもの

    以下、執筆時点の注意点です。

    ここでは、TTMLに焦点をあて、ブラウザーベースのHTML5 ビデオプレイヤーを作成します。
    実は、TTMLとHTML5 videoタグは大変相性が良く、videoタグの中のtrackタグで、ファイルをそのまま使えるのです!!!

     

    Track ElementのW3C標準化の状況:
    http://status.modern.ie/trackelement?term=track


    IE10以降ですね。今すぐ最新のIE11にしましょう!

     

    1. 作成手順:

    以下のフローとなります。

    • 英語のmp4ファイルを準備する
    • Azure Media Indexerにてttml作成
    • Microsoft Translatorにて、英語のttmlを日本語に
    • HTML ページにて、全て参照
    1. 事前準備

     

    1. Microsoft Translatorの契約

    Microsoft Azure MarkeplacetからAPI利用をします。

    Getting Started with Microsoft Translator:
    http://msdn.microsoft.com/en-us/library/hh454949.aspx

    1. Microsoft Azure MarketPlaceのサイトに行き、サインインをします。

      https://datamarket.azure.com/home/

      初めてサインインした場合は、登録画面になりますので、適切な情報を入力し、登録してください。

       

    2. Microsoft Translatorを検索します。画面右上の検索ボックスに”Translator“などと入力して検索してください。

      Microsoft Translatorが表示されます。

       

    3. 契約メニューを選択します。

      Microsoft Translatorは、翻訳文字数に応じて、課金が必要になります。
      ここでは、[無償]のものを選択します。


      ※ 上記画面は、契約済みの場合です。

       

    1. 開発者用キーを作成します。

      Microsoft Azure Marketplace経由でアプリケーション呼び出しをする際には、Client IDClient Secretの2つをもって認証を行います。
      ここでは、それを作成します。

      画面上部の[マイアカウント]を選択して、その後、画面左側に表示されるメニューから[開発者]を選択します。

    2. [開発者]の画面にて、一番下の[登録] を押します。

      1. アプリケーションの情報を入力して、[作成]ボタンを押してキーの発行を行います。

        この情報を使ってAPI呼び出しを行います。
        こちらは「例」です。

         

      2. 登録が完了すると、Microsoft Translator は[マイ データ]に分類されます。

         

    3. Azure Media Indexerによるテキストメタデータの抽出

    現在Azure Media Indexerを使うにはAPIを使用する必要があります。
    ここでは、C#の例を見ていきましょう。

    事前準備:

    Azure Media Indexer設定ファイルの例です。

    [indexing.config]

    —————————————————————————————-

    <!–?xml version=”1.0″ encoding=”utf-8″ ?>

    <configuration version=”2.0″>

    <input>

    <!– [Optional] [Recommended] Metadata of the input media file(s) –>

    <metadata key=”title” value=”TechEd 2014 Key Note” />

    <metadata key=”description” value=”So much FAN video.” />

    </input>

    <settings>

    <!– Reserved –>

    </settings>

    </configuration>

    —————————————————————————————-

     

    Task Preset for Azure Media Indexer:
    http://msdn.microsoft.com/en-us/library/dn783454.aspx

     

    1. プログラム作成

    通常のVoDのエンコード処理と変わりません。

    Visual Studio で、C#の[コンソール アプリケーション]のプロジェクトを作成します。
    その後、NuGetパッケージにて、[Windows Azure Media Services .NET SDK Extensions] をインストールしてください。

     

    Visual Studio のプロジェクト内は以下の通りです。

    主要ファイルになります。

    • BingTranslatorSvc.cs:    Microsoft Translatorとやり取りするクラスです。
    • Indexing.config:        Azure Media Indexer の設定ファイルです (上述)。
    • Program.cs:        メイン処理です。

     

    メインとなる、Program.csの中から順にみていきましょう。

    名前空間

    ———————————————————————
    using System;

    using System.Configuration;

    using System.Collections.Generic;

    using System.Linq;

    using System.IO;

    using System.Net;

    using System.Text;

    using System.Threading.Tasks;

    using System.Diagnostics;

    using System.Xml;

    using System.Xml.Linq;

     

    using Microsoft.WindowsAzure.MediaServices.Client;
    ———————————————————————

    System.Configurationが初期設定では参照されていませんので、[参照設定] を右クリックして出てくるポップアップメニューから[参照の追加]を押して、”System.Configuration” を追加してください。

     

     

    クラス変数

    app.config内からから取得しているものばかりです。

    ————————————–
    private static string TranslatorClientID = ConfigurationManager.AppSettings[“TranslatorClientID”];

    private static string TranslatorClientSecret = ConfigurationManager.AppSettings[“TranslatorClientSecret”];

    private static string uploadFile = ConfigurationManager.AppSettings[“uploadfile”];

    ————————————–

     

    [app.config] の一部

    —————————————-
    <!–?xml version=”1.0″ encoding=”utf-8″?>

    <configuration>

    <appSettings>

    TranslatorClientID” value=”” />

    TranslatorClientSecret” value=”” />

    accountName” value=”” />

    accountKey” value=”” />

    uploadfile” value=”C:\Users\dahatake\Desktop\KEY002.mp4″ />

    </appSettings>

    ————————————–

     

    Azure Media Services 接続

    ————————————–
    var context = new CloudMediaContext(

    ConfigurationManager.AppSettings[“accountName”],

    ConfigurationManager.AppSettings[“accountKey”]

    );

    —————————————

    Azure Media Servicesへの接続情報は、Azure管理画面より取得ください。

     

    ファイルのアップロード
    —————————————————-
    var asset = context.Assets.CreateFromFile(

    uploadFile,

    AssetCreationOptions.None,

    (a, p) =>

    {

    Console.WriteLine(” 経過 {0}%”, p.Progress);

    });

    —————————————————-
    これは説明不要かと。

     

    ジョブ実行

    ここでIndexingのジョブを実行します。といっても、Media Processorとして”Azure Media Indexer”の指定をして、先ほどの設定ファイルの内容を文字列として渡すだけです。

    —————————————————–
    // 1. ジョブ作成

    var configuration = File.ReadAllText(“indexing.config”);

     

    var job = context.Jobs.CreateWithSingleTask(

    “Azure Media Indexer”,

    configuration,

    asset,

    asset.Name + “-Indexed”,

    AssetCreationOptions.None);

     

    // 2. ジョブ実行.

    job.Submit();

    job = job.StartExecutionProgressTask(

    j =>

    {

    Console.WriteLine(” 状態: {0}”, j.State);

    Console.WriteLine(” 経過: {0:0.##}%”, j.GetOverallProgress());

    },

    System.Threading.CancellationToken.None).Result;

    var outputAsset = job.OutputMediaAssets.FirstOrDefault();

    ————————————————————————-

     

    動画配信ポイント作成

    元ファイルがmp4ファイルの場合は、そのままHTML5ビデオにプログレッシブダウンロード方式にて配信ができます。ここでは、アップロードしたファイルをそのまま配信に使います。

    ————————————————————————–

    context.Locators.CreateLocator(

    LocatorType.Sas,

    asset,

    context.AccessPolicies.Create(

    “Streaming Access Policy”,

    TimeSpan.FromDays(7), //7日間のみ公開

    AccessPermissions.Read)

    );

    ————————————————————————–

     

    ファイルのダウンロード

    サンプルという事もあり、作成されたファイルを全てダウンロードして、デスクトップに保存します。
    毎回これが必要というわけではありません。

     

    ————————————————————————–
    var TTMLFile = “”;

    foreach (IAssetFile file in outputAsset.AssetFiles)

    {

    Console.WriteLine(” ファイルダウンロード中: {0}”, file.Name);

    file.Download(Environment.GetEnvironmentVariable(“USERPROFILE”) +

    @”\Desktop\” +

    file.Name);

     

    // ttml は翻訳対象

    if (file.Name.EndsWith(“.ttml”))

    {

    TTMLFile = Environment.GetEnvironmentVariable(“USERPROFILE”)

    + @”\Desktop\”

    + file.Name;

    }

    }

    ————————————————————————–

     

    ここで、実際にAzure Media Indexerによって作成されたttmlファイルの内容をみましょう。

    [KEY002.mp4.ttml] の一部

    ————————————————————————-
    <!–?xml version=”1.0″ encoding=”utf-8″?>

    xml:lang=”en-us” xmlns=”http://www.w3.org/ns/ttml&#8221; xmlns:tts=”http://www.w3.org/ns/ttml#styling&#8221; xmlns:ttm=”http://www.w3.org/ns/ttml#metadata”&gt;

    <head>

    <metadata>

    <ttm:title>Media.wvx.aib

    <ttm:copyright>Copyright (c) 2013 Microsoft Corporation. All rights reserved.

    </metadata>

    <styling>

     

    </styling>

    <layout>

    xml:id=”CaptionArea” tts:origin=”0c 12.6c” tts:extent=”32c 2.4c” tts:backgroundColor=”rgba(0,0,0,160)” tts:displayAlign=”center” tts:padding=”0.3c 0.5c” />

    </layout>

    </head>

    <body region=”CaptionArea”>

    …welcome executive vice …zygote guthrie

    Good morning everyone and welcome …to …

    We live in a mobile first cloud first-world yesterday we

    ————————————————————————-

    •  タグに、抽出結果の文字列が入っています。
    • それぞれ”begin“と”end“があります。再生開始してからのその文字が話されていた時間、という意味です。

    Microsoft Translatorの呼び出し

    さて、この先で作成されたTTMLの英文を翻訳するわけですが、その為にMicrosoft Translatorを呼び出す処理を書いていきます。

    [BingTranslatorSvc.cs]

    ここでは全文を載せます。ちょっと長いですが…

    -----------------------------------------------------------------------------
    
    using System;
    
    using System.Collections.Generic;
    
    using System.Linq;
    
    using System.Text;
    
    using System.Net;
    
    using System.IO;
    
    using System.Runtime.Serialization.Json;
    
    using System.Runtime.Serialization;
    
    using System.Web;
    
    using System.ServiceModel.Channels;
    
    using System.ServiceModel;
    
    using System.Threading;
    
    namespace AzureMediaIndexer
    
    {
    
        // http://blogs.msdn.com/b/translation/p/gettingstarted1.aspx
    
        class BingTranalatorSvc
    
        {
    
            public string from    = "en";
    
            public string to    = "ja";
    
            // Azure MarketPlace と紐づけ
    				
            //Get Client Id and Client Secret from https://datamarket.azure.com/developer/applications/
    
            public string clientID        = "";
    
            public string clientSecret    = "";
    
            
    
            public string Translate(string text)
    
            {
    
                string result = "";
    
                // BingTranslator アクセス用のアクセストークンをAzure DataMarketから取得
    				
                var accessToken = new AdmAuthentication(clientID, clientSecret);
    
                
    
                string uri = "http://api.microsofttranslator.com/v2/Http.svc/Translate?text=" + System.Web.HttpUtility.UrlEncode(text) + "&from=" + from + "&to=" + to;
    
                string authToken = "Bearer " + accessToken.GetAccessToken().access_token;
    
                // Microsoft Translator呼び出し
    				
                HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(uri);
    
                httpWebRequest.Headers.Add("Authorization", authToken);
    
                // 結果取得
    				
                WebResponse response = null;
    
                response = httpWebRequest.GetResponse();
    
                using (Stream stream = response.GetResponseStream())
    
                {
    
                    System.Runtime.Serialization.DataContractSerializer dcs = new System.Runtime.Serialization.DataContractSerializer(Type.GetType("System.String"));
    
                    result = (string)dcs.ReadObject(stream);
    
                }
    
                return result;
    
            }
    
            // Refer obtaining AccessToken (http://msdn.microsoft.com/en-us/library/hh454950.aspx) 
    
            [DataContract]
    
            public class AdmAccessToken
    
            {
    
                [DataMember]
    
                public string access_token { get; set; }
    
                [DataMember]
    
                public string token_type { get; set; }
    
                [DataMember]
    
                public string expires_in { get; set; }
    
                [DataMember]
    
                public string scope { get; set; }
    
            }
    
            public class AdmAuthentication
    
            {
    
                public static readonly string DatamarketAccessUri = "https://datamarket.accesscontrol.windows.net/v2/OAuth2-13";
    
                private string clientId;
    
                private string clientSecret;
    
                private string request;
    
                private AdmAccessToken token;
    
                private Timer accessTokenRenewer;
    
                //Access token expires every 10 minutes. Renew it every 9 minutes only.
    
                private const int RefreshTokenDuration = 9;
    
                public AdmAuthentication(string clientId, string clientSecret)
    
                {
    
                    this.clientId = clientId;
    
                    this.clientSecret = clientSecret;
    
                    //If clientid or client secret has special characters, encode before sending request
    
                    this.request = string.Format("grant_type=client_credentials&client_id={0}&client_secret={1}&scope=http://api.microsofttranslator.com", HttpUtility.UrlEncode(clientId), HttpUtility.UrlEncode(clientSecret));
    
                    this.token = HttpPost(DatamarketAccessUri, this.request);
    
                    //renew the token every specfied minutes
    
                    accessTokenRenewer = new Timer(new TimerCallback(OnTokenExpiredCallback), this, TimeSpan.FromMinutes(RefreshTokenDuration), TimeSpan.FromMilliseconds(-1));
    
                }
    
                public AdmAccessToken GetAccessToken()
    
                {
    
                    return this.token;
    
                }
    
                private void RenewAccessToken()
    
                {
    
                    AdmAccessToken newAccessToken = HttpPost(DatamarketAccessUri, this.request);
    
                    //swap the new token with old one
    
                    //Note: the swap is thread unsafe
    
                    this.token = newAccessToken;
    
                }
    
                private void OnTokenExpiredCallback(object stateInfo)
    
                {
    
                    try
    
                    {
    
                        RenewAccessToken();
    
                    }
    
                    catch (Exception ex)
    
                    {
    
                        Console.WriteLine(string.Format("Failed renewing access token. Details: {0}", ex.Message));
    
                    }
    
                    finally
    
                    {
    
                        try
    
                        {
    
                            accessTokenRenewer.Change(TimeSpan.FromMinutes(RefreshTokenDuration), TimeSpan.FromMilliseconds(-1));
    
                        }
    
                        catch (Exception ex)
    
                        {
    
                            Console.WriteLine(string.Format("Failed to reschedule the timer to renew access token. Details: {0}", ex.Message));
    
                        }
    
                    }
    
                }
    
                private AdmAccessToken HttpPost(string DatamarketAccessUri, string requestDetails)
    
                {
    
                    //Prepare OAuth request 
    
                    WebRequest webRequest = WebRequest.Create(DatamarketAccessUri);
    
                    webRequest.ContentType = "application/x-www-form-urlencoded";
    
                    webRequest.Method = "POST";
    
                    byte[] bytes = Encoding.ASCII.GetBytes(requestDetails);
    
                    webRequest.ContentLength = bytes.Length;
    
                    using (Stream outputStream = webRequest.GetRequestStream())
    
                    {
    
                        outputStream.Write(bytes, 0, bytes.Length);
    
                    }
    
                    using (WebResponse webResponse = webRequest.GetResponse())
    
                    {
    
                        DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(AdmAccessToken));
    
                        //Get deserialized object from JSON stream
    
                        AdmAccessToken token = (AdmAccessToken)serializer.ReadObject(webResponse.GetResponseStream());
    
                        return token;
    
                    }
    
                }
    
                
    
            }
    
        }
    
    }
    					
    -----------------------------------------------------------------------------
    

    ポイントです。

    • アクセストークンを取得する必要があります。それを” AdmAuthentication” クラスの内部で行っています。
      • Obtaining an Access Token:
        http://msdn.microsoft.com/en-us/library/hh454950.aspx
      • アクセストークンは10分で期限が切れます。よって切れた場合のコールバック処理をしています。
      • アクセストークンはHTTP Headerの中で、以下の形で追記します。
        • Bearer xxxx

    ttmlから英文を切り出して、Microsoft Translatorを呼び出す

    せっかくですから一度に複数言語に翻訳してみます。ここでは、日本語とクリンゴン語ですね。

    ——————————————————————————-
    // Translator Language Codes:

    // http://msdn.microsoft.com/en-us/library/hh456380.aspx

    var langs = new string[]{

    “ja”,    //日本語

    “tlh”};    //クリンゴン語

    BingTranalatorSvc translator = new BingTranalatorSvc();

    translator.clientID = TranslatorClientID;

    translator.clientSecret = TranslatorClientSecret;

    int i = 0;

    ——————————————————————————-

    • Microsoft Azure Marketplace で作成した、Client IDとClient Secretを設定します。

    注: クリンゴン語は地球上には存在していません。Star Trekの中のとある種族の話している言語です。Microsoft Translatorは、クリンゴン語への機械翻訳をしてくれます!

    Microsoft Translatorによる機械翻訳呼び出し

    ——————————————————————————-

    foreach (var lang in langs)

    {

    var TTMLjp = XDocument.Load(TTMLFile);

    XNamespace ttmlns = “http://www.w3.org/ns/ttml&#8221;; //LINQ to XMLでクエリするためには、xmlnsの指定は必須

    var transTargets = from p in TTMLjp.Descendants(ttmlns + “p”)

    select p;

    translator.to = lang;

    foreach (var item in transTargets)

    {

    try

    {

    Console.WriteLine(” 機械翻訳: {0}:{1}/{2}”,

    lang,

    i,

    item.Value);

    item.SetValue(translator.Translate(item.Value));

    i++;

    }

    catch (WebException we)

    {

    ProcessWebException(we);

    break;

    }

    }

    TTMLjp.Save(TTMLFile.Replace(“.ttml”,

    string.Format(“.{0}.ttml”,lang)));

    Console.WriteLine(” 機械翻訳 完了”);

    Console.WriteLine(” 機械翻訳数: {0}:{1}/{2}”,

    lang,

    i,

    transTargets.Count());

    }

    ————————————————————-

    • LINQ to XMLにて、ttmlからタグの内容のみを抽出しています。

      • ttmlには、以下の名前空間が設定されていますので、XNamespace オブジェクトを設定しています。
      • LINQ構文が大変わかりやすいのがご理解いただけると思います。
    • 翻訳結果を、同じオブジェクトにセットしていますが、これでメモリー内のデータが上書きされます。
      • item.SetValue(translator.Translate(item.Value));
    • WebExceptionを拾っていますが、これはお勧めします。Microsoft Translatorのエラー詳細は、HTTP Responseに含まれていますので、その内容を読み取る必要があります。
      • ProcessWebExpressionはこんな感じです。

        ————————————————————————-
        private static void ProcessWebException(WebException e)

        {

        Console.WriteLine(“>>> Error: {0}”, e.ToString());

        // Obtain detailed error information

        string strResponse = string.Empty;

        using (HttpWebResponse response = (HttpWebResponse)e.Response)

        {

        using (Stream responseStream = response.GetResponseStream())

        {

        using (StreamReader sr = new StreamReader(responseStream, System.Text.Encoding.ASCII))

        {

        strResponse = sr.ReadToEnd();

        }

        }

        }

        Console.WriteLine(“>>> Http status code={0}, error message={1}”, e.Status, strResponse);

        }

        —————————————————————————

    これで完了です。

    以下、メイン部分のソースコード全文です。

    [Program.cs]

    このサンプルでは、それぞれの処理の実行時間を計測しています。

    ————————————————————————————————-

    using System;

    using System.Configuration;

    using System.Collections.Generic;

    using System.Linq;

    using System.IO;

    using System.Net;

    using System.Text;

    using System.Threading.Tasks;

    using System.Diagnostics;

    using System.Xml;

    using System.Xml.Linq;

    using Microsoft.WindowsAzure.MediaServices.Client;

    namespace AzureMediaIndexer

    {

    class Program

    {

    private static string TranslatorClientID = ConfigurationManager.AppSettings[“TranslatorClientID”];

    private static string TranslatorClientSecret = ConfigurationManager.AppSettings[“TranslatorClientSecret”];

    private static string uploadFile = ConfigurationManager.AppSettings[“uploadfile”];

    static void Main(string[] args)

    {

    // 処理時間の計測

    var totalSw = new Stopwatch();

    var sw = new Stopwatch();

    totalSw.Start();

    var context = new CloudMediaContext(

    ConfigurationManager.AppSettings[“accountName”],

    ConfigurationManager.AppSettings[“accountKey”]

    );

    Console.WriteLine(“*** 1. ファイルアップロード ***”);

    sw.Start();

    var asset = context.Assets.CreateFromFile(

    uploadFile,

    AssetCreationOptions.None,

    (a, p) =>

    {

    Console.WriteLine(” 経過 {0}%”, p.Progress);

    });

    sw.Stop();

    Console.WriteLine(” アップロード処理完了”);

    Console.WriteLine(” アップロード処理時間: {0}”, sw.Elapsed.ToString());

    Console.WriteLine(“*** 2. Indexing 実行 ***”);

    // 2.1. ジョブ作成

    var configuration = File.ReadAllText(“indexing.config”);

    var job = context.Jobs.CreateWithSingleTask(

    “Azure Media Indexer”,

    configuration,

    asset,

    asset.Name + “-Indexed”,

    AssetCreationOptions.None);

    sw.Reset();

    sw.Start();

    // 2.2. ジョブ実行.

    job.Submit();

    job = job.StartExecutionProgressTask(

    j =>

    {

    Console.WriteLine(” 状態: {0}”, j.State);

    Console.WriteLine(” 経過: {0:0.##}%”, j.GetOverallProgress());

    },

    System.Threading.CancellationToken.None).Result;

    sw.Stop();

    Console.WriteLine(” Indexing 完了”);

    Console.WriteLine(” Indexing 時間: {0}”, sw.Elapsed.ToString());

    var outputAsset = job.OutputMediaAssets.FirstOrDefault();

    Console.WriteLine(“***** 3. 配信ポイント作成 *****”);

    // Progressive Download

    context.Locators.CreateLocator(

    LocatorType.Sas,

    asset,

    context.AccessPolicies.Create(

    “Streaming Access Policy”,

    TimeSpan.FromDays(7),

    AccessPermissions.Read)

    );

    WriteToFile(String.Format(“{0}_SASURL.txt”,

    asset.Name),

    asset.AssetFiles.FirstOrDefault().GetSasUri().ToString());

    Console.WriteLine(“*** 4. ファイルダウンロード ***”);

    sw.Reset();

    sw.Start();

    var TTMLFile = “”;

    foreach (IAssetFile file in outputAsset.AssetFiles)

    {

    Console.WriteLine(” ファイルダウンロード中: {0}”, file.Name);

    file.Download(Environment.GetEnvironmentVariable(“USERPROFILE”) +

    @”\Desktop\” +

    file.Name);

    // ttml は翻訳対象

    if (file.Name.EndsWith(“.ttml”))

    {

    TTMLFile = Environment.GetEnvironmentVariable(“USERPROFILE”)

    + @”\Desktop\”

    + file.Name;

    }

    }

    Console.WriteLine(“*** 5. Bing Translator での ttml 機械翻訳 ***”);

    sw.Reset();

    sw.Start();

    // Translator Language Codes:

    // http://msdn.microsoft.com/en-us/library/hh456380.aspx

    var langs = new string[]{

    “ja”,    //日本語

    “tlh”};    //クリンゴン語

    BingTranalatorSvc translator = new BingTranalatorSvc();

    translator.clientID = TranslatorClientID;

    translator.clientSecret = TranslatorClientSecret;

    int i = 0;

    foreach (var lang in langs)

    {

    var TTMLjp = XDocument.Load(TTMLFile);

    XNamespace ttmlns = “http://www.w3.org/ns/ttml&#8221;; //LINQ to XMLでクエリするためには、xmlnsの指定は必須

    var transTargets = from p in TTMLjp.Descendants(ttmlns + “p”)

    select p;

    translator.to = lang;

    foreach (var item in transTargets)

    {

    try

    {

    Console.WriteLine(” 機械翻訳: {0}:{1}/{2}”,

    lang,

    i,

    item.Value);

    item.SetValue(translator.Translate(item.Value));

    i++;

    }

    catch (WebException we)

    {

    ProcessWebException(we);

    break;

    }

    }

    TTMLjp.Save(TTMLFile.Replace(“.ttml”,

    string.Format(“.{0}.ttml”,lang)));

    Console.WriteLine(” 機械翻訳 完了”);

    Console.WriteLine(” 機械翻訳数: {0}:{1}/{2}”,

    lang,

    i,

    transTargets.Count());

    }

    Console.WriteLine(” 機械翻訳時間: {0}”, sw.Elapsed.ToString());

    Console.WriteLine();

    Console.WriteLine(“全ての処理が終了しました。Indexing 結果がデスクトップに出力されていますので、ご確認ください。”);

    Console.WriteLine(“総処理時間: {0}”, totalSw.Elapsed.ToString());

    Console.WriteLine(“何かキーを押してください。”);

    Console.ReadLine();

    }

    ///

    /// Utility: 文字列のファイル出力

    ///

    /// outFileName”>

    /// fileContent”>

    static void WriteToFile(string outFileName, string fileContent)

    {

    System.IO.StreamWriter sr = System.IO.File.CreateText(

    Environment.GetEnvironmentVariable(“USERPROFILE”) +

    @”\Desktop\” +

    outFileName);

    sr.Write(fileContent);

    sr.Flush();

    sr.Close();

    }

    private static void ProcessWebException(WebException e)

    {

    Console.WriteLine(“>>> Error: {0}”, e.ToString());

    // Obtain detailed error information

    string strResponse = string.Empty;

    using (HttpWebResponse response = (HttpWebResponse)e.Response)

    {

    using (Stream responseStream = response.GetResponseStream())

    {

    using (StreamReader sr = new StreamReader(responseStream, System.Text.Encoding.ASCII))

    {

    strResponse = sr.ReadToEnd();

    }

    }

    }

    Console.WriteLine(“>>> Http status code={0}, error message={1}”, e.Status, strResponse);

    }

    }

    }

    ————————————————————————————————-

    プログラム実行

    早速Visual Studio から実行してみましょう。

    結構時間がかかりますね。

    実行結果の確認

    デスクトップに幾つかファイルが出力されています。

    このうち、”.ttml”を使用します。

    1. HTMLページ作成

    以下の様になります。

    [index.html]

    ———————————————————
    <!––>DOCTYPE html>

    Azure Media Indexer での字幕作成

    Segoe UI’, Tahoma, Geneva, Verdana, sans-serif; font-size: x-large;”>

    HTML5 Video + Track

    字幕: Azure Media Indexer と Bing Translator で自動生成

    ビデオプレイヤーの[CC]ボタンを押して、字幕の切り替えを試してください

    </body>

    </html>

    ————————————————————

    • Videoのsrcには、mp4ファイル向けに作成したSAS URLを指定しています。
    • trackタグは:
      • idは必須です
      • srcに.ttmlファイルを指定しています。ここでは、一緒にWeb Serverにアップロードして使います
      • label の部分がプレイヤーの字幕の表示文字列になります。
      • defaultと設定してあるものが、初期値で表示されます。

     

    1. Azure WebSiteの作成

    Azure WebSiteを作成して、ファイルをアップロードしましょう。

    Azureの管理画面で、[新規] – [Webサイト] – [簡易作成] から、以下を参考にURLとデータセンターの場所を選択します。

     

    10秒程度で本番サイトが使えるようになります。

    作成した、WebSiteを選択して、[構成] のタブに移動します。
    少し下にスクロールすると[VISUAL STUDIO ONLINEでの編集]という項目があります。これを「オン」にして、画面したの[保存]ボタンを押してください。

     

    設定が完了したら、[ダッシュボード]に戻ります。画面右側の[概要]の中に[Visual Studio Onlineでの編集]という項目が表示されます。これをクリックします。

     

    ブラウザーの中でコーディングが出来る、Visual Studio Online “Monaco”という環境が立ち上がってきます。
    ほんの少し修正するだけなのに、PC上でソースコードを直して、アップロードしなおす、という事をする必要がありません。直接Azure WebSite上にあるHTML, PHPなどのソースを編集して、保存できるのです。
    それに加えて、ドラックアンドドロップでファイルをアップロードする機能まであります。

    ドラックアンドドロップします。

     

    ファイルがアップロードされているのが確認できます。
    HTMLの場合は、タグとして認識されていますので、エディター上で色分けがされて大変読みやすくなっています。

    手元でファイル作成して、アップロード。という方法をとりましたが、いきなり”Monaco”に入って、”Monaco”の中でコーディングする、という方法でも構いません。

     

    1. MIMEの設定

    Azure WebSiteでは、ttmlのMIME設定がされていませんので、そのままでは動作しません。
    “text/xml”のmime設定を行います。
    Azure WebSiteの実体はIISですので、IISのweb.configファイルを作成し、MIME設定を行います。

     

    [web.config]

    —————————————————————————————————-
    <?xml version=”1.0″ encoding=”utf-8″?>

    <!– For HTML5 configuration details and recommendations, see https://github.com/h5bp/server-configs/wiki/web.config –>

    <configuration>

    <system.webServer>

    <staticContent>

    <remove fileExtension=”.ttml” />

    <mimeMap fileExtension=”.ttml” mimeType=”text/xml” />

    </staticContent>

    </system.webServer>

    </configuration>

     

    Azure WebSiteは最終的にこのようになりました。

     

    画面左側の再生ボタンを押して、本番サイトをみてみます。

     

    実行結果はこのような感じです。

     

    クリンゴン語で表示されていますね。

     

    [CC] のところで設定した字幕が選べるようになっています。

     

    1. まとめ

    Azure Media Indexerを使うと、そのままHTML5 Videoで作成できるTTMLのファイルが作成できる事を見てきました。
    そして、Microsoft Translatorで、かなり意味の分かる各国語に機械翻訳できるところも見てきました。

    話している場所は、シーンになります。検索結果、ビデオファイルのURLがわかるのではなく、ビデオの中のどのシーンに飛ばせばいいのかまでわかります。

    Azure Media Indexerはその他にも面白いファイルを作成してくれます。

    是非、いろんな可能性にチャレンジしてください!

     

    ご参考:

    Azure Media Indexer料金:

    http://azure.microsoft.com/ja-jp/pricing/details/media-services/#encoding

     

    Introducing Azure Media Indexer:
    http://azure.microsoft.com/blog/2014/09/10/introducing-azure-media-indexer/

    MSDN: Indexing Media Files with Azure Media Indexer:
    http://msdn.microsoft.com/en-us/library/dn783455.aspx

    What Can You Do with Azure Media Indexer? [William Zhang BLOG]:
    http://blogs.msdn.com/b/playready4/archive/2014/09/17/what-can-you-do-with-azure-media-indexer.aspx