分享

流媒体及FLV播放器相关知识点 - flash - zhangzhichao198

 earthworm 2010-01-11
流媒体及FLV播放器相关知识点
一、         两种协议区别介绍

Action Script 3.0(简称AS)开发Browser Player时,需要用NetStream,但现在NetStream.play只支持HttpFile两种协议。上网检查youtubetudouyouku,发现他们用的播放协议也都是Http。而以Flash Media Server(简称FMS)或Red5作为流媒体服务器时,它们提供的是RTMP协议,且这两种流媒体服务器是专门做过优化的。这两种协议,HTTPRTMP,有几点不同:

1)用HTTP方式: 先通过IIS FLV下载到本地缓存,然后再通过NetConnection的本地连接来播放这个FLV,这种方法是播放本地的视频,并不是播放服务器的视频。因此在本地缓存里可以找到这个FLV。其优点就是服务器下载完这个FLV,服务器就没有消耗了,节省服务器消耗。其缺点就是FLV会缓存在客户端,对FLV的保密性不好。

2)用RTMP方式: 通过NetConnection连接到FMS/Red5服务器,并实时播放服务器的FLV文件,这种方式可以任意选择视频播放点,并不象HTTP方式需要缓存完整个FLV文件到本地才可以任意选择播放点,其优点就是在本地缓存里是找不到这个FLV文件的。其优点就是FLV不会缓存在客户端,FLV的保密性好,其缺点就是消耗服务器资源,连接始终是实时的。

由以上分析可以知道,Http方式是本地播放,而RTMP方式是服务器实时播放。

 

二、         AS介绍

AS 3.0开始采用面向对象的设计,而在运行速度上也有了很大的提高。在面向对象的基础上,AS也采纳了类C#JavaPackagenamespace逻辑组织结构,更方便于RIA的开发。

       AS通常可以在3种环境下进行开发。

(1)       文本编辑器和编译器。

安装AS的编译器,利用记事本等文本编辑器进行开发,保存为AS文件后进行编译即可。通常可以利用Ant组织编译生成swf

(2)       利用Adobe Flash CS 3进行开发

AdobeMacromedia并入旗下后,便推出了不同于以往Macromedia Flash 8.0版本号的Adobe Flash CS 3。在Flash CS3中,用户可以方便的将设计FLASH场景、图层等同编写AS脚本相结合。同时,由于Flash CS3内置了很多Flash控件,用户可以将通过fl.control这个开发包方便的使用这些控件。

(3)       利用Flex Builder 3进行开发

这是一种基于EclipseIDE,熟悉Eclipse的用户可以像编写Java程序一样来编写AS。同时Flex Builder 3的主要功能是为基于Flex框架程序提供了良好的开发环境。若需要在Flex Builder 3AS工程中使用内置的控件,首先需要将Flash CS3中的标准库导入到场景中,然后发布成为swc文件。最后将此swc文件导入到AS的编译路径中即可。

 

三、基于ASFlv Player

(1)           自行编写Flv Player

编写Flv Player仅需要对AS相关NetStream操作部分有些了解, HTMLJS的基础知识。下面是一个基本的范例:

package {

    import fl.controls.Button;

    import flash.display.Sprite;

    import flash.events.*;

    import flash.media.Video;

    import flash.net.NetConnection;

    import flash.net.NetStream;

    import flash.text.TextField;

 

    public class Player extends Sprite

    {

       private var _width:int;

       private var _height:int;

      

       private var _stream:NetStream;

        private var _connection:NetConnection;

        private var _video:Video;

        private var _playbackTime:TextField = new TextField();

        private var _duration:uint;

        private var _info:TextField = new TextField();

       

        private var btStart:Button = new Button();

       private var btStop:Button = new Button();

       private var btPause:Button = new Button();

      

       private var movie:String = "";

       private var status:Boolean = true;

      

       public function Player()

       {

           initialize();

          

           var param:Object = root.loaderInfo.parameters;

           movie = String(param["movie"]);

          

           _info.y = 360;

           this.addChild(_info);                    

       }

      

       private function initialize():void{

           _connection = new NetConnection();

           _connection.connect(null);

          

           _stream = new NetStream(_connection);

           _stream.addEventListener(NetStatusEvent.NET_STATUS, onStatus);

           _stream.bufferTime = 10;

          

           _video = new Video();

           this.addChild(_video);

           _video.attachNetStream(_stream);

          

           var client:Object = new Object(  );

            client.onMetaData = onMetaData;

            _stream.client = client;

            _playbackTime.y = 300;

            addChild(_playbackTime);

            addEventListener(Event.ENTER_FRAME, onEnterFrame);

           

            btStart.label = "start";

            btStart.y = 300;

            btStart.x = 0;

            btStart.addEventListener(MouseEvent.CLICK, startButtonAction);

            addChild(btStart);

           

            btStop.label = "stop";

            btStop.y = 300;

            btStop.x = 120;

            btStop.addEventListener(MouseEvent.CLICK, stopButtonAction);

            addChild(btStop);

           

            btPause.label = "pause";

            btPause.y = 300;

            btPause.x = 240;

            btPause.addEventListener(MouseEvent.CLICK, pauseButtonAction);         

           addChild(btPause);

       }

      

       private function startButtonAction(e:MouseEvent):void{

           _stream.play(movie);

       }

      

       private function stopButtonAction(e:MouseEvent):void{

           _stream.close();

       }

      

       private function pauseButtonAction(e:MouseEvent):void{

           if(status){

              _stream.pause();

              status = false;

           }else{

              _stream.resume();

              status = true;

           }

       }

      

       private function onMetaData(data:Object):void {

            _duration = data.duration;

        }

       

        private function onEnterFrame(event:Event):void {

            if(_duration > 0 && _stream.time > 0) {

                _playbackTime.text = Math.round(_stream.time) + " / " +

                Math.round(_duration);

            }

        }

       

        private function onStatus(event:NetStatusEvent):void {

        if(_video.videoWidth > 0 && _video.width != _video.videoWidth) {

            _width = _video.videoWidth;

            _height = _video.videoHeight;

           

            var param:Object = root.loaderInfo.parameters;

             

              var widthString:String = String(param["width"]);

              var heightString:String = String(param["height"]);

             

              var width:int = -1;

              var height:int = -1;

             

              if(widthString != "undefined"){

                  width = int(widthString);

              }

             

              if(heightString != "undefined"){

                  height = int(heightString);

               }

             

              if(width == -1){

                  if(height == -1){

                     _video.width = _width;

                     _video.height = _height;

                  }else{

                     _video.height = height;

                     _video.width = _width * height / _height;

                  }

              }else{

                     _video.width = width;

                     _video.height = _height * width / _width;

              }

        }

       }

    }

}

(2)           使用开源的Flv player

推荐使用Flowplayer,可以下载它的源代码,同样是利用ant进行编译。但是需要注意的是,需要进行简单的修改。

build.properties文件中修改MTASC_BINSWFMILL_BIN的值

//MTASC_BIN=/opt/mtasc/mtasc

MTASC_BIN=bin/mtasc/mtasc.exe

// You should use swfmill version 0.2.11 (will not work with the newer version)

//SWFMILL_BIN=/usr/local/bin/swfmill

SWFMILL_BIN=bin/swfmill/swfmill.exe

    skinbuild.xml文件中

<target name="set-os-swfmill-bin">

        <condition property="os_swfmill_bin"

value="${SWFMILL_BIN}"

else="${SWFMILL_BIN}">

<!--原来是value="${SWFMILL_BIN_WIN}" else="${SWFMILL_BIN}" -->

            <os family="windows"/>

        </condition>

    </target>

       将更改后,执行ant即可,就可以得到重新编译好的flowplayer

       当需要更改播放器皮肤,特别是需要将播放器皮肤提示信息的英文改为中文,即修改skin.as部分代码,这时候就必须要重新编译了。

 

四、支持RTMP协议的Red5 Server

Red5Java实现的一种开源的Flash流媒体服务器,它支持FLVMP3格式的Streaming Audio/VideoFLV格式的Recording Client Stream、共享对象、实时流发布等多种功能。

当使用Red5作为Server时,需要完成客户端和服务器端两部分的工作。在服务器端,写自己的应用程序,即rtmp服务的提供。这个应用程序的入口应该extends ApplicationAdapter这个类,然后将它部署到Server上。服务器端示例代码如下:

import org.red5.server.adapter.ApplicationAdapter;

public class Application extends ApplicationAdapter {

public Double add(Double a, Double b){

return a + b;

}

}

在客户端由AS完成,去访问服务器端构造的服务,示例代码如下

nc = new NetConnection();

nc.connect("rtmp://localhost/myapp");

nc.onResult = function(obj) {

trace("The result is " + obj);

}

nc.call("add", nc, 1, 2);

这样就完成了基本的实现了AS通过RTMP协议调用Red5 服务器端所提供的服务。更多的具体内容,可以参考Red5文档去实践。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多