流媒体发布--在Windows Store应用中使用Azure媒体服务之三

经过前面的努力,我们终于完成了视频文件的上传和编码,那么接下来的最后一步就是将如何该视频发布出去了。相对应前面的步骤,这一次就要简单的多了。

 首先,在确认编码已经成功之后,我们可以获得输出的媒体的Asset编号:

 private async Task<string> CreateAssetFile(string accessToken, string assetId)

{

    var request = (HttpWebRequest)HttpWebRequest.Create("https://wamshknclus001rest-hs.cloudapp.net/api/Files");

    request.Method = "POST";

    request.ContentType = "application/json;odata=verbose";

    request.Accept = "application/json;odata=verbose";

 

    string requestbody =

    "{\"Name\":\"test.wmv\", \"ContentFileSize\":\"0\",\"MimeType\":\"video/x-ms-wmv\",\"ParentAssetId\":\"" + assetId + "\"}";

 

    request.Headers["DataServiceVersion"] = "3.0";

    request.Headers["MaxDataServiceVersion"] = "3.0";

    request.Headers["x-ms-version"] = "2.7";

    request.Headers["Authorization"] = "Bearer " + accessToken;

 

    var requestBytes = Encoding.UTF8.GetBytes(requestbody);

 

    var requestStream = await request.GetRequestStreamAsync();

    await requestStream.WriteAsync(requestBytes, 0, requestBytes.Length);

    await requestStream.FlushAsync();

 

    var response = await request.GetResponseAsync();

    var responseStream = response.GetResponseStream();

    var stream = new StreamReader(responseStream);

 

    var returnBody = stream.ReadToEnd();

    JObject responseJsonObject = JObject.Parse(returnBody);

    var d = responseJsonObject["d"];

    return d.Value<string>("Id");

}

然后我们需要得到一个可以下载该Asset的policy编号

private async Task<string> DownloadAccessPolicy(string accessToken)

{

            var request = (HttpWebRequest)HttpWebRequest.Create("https://wamshknclus001rest-hs.cloudapp.net/api/AccessPolicies");

            request.Method = "POST";

            request.ContentType = "application/json;odata=verbose";

            request.Accept = "application/json;odata=verbose";

 

            string name = "DownloadPolicy" + DateTime.UtcNow.ToString("s") + "Z";

            string dura = "3600";

            int permission = 1;

            var requestbody = "{ \"Name\" : \"" + name + "\", \"DurationInMinutes\" : \"" + dura + "\", \"Permissions\" : " + permission + "}";

 

            request.Headers["DataServiceVersion"] = "3.0";

            request.Headers["MaxDataServiceVersion"] = "3.0";

            request.Headers["x-ms-version"] = "2.5";

            request.Headers["Authorization"] = "Bearer " + accessToken;

 

            var requestBytes = Encoding.UTF8.GetBytes(requestbody);

 

            var requestStream = await request.GetRequestStreamAsync();

            await requestStream.WriteAsync(requestBytes, 0, requestBytes.Length);

            await requestStream.FlushAsync();

 

            var response = await request.GetResponseAsync();

            var responseStream = response.GetResponseStream();

            var stream = new StreamReader(responseStream);

 

            var returnBody = stream.ReadToEnd();

            var responseJsonObject = JObject.Parse(returnBody);

            var d = responseJsonObject["d"];

            return d.Value<string>("Id");

}

根据这个Asset编号以及相应的Policy编号,就可以得到Stream的路径了:

public async Task<string> GetOriginURL(string policyId, string assetId, string accessToken)

{

 

            HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create("https://wamshknclus001rest-hs.cloudapp.net/api/Locators");

 

            request.Method = "POST";

 

            request.ContentType = "application/json;odata=verbose";

            request.Accept = "application/json;odata=verbose";

            string starttime = DateTime.UtcNow.ToString("s") + "Z";

            int type = 2;

            String requestbody = "{ \"AccessPolicyId\" : \"" + policyId + "\", \"AssetId\" : \"" + assetId + "\", \"StartTime\" : \"" + starttime + "\", \"Type\" : " + type + "}";

 

            request.Headers["DataServiceVersion"] = "3.0";

            request.Headers["MaxDataServiceVersion"] = "3.0";

            request.Headers["x-ms-version"] = "2.5";

            request.Headers["Authorization"] = "Bearer " + accessToken;

 

            var requestBytes = Encoding.UTF8.GetBytes(requestbody);

 

            var requestStream = await request.GetRequestStreamAsync();

            await requestStream.WriteAsync(requestBytes, 0, requestBytes.Length);

            await requestStream.FlushAsync();

 

            WebResponse response = await request.GetResponseAsync();

            Stream responseStream = response.GetResponseStream();

            StreamReader stream = new StreamReader(responseStream);

 

            var returnBody = stream.ReadToEnd();

            JObject responseJsonObject = JObject.Parse(returnBody);

            var d = responseJsonObject["d"];

            return d.Value<string>("Path");

}

这个路径是不包含文件名的,另外,为了支持不同的平台,我们需要在该路径后面加上不同的manifest标志,由于我们前面是将媒体文件编码为Smooth Streaming流的,所以这里只需要加上manifest就可以了,最终在Button_Click中的代码就是:

var outputAssetId=await GetOutputAssetId(Id,accessToken);

policyId = await DownloadAccessPolicy(accessToken);

var streamPath = await GetOriginURL(policyId, outputAssetId, accessToken);

var streamFullPath=streamPath+"Wildlife.ism/manifest";

这里得到的streamFullPath就是可以用来播放的流媒体路径了。你可以把它放到任意一个支持Smooth Streaming流媒体的播放器中播放。那么在Windows Store应用中该如何播放呢?其实微软已经提供了支持Smooth Streaming的Windows Store应用控件,你可以首先下载Microsoft Smooth Streaming Client SDK for Windows 8.1:

https://visualstudiogallery.msdn.microsoft.com/0170c67c-c183-4fee-8dd4-c2b44d710d40

以及Player Framework for Windows and WP v2.0:

https://playerframework.codeplex.com/releases

然后在您的应用的Reference中添加三个引用:

Microsoft Smooth Streaming Client SDK For Windows 8.1

Microsoft Player Framework

Microsoft Player Framework Adaptive Streaming Plugin

注意,在添加了这三个引用以后,您的应用就不能使用Any CPU了,而必须的显式的设置x86或者x64。

然后在Toolbox里面就可以看到一个新的控件MediaPlayer,将该Media Player加到我们的XAML文件中

<PlayerFramework:MediaPlayer x:Name="mediaPlayer"/>

然后在后台的Button_Click的事件处理函数中添加代码来使Media player支持Smooth Streaming 并且设置它的Source,这样我们得到的流媒体才可以在Windows Store应用中播放:

var adaptivePlugin = new Microsoft.PlayerFramework.Adaptive.AdaptivePlugin();

mediaPlayer.Plugins.Add(adaptivePlugin);          

mediaPlayer.Source = new Uri(streamFullPath);

mediaPlayer.Play();

终于,所有的工作都已经大告成功,我们现在可以享受Smooth Streaming的流畅播放体验了。当然不管是Azure Mobile以及Microsoft Player Framework都是支持HLS以及MPEG DASH,所以如果你想采用这两种格式的话也是完全没问题的,区别就在于编码时格式选择的不同以及streamFullPath中manifest后缀的不同,有兴趣的朋友可以去自己尝试一下,这里我不重复了。