微软云平台媒体服务实践系列 3- 基于媒体服务REST API及Xamarin进行iOS, Android , Windows 应用开发

据统计,在Internet Traffic中,Video 所占的量超过了一半;相对于只使用电视机看节目的用户而言,使用移动设备的用户会多看接近50%的节目。可见,视频支持的终端设备越多,意味着越高的收视率,拥有越多的用户群,但是如果视频的缓冲时间长、画质差,用户很可能放弃观看。自适应流媒体技术可以根据客户端的网络带宽、系统资源等自动地选择恰当分辨率的媒体内容进行播放,为用户提供画质清晰流畅的播放体验。本文基于微软云平台媒体服务,介绍如何制定一个跨iOS,Android,Windows移动平台的自适应流媒体视频点播(VoD)方案,以期望在当今3大移动平台上,进行流媒体的制作与播放。

在移动平台上使用Azure Media Services (AMS) 的第一大难点就是对于iOS, Android,Windows Store 或Windows Phone app,没有可以直接使用的AMS SDK,也没有相应的移动应用使用媒体服务的code 样例;此外,各个移动平台拥有不同的开发环境与开发语言,那是否意味着需要分别去学习objective-c/swift, java,C#/VB.Net等才能完成整个方案? 而且该过程所耗费的时间及成本都不低。虽然困难重重,但是我们还是有机会的:一是媒体服务提供了可供所有平台调用的REST APIs;二是Xamarin的出现为我们解决了高效开发跨平台应用的难题,当然Cordova也是一个选择;三是媒体服务有相应的.Net code 样例供参考使用。(总结如下图所示)                                           

基于AMS REST APIs和Xamarin, 整个方案如下图所示,主要分为移动客户端和媒体服务端,首先移动客户端负责将原始媒体文件上传到云端,再让媒体服务完成编码、流媒体发布等任务,最后再由客户端播放使用。那么针对不同的客户端,是不是就需要3个开发团队完成各自平台的项目开发及维护、修正等,有没有一种一次编写、到处运行的方案呢?

                                          

 Xamarin为我们解决了高效开发的难题,开发者基于Visual Studio, 使用C#便可同时开发出iOS, Android, Windows Phone和Windows Store App。如下图所示,Xamarin 由Mono .net framework开源项目的创始人创办,基于微软.Net Framework, 将 3大移动平台的SDK APIs 100%的移植成C#类库,由于拥有共同的类库,因此各个平台的项目可以共享与平台无关的code,如使用web service,当然每个平台也有其独特性,如UI 控件,只不过都是通过C#及描述性语言如XAML,XML活XIB实现。

                                        

 

基于以上信息,在共享项目code里使用媒体服务,各个移动平台再使用对应的流媒体播SDK API即完成整个方案的设计。

                                        

   

基于REST APIs使用媒体服务的详细过程在前面的系列文:基于Windows Azure Media Service REST API 进行Windows Store/Windows Phone 应用开发系列1,2,3,4,5 进行了详细的介绍,代码基本上可以直接复用(基于System.Net.Http. HttpClient ),只是有些响应的返回内容的解析,在Xamarin中使用System.Linq.XDocument 类;此外,在上传媒体文件时(如下代码所示),不再使用Windows Runtime 的Windows.Storage.StorageFolder 类(高亮显示部分),由于上传过程使用的是Stream类型的数据且Xamarin支持System.IO.Stream 类,所以可以在各个平台独立地读取video为System.IO.Stream 类型,再传给share code操作 ;PCL Storage extension可以进行文件系统的读取,类似于Windows.Storage.StorageFolder的作用。

            HttpClientHandler handler = new HttpClientHandler { MaxRequestContentBufferSize = 10000000 };

            HttpClient httpClient = new HttpClient(handler);              

            httpClient.DefaultRequestHeaders.Add("x-ms-version", "2011-08-18");

            httpClient.DefaultRequestHeaders.Add("x-ms-date", "2011-01-17");

            httpClient.DefaultRequestHeaders.Add("x-ms-blob-type", "BlockBlob");          

         

           StorageFolder library = Windows.Storage.KnownFolders.VideosLibrary;          

            var videoFile = await library.GetFileAsync(MediaFileName);

            var props = await videoFile.GetBasicPropertiesAsync();

            var stream = await videoFile.OpenStreamForReadAsync();

            ContentSize = props.Size;

            StreamContent streamContent = new StreamContent(stream, (int)props.Size);

            HttpResponseMessage response = await httpClient.PutAsync(uploadUrl, streamContent);

在使用模拟器进行测试时,可以直接使用System.Reflection.Assembly 类中的API读取项目中的资源,将读取的Stream传给share code 即可。

var assembly = Assembly.GetExecutingAssembly();

var resourceName = "iStream.Droid.Assets.FromAndroid.wmv";        

Stream videoStream = assembly.GetManifestResourceStream(resourceName);

在MERGE过程中,Xamarin中使用的System.Net.HttpWebRequest 类型的request没有GetRequestStreamAsync() 及GetResponseAsync() 函数,为便于操作,为HttpWebRequest添加扩展方法:

public static class HttpWebRequestExtensions

   {

       public static Task<Stream> GetRequestStreamAsync(this HttpWebRequest request)

         {

             var tcs = new TaskCompletionSource<Stream>();

             try

             {

                 request.BeginGetRequestStream(iar =>

               {

                    try

                    {

                       var response = request.EndGetRequestStream(iar);

                       tcs.SetResult(response);

                   }

                    catch (Exception exc)

                  {

                       tcs.SetException(exc);

                   }

               }, null);

           }

            catch (Exception exc)

           {

               tcs.SetException(exc);

           }

           return tcs.Task;

      }

  

       public static Task<HttpWebResponse> GetResponseAsync(this HttpWebRequest request)

        {

           var tcs = new TaskCompletionSource<HttpWebResponse>();

    

           try

          {

              request.BeginGetResponse(iar =>

             {

                  try

                   {

                      var response = (HttpWebResponse)request.EndGetResponse(iar);

                      tcs.SetResult(response);

                  }

                  catch (Exception exc)

                   {

                      tcs.SetException(exc);

                  }

              }, null);

           }

            catch (Exception exc)

          {

              tcs.SetException(exc);

          }

            return tcs.Task;

      }

    }

 以上就是关于跨移动平台使用媒体服务制定自适应流媒体点播方案的介绍,通过对Xamarin及媒体服务 REST APIs的研究与编程实现,扩展了媒体服务在移动平台的运用,也极大地提高了开发效率,同时,该方案还可适用于其他基于REST API的服务,制定跨多平台的开发方案。