基于Windows Azure Media Service REST API 进行Windows Store/Windows Phone 应用开发系列-Part 5发布流媒体

在文章基于Windows Azure Media Service REST API 进行Windows Store/Windows Phone 应用开发系列-Part 1 简介中介绍了基于Windows Azure Media Service(Windows Azure 媒体服务,简称WAMS)进行应用开发的相关信息及包含的基本流程,在文章基于Windows Azure Media Service REST API 进行Windows Store/Windows Phone 应用开发系列-Part 2初始设置链接到WAMS中介绍了如何使用REST API进行WAMS的链接,然后在基于Windows Azure Media Service REST API 进行Windows Store/Windows Phone 应用开发系列-Part 3上传媒体到WAMS中少如何将媒体文件上传到媒体服务,并在基于Windows Azure Media Service REST API 进行Windows Store/Windows Phone 应用开发系列-Part 3媒体编码中详细介绍了如何对媒体服务中媒体文件创建编码作业对其编码,并查看编码进程。当编码工作结束后,我们就可以进行流媒体发布工作了,这也正是本文包含的内容。

本文将基于前面4篇内容进一步讲解如何对编码输出的文件进行流媒体的发布工作。

使用REST API发布流媒体,主要流程是:

  1. 创建具有读取权限的AccessPolicy
  2. 创建用于传输媒体内容的源URL,再在此URL上构建最终的流媒体URL

请注意,如前文所强调的在使用REST API时访问媒体服务中的实体时,必须在HTTP请求中添加如下必须的标头字段和值;WAMS 的原始服务URI 为https://media.windows.net/,成功连接到此 URI后,会收到一个“301 重定向”响应指向另一个媒体服务URI,需要从该响应中提取出新的的媒体服务URI,随后的调用都是基于该 URI,详细内容参见Part2内容。

根据文档媒体服务 REST API 开发的设置可知,每次调用WAMS时,客户端必须在请求中包括必需的标头字段和值,列表如下:

Header

Type

Value

Authorization

Bearer

Bearer 是唯一接受的授权机制。

该值还必须包括由 ACS 提供的访问令牌。

x-ms-version

Decimal

2.7

DataServiceVersion

Decimal

3.0

MaxDataServiceVersion

Decimal

3.0

 

在传输任何媒体内容之前,必须先创建具有读取权限的AccessPolicy,然后创建相应的定位符地址,以便指定将要传输的流媒体类型(如微软的自适应流媒体协议smooth streaming, apple 的HLS,国际标准MPEG DASH),此处AccessPolicy的请求如前文上传文件时所用的请求类似,唯一的区别在于构造请求body内容时指定Permission=1,当然,为了以示区别,也AccessPolicy 指定不同的Name。由于文章3已做讲解,这里省略了细节实现内容。

理论上来说接下来就可以创建用于传输媒体内容的源URL了,但是在此操作之前我们需要先获取编码输出文件所在的位置,进而发布此位置中包含的文件。

执行过程可参考如下代码,返回文件所在位置:

  private async Task<string> GetOutputAssetAsync(string acsToken, string wamsEndpoint, string jobId)

        { 

            AuthenticationHeaderValue header = CreateBasicAuthenticationHeader(acsToken); 

            HttpClient httpClient = new HttpClient();

            httpClient.MaxResponseContentBufferSize = int.MaxValue; 

            httpClient.DefaultRequestHeaders.Add("Authorization", header.ToString());

            httpClient.DefaultRequestHeaders.Add("x-ms-version", "2.7");

            httpClient.DefaultRequestHeaders.Add("DataServiceVersion", "3.0");

            httpClient.DefaultRequestHeaders.Add("MaxDataServiceVersion", "3.0");

            httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));        

 

            string url = wamsEndpoint + "Jobs('" + WebUtility.UrlEncode(jobId) + "')/OutputMediaAssets()"; 

            var response = await httpClient.GetAsync(url); 

            string ouputId = null;

            if (response.IsSuccessStatusCode)

            {

                var content = await response.Content.ReadAsStringAsync();

                JObject jsonObject = JObject.Parse(content);

                var value = jsonObject.Value<JArray>("value");

                ouputId = value.First.Value<string>("Id"); 

                return ouputId; 

            }

            else

                return null;

        }

现在我们就可以正式创建流媒体地址了,首先创建用于传输媒体内容的源URL-locatorURL,再在此URL上构建最终的流媒体URL,操作很简单,即根据流媒体类型,添加相应的后缀内容即可:

1) Smooth streaming: locatorURL/filename.ism/manifest

2) HLS V4: locatorURL/filename.ism/manifest(format=m3u8-aapl)

3) HLS V3: locatorURL/filename.ism/manifest(format=m3u8-aapl-v3)

4) MPEG DASH: locatorURL/filename.ism/manifest(format=mpd-time-csf)

由于此处是针对windows 平台,只支持smooth streaming, 所以以下代码仅构建smooth streaming的URL.

创建用于传输的源URL的请求简要总结如下,详情请参见:使用 Media Services REST API 传送资产

EndPoint

https://media.windows.net/API/Locators   

或重定向后的新的URI/Locators

HTTP Method

GET

Request Headers

DataServiceVersion: 3.0MaxDataServiceVersion: 3.0x-ms-version: 2.7Authorization: Bear + ACSToken

Request Content Type

application/json; odata=verbose

Request Body Format

 {     "AccessPolicyId": "< AccessPolicyId >"),           “AssetId”: “<encoded output assetId>”,
           “StartTime”: “<DateTime.UtcNow >”,
           “Type”: “2”
 }

 

执行过程可参考如下代码,

  private async Task<string> CreateSStreamingUrlAsync(string acsToken, string wamsEndPoint, string encodingJobId)

        {

            string outputAssetId = await GetOutputAssetAsync(acsToken, wamsEndPoint, encodingJobId);

            string apID = await CreateAccessPolicyAsync(acsToken, wamsEndPoint, "DownloadPolicy", 1); 

            AuthenticationHeaderValue header = CreateBasicAuthenticationHeader(acsToken); 

            HttpClient httpClient = new HttpClient();

            httpClient.MaxResponseContentBufferSize = int.MaxValue; 

            httpClient.DefaultRequestHeaders.Add("Authorization", header.ToString());

            httpClient.DefaultRequestHeaders.Add("x-ms-version", "2.7");

            httpClient.DefaultRequestHeaders.Add("DataServiceVersion", "3.0");

            httpClient.DefaultRequestHeaders.Add("MaxDataServiceVersion", "3.0"); 

            HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, wamsEndPoint);

            request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));   

            String requestBody = "{ \"AccessPolicyId\" : \"" + apID + "\"," +

                           " \"AssetId\" : \"" + outputAssetId + "\", " +

                           " \"StartTime\" : \"" + DateTime.UtcNow.ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss") + "\", " +

                           " \"Type\" : " + "2" + "}"; 

            HttpContent body = new StringContent(requestBody, Encoding.UTF8, "application/json");

            var response = await httpClient.PostAsync(wamsEndPoint + "Locators", body); 

            string ssUrl = null; ;

            if (response.IsSuccessStatusCode)

            {

                var content = await response.Content.ReadAsStringAsync(); 

                XmlDocument xmlDoc = new XmlDocument();

                xmlDoc.LoadXml(content);

                XmlNodeList elemListBase = xmlDoc.GetElementsByTagName("d:Path");               

                foreach (var ele in elemListBase)

                {

                    ssUrl = ele.InnerText;

                }

 

                ssUrl = ssUrl+MediaNamewithoutExtention + ".ism/manifest";            

            } 

            return ssUrl;

        }

 

 同时我们可以在portal上发现出现了发布链接,且可以直接播放流媒体内容了,帮住我们检查结果。

 

 

 

当然做为Windows Store/Phone应用,我们需要使用特定的客户端SDK播放流媒体内容,对于Windows Store 应用,使用Microsoft Smooth Streaming Client SDK for Windows 8;对于Windows Phone 应用,使用Smooth Streaming Client SDK for Windows Phone 8.1,而且文档How to Build a Smooth Streaming Windows Store Application详细讲解了其使用过程。

 

通过本系列文章,我们讲解了如何在WinRT 应用中使用媒体服务,为广大用户提供自适应流媒体体验。