<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"><title>Web, Technologies, IA, Vidéo... - Cloud, Encodage, Vidéo</title><link href="https://www.alkannoide.com/" rel="alternate"/><link href="https://www.alkannoide.com/feeds/cloud-encodage-video.atom.xml" rel="self"/><id>https://www.alkannoide.com/</id><updated>2012-09-12T14:58:00+02:00</updated><entry><title>Microsoft Azure Media Services – How to encode in the Azure Cloud – Part 2</title><link href="https://www.alkannoide.com/2012/09/12/microsoft-azure-media-services-how-to-encode-in-the-azure-cloud-part-2/" rel="alternate"/><published>2012-09-12T14:58:00+02:00</published><updated>2012-09-12T14:58:00+02:00</updated><author><name>admin</name></author><id>tag:www.alkannoide.com,2012-09-12:/2012/09/12/microsoft-azure-media-services-how-to-encode-in-the-azure-cloud-part-2/</id><summary type="html">&lt;p&gt;After the first post which give an overview and explain how set-up a WAMS environment, I continue the discovery of &lt;a href="http://en.wikipedia.org/wiki/Wayne's_World"&gt;WAMS World&lt;/a&gt; (sorry for the pun ;-)). In this post, we will see how we can transform a video from a input format to another format. It's possible to generate multiple …&lt;/p&gt;</summary><content type="html">&lt;p&gt;After the first post which give an overview and explain how set-up a WAMS environment, I continue the discovery of &lt;a href="http://en.wikipedia.org/wiki/Wayne's_World"&gt;WAMS World&lt;/a&gt; (sorry for the pun ;-)). In this post, we will see how we can transform a video from a input format to another format. It's possible to generate multiple output format or to encrypt the video. But we will see it in a next posts.&lt;/p&gt;
&lt;p&gt;First of all, we need to understand the different terms we will use in WAMS. In my example, I want to obtain this workflow :&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;create an &lt;a href="http://msdn.microsoft.com/en-us/library/hh974277"&gt;asset&lt;/a&gt; : an asset is an entity which contains all informations on the video (metadata, ...)&lt;/li&gt;
&lt;li&gt;upload a file in blob storage and associate to the asset&lt;/li&gt;
&lt;li&gt;apply a &lt;a href="http://msdn.microsoft.com/en-us/library/hh974277"&gt;job&lt;/a&gt; on the asset. A job is composed by one or more &lt;a href="http://msdn.microsoft.com/en-us/library/hh974286"&gt;tasks&lt;/a&gt;. A task is an action : eg:  encoding with protection. To run the task, we use a &lt;a href="http://msdn.microsoft.com/en-us/library/hh974283"&gt;MediaProcessor&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;after the job completed, deliver the video via the Azure CDN.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;Create an asset&lt;/h2&gt;
&lt;p&gt;As I said previously, the AMS is based on REST, so you use HTTP verbs to make an action. Here is the PHP class, I used to make API call (I completed the code &lt;a href="https://www.alkannoide.com/2012/08/24/microsoft-azure-media-services-how-to-encode-in-the-azure-cloud-part-1/" title="Microsoft Azure Media Services – How to encode in the Azure Cloud – Part 1"&gt;given in previous post&lt;/a&gt;):&lt;/p&gt;
&lt;p&gt;[php]class Rest{&lt;br&gt;
protected \$strUrl;&lt;br&gt;
protected \$strToken;&lt;br&gt;
protected \$strBody;&lt;br&gt;
public function __construct(){&lt;br&gt;
\$this-&amp;gt;requestToken();&lt;br&gt;
}&lt;/p&gt;
&lt;p&gt;private function generateData(\$arrData){&lt;br&gt;
return implode('&amp;amp;', \$arrData);&lt;br&gt;
}&lt;/p&gt;
&lt;p&gt;public function requestToken(){&lt;br&gt;
if (file_exists(TOKEN_STORAGE)){&lt;br&gt;
echo 'Get Token from storage'."\n";&lt;br&gt;
\$data = file_get_contents(TOKEN_STORAGE);&lt;br&gt;
\$arrToken = json_decode(\$data);&lt;br&gt;
if ((filemtime(TOKEN_STORAGE) + \$arrToken-&amp;gt;expires_in) &amp;gt; time()) {&lt;br&gt;
\$this-&amp;gt;strToken = \$arrToken-&amp;gt;access_token;&lt;br&gt;
} else {&lt;br&gt;
echo 'Token expired'."\n";&lt;br&gt;
unlink(TOKEN_STORAGE);&lt;br&gt;
\$this-&amp;gt;requestToken();&lt;br&gt;
}&lt;br&gt;
} else {&lt;br&gt;
echo 'Get new token from API'."\n";&lt;br&gt;
\$arrData = array(&lt;br&gt;
'grant_type=client_credentials',&lt;br&gt;
'client_id='.CLIENT_ID,&lt;br&gt;
'client_secret='.urlencode(ACCESS_KEY),&lt;br&gt;
'scope=urn%3aWindowsAzureMediaServices'&lt;br&gt;
);&lt;br&gt;
\$arrHeader = array(&lt;br&gt;
'Content-length:'.strlen(\$this-&amp;gt;generateData(\$arrData))&lt;br&gt;
);&lt;/p&gt;
&lt;p&gt;\$ch = curl_init();&lt;br&gt;
curl_setopt(\$ch, CURLOPT_URL, TOKEN_URL);&lt;br&gt;
curl_setopt(\$ch, CURLOPT_POSTFIELDS, \$this-&amp;gt;generateData(\$arrData));&lt;br&gt;
curl_setopt(\$ch, CURLOPT_HTTPHEADER, \$arrHeader);&lt;br&gt;
curl_setopt(\$ch, CURLOPT_RETURNTRANSFER, true);&lt;br&gt;
\$data = curl_exec(\$ch);&lt;br&gt;
curl_close(\$ch);&lt;/p&gt;
&lt;p&gt;\$arrToken = json_decode(\$data);&lt;br&gt;
if (isset(\$arrToken-&amp;gt;error)){&lt;br&gt;
print_r(\$arrToken);&lt;br&gt;
die();&lt;br&gt;
}&lt;br&gt;
\$this-&amp;gt;strToken = \$arrToken-&amp;gt;access_token;&lt;br&gt;
file_put_contents(TOKEN_STORAGE, \$data);&lt;br&gt;
echo 'Token save in storage'."\n";&lt;br&gt;
}&lt;br&gt;
return \$this-&amp;gt;strToken;&lt;br&gt;
}&lt;/p&gt;
&lt;p&gt;public function request(\$arrData = array()){&lt;br&gt;
\$ch = curl_init();&lt;br&gt;
\$arrHeader = array(&lt;br&gt;
'x-ms-version:1.0',&lt;br&gt;
'DataServiceVersion:3.0',&lt;br&gt;
'MaxDataServiceVersion:3.0',&lt;br&gt;
'Authorization: Bearer '.\$this-&amp;gt;strToken,&lt;br&gt;
'Content-Type: application/json;odata=verbose',&lt;br&gt;
'Accept: application/json;odata=verbose'&lt;br&gt;
);&lt;br&gt;
echo 'Call API:'.\$this-&amp;gt;strUrl."\n";&lt;br&gt;
curl_setopt(\$ch, CURLOPT_URL, \$this-&amp;gt;strUrl);&lt;br&gt;
curl_setopt(\$ch, CURLOPT_HTTPHEADER, \$arrHeader);&lt;br&gt;
curl_setopt(\$ch, CURLOPT_HEADER, true);&lt;br&gt;
curl_setopt(\$ch, CURLOPT_RETURNTRANSFER, true);&lt;br&gt;
if (!empty(\$arrData)){&lt;br&gt;
curl_setopt(\$ch, CURLOPT_POSTFIELDS, json_encode(\$arrData));&lt;br&gt;
}&lt;br&gt;
\$data = curl_exec(\$ch);&lt;br&gt;
\$arrInfo = curl_getinfo(\$ch);&lt;br&gt;
curl_close(\$ch);&lt;/p&gt;
&lt;p&gt;list(\$strHeader, \$strBody) = explode("\r\n\r\n", \$data, 2);&lt;/p&gt;
&lt;p&gt;if (\$arrInfo['http_code'] == 301){&lt;br&gt;
if(preg_match('`\s*Location:\s(.+)`i', \$data, \$arrTmp)){&lt;br&gt;
\$arrTmp[1] = trim(\$arrTmp[1]);&lt;br&gt;
Register::getInstance()-&amp;gt;setIndex('base_url', \$arrTmp[1]);&lt;br&gt;
\$this-&amp;gt;strUrl = \$arrTmp[1].\$this-&amp;gt;getVerb();&lt;br&gt;
echo 'Redirection to '.\$this-&amp;gt;strUrl."\n";&lt;br&gt;
\$this-&amp;gt;request(\$arrData);&lt;br&gt;
}&lt;br&gt;
} else {&lt;br&gt;
\$this-&amp;gt;strBody = \$strBody;&lt;br&gt;
}&lt;br&gt;
}&lt;/p&gt;
&lt;p&gt;private function getVerb(){&lt;br&gt;
\$arrUrl = explode('/', \$this-&amp;gt;strUrl);&lt;br&gt;
return array_pop(\$arrUrl);&lt;br&gt;
}&lt;br&gt;
}[/php]&lt;/p&gt;
&lt;p&gt;You can look, the code manages the token, so you only need to make the API call.&lt;/p&gt;
&lt;p&gt;Now, we will create an asset. To do that, we need&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;an asset name; in my case : first_sintel_test.&lt;/li&gt;
&lt;li&gt;the URI of the API : https://wamsbluclus001rest-hs.cloudapp.net/API/Assets&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We will &lt;a href="http://msdn.microsoft.com/en-us/library/hh974277#create_an_asset"&gt;create an asset with POST verb&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;[php]class Asset extends Rest{&lt;/p&gt;
&lt;p&gt;public function __construct(){&lt;br&gt;
parent::__construct();&lt;br&gt;
}&lt;/p&gt;
&lt;p&gt;public function createAsset(\$strName) {&lt;br&gt;
\$strAPIname = 'Assets';&lt;br&gt;
\$this-&amp;gt;strUrl = 'https://wamsbluclus001rest-hs.cloudapp.net/API/'.\$strAPIname;&lt;br&gt;
\$arrCreate = array('Name' =&amp;gt; \$strName);&lt;br&gt;
\$this-&amp;gt;request(\$arrCreate);&lt;br&gt;
}&lt;br&gt;
}&lt;/p&gt;
&lt;p&gt;\$obj = new Asset();&lt;br&gt;
\$str = \$obj-&amp;gt;createAsset('first_sintel_test');&lt;/p&gt;
&lt;p&gt;print_r(json_decode(\$str));&lt;br&gt;
[/php]&lt;/p&gt;
&lt;p&gt;Ok, the server answers, the asset was created. Now, we will verified by listing the different asset. The method below will be added to the previous one.&lt;/p&gt;
&lt;p&gt;[php]public function listAsset() {&lt;br&gt;
\$strAPIname = 'Assets';&lt;br&gt;
\$this-&amp;gt;strUrl = Register::getInstance()-&amp;gt;getIndex('base_url').\$strAPIname;&lt;br&gt;
\$this-&amp;gt;request();&lt;br&gt;
return \$this-&amp;gt;strBody;&lt;br&gt;
}&lt;br&gt;
[/php]&lt;/p&gt;
&lt;p&gt;Note the asset ID, you need it after. Now, we call the &lt;a href="http://msdn.microsoft.com/en-us/library/hh974277#list_an_asset"&gt;list Asset API&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;[php]&lt;br&gt;
\$obj = new Asset();&lt;br&gt;
\$str = \$obj-&amp;gt;listAsset();&lt;/p&gt;
&lt;p&gt;print_r(json_decode(\$str));&lt;br&gt;
[/php]&lt;/p&gt;
&lt;p&gt;Good, we have our first_sintel_test asset with his creation date, his status and &lt;a href="http://msdn.microsoft.com/en-us/library/hh974277#asset_entity_properties"&gt;some others properties&lt;/a&gt;. You can filter to get informations about one asset by adding the ID (a unique identifier).&lt;/p&gt;
&lt;p&gt;Now, we can upload our file in blob storage.&lt;/p&gt;
&lt;h2&gt;Upload a file and associate to asset&lt;/h2&gt;
&lt;p&gt;To upload a file and associate to an asset, you need to give &lt;a href="http://msdn.microsoft.com/en-us/library/hh974297#create_an_accesspolicy"&gt;access via policies&lt;/a&gt; (time duration and permission: read, write, delete,...). You can create the policy, the process is the same like the Asset creation. Note the access ID, you need it after.&lt;/p&gt;
&lt;p&gt;[php]&lt;br&gt;
\$obj = new AccessPolicy();&lt;br&gt;
\$str = \$obj-&amp;gt;createAssetPolicy('sintel_policy', 30, 2);&lt;br&gt;
print_r(json_decode(\$str));&lt;br&gt;
[/php]&lt;/p&gt;
&lt;p&gt;We have now a policy to upload the file, we have to get a URL path to upload by created a &lt;a href="http://msdn.microsoft.com/en-us/library/hh974308"&gt;Locator&lt;/a&gt;. When it will be created, it will available in the Asset list API. To create a Locator, you need 4 informations :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;the asset ID (you noted it before)&lt;/li&gt;
&lt;li&gt;the access policy ID (noted it too)&lt;/li&gt;
&lt;li&gt;the start time : this one is to give the access in the future or now (have a look on &lt;a href="http://msdn.microsoft.com/en-us/library/jj129593#upload_a_file"&gt;documentation's tips&lt;/a&gt; to give access immediately).&lt;/li&gt;
&lt;li&gt;the type of access (SAS, Origin or Azure CDN)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Ok, now we can upload the file with &lt;a href="http://msdn.microsoft.com/en-us/library/windowsazure/dd179355.aspx"&gt;Windows Azure Storage Services REST API&lt;/a&gt;. You can check that your video was uploaded correctly via the Azure Portal : Storage -&amp;gt; Select your storage -&amp;gt; Containers and you can see it :&lt;/p&gt;
&lt;p&gt;&lt;a href="/images/2012/09/storage-container1.jpg"&gt;&lt;img src="/images/2012/09/storage-container1.jpg" title="storage-container" class="alignleft size-full wp-image-930" width="700" height="233" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Now, before process the video we need to &lt;a href="http://msdn.microsoft.com/en-us/library/hh974277#publish_an_asset"&gt;publish the asset&lt;/a&gt;. Take care on the Content-length header's value, it needs to be set at 0. I make a little update on the code.&lt;/p&gt;
&lt;p&gt;[php]&lt;br&gt;
public function request(\$arrData = array(), \$strTypePost = false){&lt;br&gt;
....&lt;br&gt;
echo 'Call API:'.\$this-&amp;gt;strUrl."\n";&lt;br&gt;
if (\$strTypePost &amp;amp;&amp;amp; empty(\$arrData)) {&lt;br&gt;
curl_setopt(\$ch, CURLOPT_CUSTOMREQUEST, 'POST');&lt;br&gt;
\$arrHeader[] = 'Content-Length: 0';&lt;br&gt;
}&lt;br&gt;
curl_setopt(\$ch, CURLOPT_URL, \$this-&amp;gt;strUrl);&lt;br&gt;
....&lt;br&gt;
\$this-&amp;gt;strUrl = \$arrTmp[1].\$this-&amp;gt;getVerb();&lt;br&gt;
echo 'Redirection to '.\$this-&amp;gt;strUrl."\n";&lt;br&gt;
\$this-&amp;gt;request(\$arrData, \$strTypePost);&lt;br&gt;
....&lt;br&gt;
}[/php]&lt;/p&gt;
&lt;p&gt;Then, you will receive a 204 header code.&lt;/p&gt;
&lt;h2&gt;Create a job&lt;/h2&gt;
&lt;p&gt;Ok, now, we have the asset and the file. But, in which format do we want to transcode ? Microsoft give us &lt;a href="http://msdn.microsoft.com/en-us/library/hh973619"&gt;a list of presets&lt;/a&gt; to make Task on WAMS : transcode in differents commons formats (for example iOS), apply protection (via PlayReady DRM) or rewrap contents from Smooth to HLS. I choose this preset : &lt;em&gt;H.264 iPod Classic / Nano. &lt;/em&gt;We can apply multiple tasks on an asset, but we will this it in a next post.&lt;/p&gt;
&lt;p&gt;Let's go to create our first job and apply a task preset.&lt;/p&gt;
&lt;p&gt;[php]class Jobs extends Rest{&lt;/p&gt;
&lt;p&gt;public function __construct(){&lt;br&gt;
\$this-&amp;gt;requestToken();&lt;br&gt;
}&lt;/p&gt;
&lt;p&gt;public function listJobs(){&lt;br&gt;
\$strAPIname = 'Jobs';&lt;br&gt;
\$this-&amp;gt;strUrl = Register::getInstance()-&amp;gt;getIndex('base_url').\$strAPIname;&lt;br&gt;
\$this-&amp;gt;request();&lt;br&gt;
return \$this-&amp;gt;strBody;&lt;br&gt;
}&lt;/p&gt;
&lt;p&gt;public function createJob(\$strName, \$strAssetUri, \$strConfig, \$strProcessor, \$strTaskBody) {&lt;br&gt;
\$strAPIname = 'Jobs';&lt;br&gt;
\$this-&amp;gt;strUrl = Register::getInstance()-&amp;gt;getIndex('base_url').\$strAPIname;&lt;/p&gt;
&lt;p&gt;\$objMedia = new stdClass();&lt;br&gt;
\$objMedia-&amp;gt;__metadata-&amp;gt;uri = \$strAssetUri;&lt;/p&gt;
&lt;p&gt;\$objTask = new stdClass();&lt;br&gt;
\$objTask-&amp;gt;Configuration = \$strConfig;&lt;br&gt;
\$objTask-&amp;gt;MediaProcessorId = \$strProcessor;&lt;br&gt;
\$objTask-&amp;gt;TaskBody = \$strTaskBody;&lt;/p&gt;
&lt;p&gt;\$arrCreate = new stdClass();&lt;br&gt;
\$arrCreate-&amp;gt;Name = \$strName;&lt;br&gt;
\$arrCreate-&amp;gt;InputMediaAssets[] = \$objMedia;&lt;br&gt;
\$arrCreate-&amp;gt;Tasks[] = \$objTask;&lt;/p&gt;
&lt;p&gt;\$this-&amp;gt;request(\$arrCreate);&lt;br&gt;
return \$this-&amp;gt;strBody;&lt;br&gt;
}&lt;/p&gt;
&lt;p&gt;public function cancelJob(\$assetId) {&lt;br&gt;
\$strAPIname = 'CancelJob?jobid=';&lt;/p&gt;
&lt;p&gt;\$this-&amp;gt;strUrl = Register::getInstance()-&amp;gt;getIndex('base_url').\$strAPIname."'".urlencode(\$assetId)."'";&lt;/p&gt;
&lt;p&gt;\$this-&amp;gt;request();&lt;br&gt;
return \$this-&amp;gt;strBody;&lt;br&gt;
}&lt;br&gt;
}[/php]&lt;/p&gt;
&lt;p&gt;This class provides methods to list, create and cancel a job. Here is a API creation call :&lt;/p&gt;
&lt;p&gt;[php]&lt;br&gt;
\$objJob = new Jobs();&lt;br&gt;
\$str = \$objJob-&amp;gt;createJob('EncoreSecondSintel', \$assetUri, \$strConf, \$strProcess, \$strTaskBody);&lt;br&gt;
print_r(json_decode(\$str));&lt;br&gt;
[/php]&lt;/p&gt;
&lt;p&gt;&lt;em&gt;\$assetUri&lt;/em&gt; is given when you create the asset, &lt;em&gt;\$strConf&lt;/em&gt; is the preset we choose (the string &lt;em&gt;H.264 iPod Classic / Nano&lt;/em&gt;), &lt;em&gt;\$strTaskBody&lt;/em&gt; is a XML string :&lt;/p&gt;
&lt;p&gt;[xml]\&amp;lt;?xml version="1.0" encoding="utf-16"?&amp;gt;&lt;br&gt;
\&amp;lt;taskBody&amp;gt;&lt;br&gt;
\&amp;lt;inputAsset&amp;gt;JobInputAsset(0)\&amp;lt;/inputAsset&amp;gt;&lt;br&gt;
\&amp;lt;outputAsset&amp;gt;JobOutputAsset(0)\&amp;lt;/outputAsset&amp;gt;&lt;br&gt;
\&amp;lt;/taskBody&amp;gt;[/xml]&lt;/p&gt;
&lt;p&gt;There is a last parameter : &lt;em&gt;\$strProcess&lt;/em&gt;. This is the ID of the MediaProcessor we want to use. There is 4 types of &lt;a href="http://msdn.microsoft.com/en-us/library/hh974283"&gt;MediaProcessors&lt;/a&gt; :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Storage Decryption&lt;/li&gt;
&lt;li&gt;Windows Azure Media Encoder&lt;/li&gt;
&lt;li&gt;MP4 to Smooth Streams Task&lt;/li&gt;
&lt;li&gt;PlayReady Protection Task&lt;/li&gt;
&lt;li&gt;Smooth Streams to HLS Task&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In our case, we are using the Windows Azure Media Encoder, so apply the associated ID give by the MediaProcessor API on the &lt;em&gt;\$strProcess&lt;/em&gt; param.&lt;/p&gt;
&lt;p&gt;Ok, now we can create a Job. The &lt;a href="http://msdn.microsoft.com/en-us/library/5100ddd7-92ff-4c37-84d2-4f84fee250a7#job_entity_properties"&gt;Job entity&lt;/a&gt; have different properties :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Job ID&lt;/li&gt;
&lt;li&gt;Time datas (creation, end of task, running duration,...)&lt;/li&gt;
&lt;li&gt;State&lt;/li&gt;
&lt;li&gt;Tasks details. This parameter provide us some additionnals informations like the performance :&lt;/li&gt;
&lt;/ul&gt;
&lt;table data-cellspacing="0" data-cellpadding="0"&gt;
&lt;colgroup&gt;
&lt;col style="width: 100%" /&gt;
&lt;/colgroup&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td data-valign="middle"&gt;EncodeTime: 00:00:20.9047240&lt;br /&gt;
Avg CPU Load: 70.3%  Avg Active Core: 3.9/4&lt;br /&gt;
Download: 00:00:02.1264505&lt;br /&gt;
Upload: 00:00:09.4015013&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;Great, the job is running, we can follow the progression with the listJobs() method.&lt;/p&gt;
&lt;p&gt;When the job is done, the movie is on blob storage in Azure. There is few solutions :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;download the movie&lt;/li&gt;
&lt;li&gt;publish the movie on the Azure CDN (for streaming)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In our case, we will download the movie with  &lt;a href="http://msdn.microsoft.com/en-us/library/windowsazure/dd179355.aspx"&gt;Windows Azure Storage Services REST API&lt;/a&gt;.  After few seconds (or minutes it depends on your movie size), you will have the video on your local storage and view it.&lt;/p&gt;
&lt;p&gt;To finish :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;the transfert (upload/download : on/from Azure and from AzureStorage to MediaService instances)  on the differents files seems to take more time than the transcoding process&lt;/li&gt;
&lt;li&gt;for a good usage, you need to understand all the entities available and how they will be implemented&lt;/li&gt;
&lt;li&gt;there is many possibilities, so don't hesitate to test the multiple combinaison you think. I will make other(s) post(s) on this subject.&lt;/li&gt;
&lt;/ul&gt;</content><category term="Cloud, Encodage, Vidéo"/></entry><entry><title>Microsoft Azure Media Services - How to encode in the Azure Cloud - Part 1</title><link href="https://www.alkannoide.com/2012/08/24/microsoft-azure-media-services-how-to-encode-in-the-azure-cloud-part-1/" rel="alternate"/><published>2012-08-24T15:25:00+02:00</published><updated>2012-08-24T15:25:00+02:00</updated><author><name>admin</name></author><id>tag:www.alkannoide.com,2012-08-24:/2012/08/24/microsoft-azure-media-services-how-to-encode-in-the-azure-cloud-part-1/</id><summary type="html">&lt;p&gt;I open a serie of posts which will talk about this solution. Microsoft announced at the end of spring the preview of &lt;a href="https://www.windowsazure.com/en-us/develop/net/how-to-guides/media-services/#what-are"&gt;Windows Azure Media Services&lt;/a&gt;. WAMS form an extensible media platform that integrates the best of the Microsoft Media Platform and third-party media components in Windows Azure.&lt;/p&gt;
&lt;h2&gt;Overview&lt;/h2&gt;
&lt;p&gt;WAMS …&lt;/p&gt;</summary><content type="html">&lt;p&gt;I open a serie of posts which will talk about this solution. Microsoft announced at the end of spring the preview of &lt;a href="https://www.windowsazure.com/en-us/develop/net/how-to-guides/media-services/#what-are"&gt;Windows Azure Media Services&lt;/a&gt;. WAMS form an extensible media platform that integrates the best of the Microsoft Media Platform and third-party media components in Windows Azure.&lt;/p&gt;
&lt;h2&gt;Overview&lt;/h2&gt;
&lt;p&gt;WAMS can transform movie in differents formats and codecs :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Supported video and audio codecs:&lt;/li&gt;
&lt;li&gt;H.264 High, Main and Baseline Profiles&lt;/li&gt;
&lt;li&gt;AAC-LC&lt;/li&gt;
&lt;li&gt;HE-AAC&lt;/li&gt;
&lt;li&gt;VC-1 (Windows Media Video 9) Simple, Main and Advanced Profiles&lt;/li&gt;
&lt;li&gt;Windows Media Audio Standard&lt;/li&gt;
&lt;li&gt;Windows Media Audio Professional&lt;/li&gt;
&lt;li&gt;Supported format conversions:&lt;/li&gt;
&lt;li&gt;ISO MP4 (.mp4) to Smooth Streaming File Format (PIFF 1.3) (.ismv; .isma)&lt;/li&gt;
&lt;li&gt;Smooth Streaming File Format (PIFF) to Apple HTTP Live Streaming (.msu8, .ts)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For the moment, you can only make VoD video.&lt;br&gt;
It is already possible to encrypt your content (via PlayReady DRM). You can manage it via &lt;a href="http://msdn.microsoft.com/en-us/library/hh973613"&gt;.NET&lt;/a&gt; or &lt;a href="http://msdn.microsoft.com/en-us/library/hh973618"&gt;REST API&lt;/a&gt;. I'm not a .NET developer, so I will try the solution via API. My code side will be in PHP.&lt;/p&gt;
&lt;h2&gt;Setup&lt;/h2&gt;
&lt;p&gt;First of all, you need to &lt;a href="http://social.msdn.microsoft.com/Forums/en-US/MediaServices/thread/a9d3d1b4-09eb-4a28-ad1d-a1f4cf3123cb"&gt;setup your account to use WAMS&lt;/a&gt;. Currently, the setup is only possible via Powershell, but it will change via the Azure portal. For this step, you need a Windows, but after you can use other OS.&lt;/p&gt;
&lt;p&gt;To connect to Media services, you need two things : 1) an access token provided by Windows Azure Access Control Services (ACS) and 2) the URI of Media Services itself. To get the token, you make a &lt;a href="http://msdn.microsoft.com/en-us/library/hh973616"&gt;OAuth request&lt;/a&gt; with the parameter you get when you setup your account : the access key and the client ID. Different libraries are available in different langage to make this kind of request, for me, I create a simple PHP method to manage it.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;php&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Rest&lt;/span&gt;&lt;span class="err"&gt;{&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;protected&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;strUrl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;protected&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;strToken&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;protected&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;strBody&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;function&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;requestToken&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="err"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;!&lt;/span&gt;&lt;span class="n"&gt;file_exists&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TOKEN_STORAGE&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="err"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="n"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Get Token from storage&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="ss"&gt;&amp;quot;\n&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="k"&gt;data&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;file_get_contents&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TOKEN_STORAGE&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;arrToken&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;json_decode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="k"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;filemtime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TOKEN_STORAGE&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;arrToken&lt;/span&gt;&lt;span class="o"&gt;-&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;gt&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="n"&gt;expires_in&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;gt&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;time&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;this&lt;/span&gt;&lt;span class="o"&gt;-&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;gt&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="n"&gt;strToken&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;arrToken&lt;/span&gt;&lt;span class="o"&gt;-&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;gt&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="n"&gt;access_token&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="err"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="n"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Token expired&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="ss"&gt;&amp;quot;\n&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="n"&gt;unlink&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TOKEN_STORAGE&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;this&lt;/span&gt;&lt;span class="o"&gt;-&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;gt&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="n"&gt;requestToken&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="err"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="err"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="n"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Get new token from API&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="ss"&gt;&amp;quot;\n&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;arrData&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;grant_type=client_credentials&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;client_id=&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CLIENT_ID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;client_secret=&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;urlencode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ACCESS_KEY&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;scope=urn%3aWindowsAzureMediaServices&amp;#39;&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;arrHeader&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Content-length:&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;strlen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;this&lt;/span&gt;&lt;span class="o"&gt;-&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;gt&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="n"&gt;generateData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;arrData&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;ch&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;curl_init&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="n"&gt;curl_setopt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;ch&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;CURLOPT_URL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;TOKEN_URL&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="n"&gt;curl_setopt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;ch&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;CURLOPT_POSTFIELDS&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;this&lt;/span&gt;&lt;span class="o"&gt;-&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;gt&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="n"&gt;generateData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;arrData&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="n"&gt;curl_setopt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;ch&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;CURLOPT_HTTPHEADER&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;arrHeader&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="n"&gt;curl_setopt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;ch&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;CURLOPT_RETURNTRANSFER&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="k"&gt;data&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;curl_exec&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;ch&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="n"&gt;curl_close&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;ch&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;arrToken&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;json_decode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="k"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;isset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;arrToken&lt;/span&gt;&lt;span class="o"&gt;-&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;gt&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="err"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="n"&gt;print_r&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;arrToken&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="n"&gt;die&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="err"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;this&lt;/span&gt;&lt;span class="o"&gt;-&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;gt&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="n"&gt;strToken&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;arrToken&lt;/span&gt;&lt;span class="o"&gt;-&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;gt&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="n"&gt;access_token&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="n"&gt;file_put_contents&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TOKEN_STORAGE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="k"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="n"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Token save in storage&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="ss"&gt;&amp;quot;\n&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="err"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;         &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;this&lt;/span&gt;&lt;span class="o"&gt;-&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;gt&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="n"&gt;strToken&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="err"&gt;}&lt;/span&gt;
&lt;span class="err"&gt;}&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;/php&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The AMS response will contains the token. If you make many calls, I suggest to cache the access token, the expires_in value and the timestamp of the request to avoid unnecessary calls.&lt;/p&gt;
&lt;p&gt;Now, we have a token to access, we can play with the Azure Media Services. We will see it in next posts.&lt;/p&gt;</content><category term="Cloud, Encodage, Vidéo"/></entry></feed>