基于web端Flash播放开发经验分享
1、一、SDK加载与注册1.Yunfan.swf加载方式确认YufanSDK的地址,你可以使用自己的CDN。如果要加载来自云帆服务器的YunfanSDK,请与云帆客服联系。privatevarYUNFAN_SDK:String="http://yourdomain/path/Yunfan.swf";初始化加载相关的变量和声明YunfanStream类。privatevarreq:URLRequest=newURLRequest(YUNFAN_SDK); privatevarcontext:LoaderContext=newLoaderContext(true,ApplicationDomain.currentDomain);context.securityDomain=flash.system.SecurityDomain.currentDomain;privatevarloader=newLoader();privatevarYunfanStream:Class;privatevarstream:*;注册加载事件,在加载完成事件中获取YunfanStream类,并实例化一个播放流。loader.contentLoaderInfo.addEventListener(Event.COMPLETE,function():void{YunfanStream=loader.contentLoaderInfo.applicationDomain.getDefinition("YunfanStream")asClass; loader.contentLoaderInfo.removeEventListener(Event.COMPLETE,arguments.callee);//加载到YunfanStream类后,实例化等操作varconnection=newNetConnection(); connection.connect(null);stream=newYunfanStream(netConnection);trace('yunfanp2p加载成功,版本号:'+stream.version);});开始从Yunfan.swf中加载YunfanStream类。loader.load(req,context);2.YunfanLoader.swc加载方式加初始化加载相关的变量和声明YunfanStream类。importcom.yunfancdn.loader.YunfanLoader;importcom.yunfancdn.YunfanEvent;privatevaryfLoader:YunfanLoader;privatevarYunfanStream:Class;privatevarstream:*;加载YunfanStream的函数体,里面注册了加载成功和失败的事件。privatefunctionloadYunfan():void{try{ yfLoader=newYunfanLoader();yfLoader.addEventListener(YunfanEvent.COMPLETE,onComplete);yfLoader.addEventListener(YunfanEvent.ERROR,onError);yfLoader.load();}catch(e:*){trace('loadyunfanerror'+e)}}加载成功事件,在加载完成事件中获取YunfanStream类,并实例化一个播放流。privatefunctiononComplete(e:YunfanEvent):void{ varconnection=newNetConnection(); connection.connect(null);YunfanStream=e.data.StreamClassasClass; stream=newYunfanStream(connection); trace('yunfanp2p加载成功,版本号:'+stream.version); this.yfLoader.removeEventListener(YunfanEvent.COMPLETE,this.onComplete); this.yfLoader.removeEventListener(YunfanEvent.ERROR,this.onError); this.yfLoader=null;}加载失败事件。privatefunctiononError(e:YunfanEvent):void{ this.yfLoader.removeEventListener(YunfanEvent.COMPLETE,this.onComplete); this.yfLoader.removeEventListener(YunfanEvent.ERROR,this.onError); this.yfLoader=null; trace("yunfanp2p加载失败,"+e.data.code); }开始加载YunfanStream。loadYunfan():YunfanStream获取后,你可以尝试获取sdk版本号,来验证sdk是否加载成功。注册YunfanStream,验证你是否有权限使用YunfanSDK。privateconstYUNFAN_KEY:String="请在yunfancdn.com网站上注册并申请KEY";stream.register(YUNFAN_KEY);yunfan.addEventListener(YunfanEvent.REGISTER_FAIL,onRegisterHandler);yunfan.addEventListener(YunfanEvent.REGISTER_SUCC,onRegisterHandler);注册的回调事件,如果注册成功,那么你就可以正常使用YunfanP2P服务了。privatefunctiononRegisterHandler(e:YunfanEvent):void{if(e.type==YunfanEvent.REGISTER_SUCC){trace('yunfanp2p注册成功,状态码:'+e.code);//可以开始使用yunfanstream了}elseif(e.type==YunfanEvent.REGISTER_SUCC){trace('yunfanp2p注册失败,状态码:'+e.code);}}注册事件返回的状态码含义如下图:

2、二、获取yunfanSDK版本号l静态属性:YunfanStream.VERSIONl实例属性:stream.version你可以将该版本号通过ContextMenu类添加至flash右键菜单中方便双方调试。
3、三、YunfanStream使用示例YunfanStream由NetStream派生,支持NetStream所有的属性、方法和事件,你完全可以按照NetStream类一样使用。YunfanStream视频播放参数如下图:YunfanStream会请求videoUrl,以获取视频码流(同一个视频不同码率也是不同的视频码流)。如果贵方同一个影片只有唯一一个videoUrl,那么keyUrl可与videoUrl相同。如果同一个视频影片拥有多个videoUrl,请配置该影片的关键地址keyUrl。比如:同一个视频地址每天都会变化:videoUrl1="http://www.iqiyi.com/dianshiju/20130615/b1400ed7e0aab7ff.html";videoUrl2="http://www.iqiyi.com/dianshiju/20130616/b1400ed7e0aab7ff.html";那么应该这项传参数:keyUrl="http://www.iqiyi.com/b1400ed7e0aab7ff";stream.play(videoUrl1,keyUrl);stream.play(videoUrl2,keyUrl);

4、四、使用示例:初始化视频播放器,并将播放器添加到舞台。privatevarvideo:Video=newVideo();stage.addChild(video);给播放流注册事件,同时播放器关联该播放流,然后把视频地址传给播放流开始播放。privatevarvideoUrl:String="你的视频源地址";privatevarkeyUrl:String="你的视频关键地址";stream.addEventListener(NetStatusEvent.NET_STATUS,netStatusHandler);stream.client=this;video.attachNetStream(stream);stream.play(videoUrl,keyUrl);播放过程中的状态事件:privatefunctionnetStatusHandler(e:NetStatusEvent):void{switch(e.info.code){case"NetConnection.Connect.Success"://NetConnection连接成功break;case"NetStream.Play.StreamNotFound"://找不到视频流,请检查视频url或者网络break;case"NetStream.Play.Start"://视频启动播放。一次play()方法至多触发一次该事件。break;case"NetStream.Play.Stop"://视频停止播放。手动close不会触发该事件break;case"NetStream.Unpause.Notify"://暂停后恢复播放状态break;case"NetStream.Buffer.Full"://缓冲区已满,流开始播放break;case"NetStream.Pause.Notify"://暂停break;case"NetStream.Buffer.Empty"://缓冲区内数据不足,发起缓冲break;}}播放流触发的视频元信息事件:publicfunctiononMetaData(info:Object):void{//从这里获取视频宽、高、时长、大小、关键帧等信息for(vari:*ininfo){trace(i+":"+info[i]);}
5、五、YunfanStream自定义事件YunfanStream除了NetStream原生事件外,新增了以下事件(同样由NetStatusEvent扩展):l{code:'NetStream.SecurityError.843',value:data.ip})视频服务器(包括CDN节点)的843端口服务未开启或者返回的843策略文件异常。value为对应服务器ip。l{code:'NetStream.NetWork.ContentRangeError',value:data.ip})视频服务器(包括CDN节点)不支持Range字段的HTTP分段请求。value为对应服务器ip。l{code:'NetStream.CDN.StreamNotFound'})云帆CDN上找不到视频文件,当使用云帆CDN的时候请注意该事件。当视频首次点播的时候,云帆CDN还没有cache到该视频,就找不到该文件,这时候会触发该事件,同时云帆CDN会去下载该视频。等下次点播,云帆CDN上有了该视频,就会从云帆CDN上下载视频。触发该事件的时候,你可以转向Netstream下载,并将YunfanStream的实例close。
6、六、视频源服务器(CDN)需要哪些支持?1.支持标准HTTP协议中的RANGE字段Range:用于请求头中,指定第一个字节的位置和最后一个字节的位置,一般格式:Range:bytes=(起始字节位置,单位byte)-(结束字节位置,单位byte)如:Range:bytes=0-0,表示请求第0-0位置也就是第1个字节的数据Range:bytes=1-100,表示请求第1-100位置共100个字节的数据Range:bytes=0-,表示请求从0开始到最后一个字节的数据Content-Range:用于响应头,指定整个实体中的一部分的插入位置,他也指示了整个实体的长度。在服务器向客户返回一个部分响应,它必须描述响应覆盖的范围和整个实体长度。一般格式:Content-Range:bytes=(起始字节位置)-(结束字节位置)/(整个实体长度)客户端请求下载文件:GET/test.rarHTTP/1.1Connection:closeHost:116.1.219.219Range:bytes=0-801//一般请求下载整个文件是bytes=0-或不用这个头服务端响应头:HTTP/1.1206OKContent-Length:801Content-Type:application/octet-streamContent-Range:bytes0-800/801//801:文件总大小2.视频url支持start和end参数格式:http://domain.com/path/filename.mp4?start=xxx&end=xxx表示分段请求视频文件,范围从start位置开始到end结束,单位是字节。服务端返回的格式同支持标准HTTP协议中的RANGE字段。3.视频服务器根目录配置跨域策略文件确保你的视频服务器根目录下http://domain.com/crossdomain.xml能访问,且响应格式为Content-Type:text/xml,内容如下:<?xmlversion="1.0"encoding="UTF-8"?><cross-domain-policy><allow-access-fromdomain="*"/></cross-domain-policy>4.视频服务器开启843端口在你的视频服务器上启动一个TCP监听843端口的服务,当有连接并发送了'<policy-file-request/>\0'这样的字符串的时候,返回如下内容,然后关闭连接。<?xmlversion="1.0"encoding="UTF-8"?><cross-domain-policy><allow-access-fromdomain="*"to-ports="*"/></cross-domain-policy>你也可以联系索取该843服务器的程序代码。