基于AS3丶FMS。对视频音频流的发布做一次总结。

点击右边的链接,可以先体验下:http://www.vini123.com/chatroom/

在视频音频流的发布前,先得做好第一步,NetConnecttion的连接。

然后,开始才开始视频音频流的发布。先创建一个NetStream对象,其包含一个参数就是NetConnection。

再获取摄像头,麦克风。设置摄像头,麦克风。将摄像头,麦克风附着到流上。如果是摄像头,还得建立一个Video对象,将摄像头也附着到Video对象上,使得自己也能看见视频。因为Video对象会添加到显示列表中。除非你不添加上去。

最后,发布流。


可以将视频流音频流放在一个流(NetStream)里边发布,也可以分开发布。NetStream发布流,有两个参数,第一个参数是流的名字,第二个参数是发布的类型。
有效值是“record”、“append”、“appendWithGap”和“live”。默认值为“live”。

如果传递“record”,则服务器将发布并录制实时数据,同时将录制的数据保存到名称与传递给 name 参数的值相匹配的新文件中。如果该文件存在,则覆盖该文件。
如果传递“append”,则服务器将发布并录制实时数据,同时将录制的数据附加到名称与传递给 name 参数的值相匹配的文件中。如果未找到与 name 参数相匹配的文件,则创建一个文件。
如果您传递“appendWithGap”,则会传递关于时间协调的其他信息,以帮助服务器在动态流式处理时确定正确的转换点。
如果省略此参数或传递“live”,则服务器将发布实时数据而不进行录制。如果存在名称与传递给 name 参数的值相匹配的文件,则删除它。

因为仅仅是针对FMS的流发布,设置比较简单,相应的API也比较少。

流发布了,在多客户端的情况下。其他客户端应该就能看到视频和音频。其他客户端通过NetStream来播放流,而达到看到视频,听到音频的功能。

发布和播放流code:

package com.vini123.net
{
    import com.vini123.client.FMSClient;
    import com.vini123.client.FMSEr;
    import com.vini123.controller.Controller;
    import com.vini123.event.FMSEvent;
    
    import flash.display.Sprite;
    import flash.events.EventDispatcher;
    import flash.events.IEventDispatcher;
    import flash.media.Camera;
    import flash.media.Microphone;
    import flash.media.SoundCodec;
    import flash.media.SoundTransform;
    import flash.media.Video;
    import flash.net.NetStream;
    import flash.net.NetStreamPlayOptions;
    
    public class MediaStream extends EventDispatcher
    {
        private var _videoContainer:Sprite;
        private var _fmser:FMSEr;
        
        private var _nsVideo:NetStream;
        private var _nsAudio:NetStream;
        private var _cam:Camera;
        private var _mic:Microphone;
        private var _video:Video;
        private var _soundTransform:SoundTransform;
        private var _netStreamOptions:NetStreamPlayOptions;
        
        public function MediaStream(target:IEventDispatcher=null)
        {
            super(target);
            
            FMSClient.instance.addEventListener(FMSEvent.HAS_PUBLISH , hasPublish);
            FMSClient.instance.addEventListener(FMSEvent.DONOT_PUBLISH , doNotPublish);
        }

        public function set videoContainer(value:Sprite):void
        {
            _videoContainer = value;
        }

        public function start():void
        {
            publishVideo();
            publishAudio();
            Controller.instance.fmser.nc.call("beginPublish" , null, Controller.instance.userName);
        }
        
        public function stop():void
        {
            clearVideoStream();
            clearAudioStream();
            Controller.instance.fmser.nc.call("stopPublish" , null, Controller.instance.userName);
        }
        
        /**
         * 发布流 
         * 
         */        
        private function publishVideo():void
        {
            //var h264Settings:H264VideoStreamSettings = new H264VideoStreamSettings();
            //h264Settings.setProfileLevel(H264Profile.BASELINE, H264Level.LEVEL_5_1);
            //h264Settings.setMode(320,240,15);
            //h264Settings.setQuality(0,100);
            _nsVideo = new NetStream(Controller.instance.fmser.nc);
            _nsVideo.client = this;
            _nsVideo.bufferTime = 0;
            
            _cam = Camera.getCamera();
            if(_cam)
            {
                _cam.setMode(320,240,15,false);
                _cam.setQuality(0,80);
                _cam.setKeyFrameInterval(13);
                _nsVideo.attachCamera(_cam);
                
                _video = new Video();
                _video.attachCamera(_cam);
                _video.width = 320 ;
                _video.height = 240 ;
                _videoContainer.addChild(_video);
                _nsVideo.publish(("video" + Controller.instance.userName) , "live");
            }
        }
        
        private function publishAudio():void
        {
             _nsAudio = new NetStream(Controller.instance.fmser.nc);
            _nsAudio.bufferTime = 0;
            _nsAudio.client = this;
            _mic = Microphone.getMicrophone();
            if(_mic)
            {
                _mic.codec = SoundCodec.SPEEX;
                _mic.encodeQuality = 4 ;
                _mic.framesPerPacket = 1 ;
                _mic.noiseSuppressionLevel = 0;
                _mic.setSilenceLevel(10 , 1000);
                _mic.setUseEchoSuppression(true);
                _mic.setLoopBack(false);
                _mic.rate = 44 ;
                _mic.gain = 50 ;
                _nsAudio.attachAudio(_mic);
            }
            
            _soundTransform = _nsAudio.soundTransform;
            _soundTransform.volume = 0.5 ;
            _nsAudio.soundTransform = _soundTransform;
            _nsAudio.publish(("audio" + Controller.instance.userName),"live");
        }
        
        private function clearVideoStream(clearPublish:Boolean = false):void
        {
            if(_nsVideo)
            {
                _video.clear();
                _video = null;
                _cam = null;
                _nsVideo.close();
                _nsVideo = null;
            }
        }
        
        private function clearAudioStream(clearPublish:Boolean = false):void
        {
            if(_nsAudio)
            {
                _mic = null;
                _nsAudio.close();
                _nsAudio = null;
            }        
        }
        
        /**
         *  播放流 
         */    
        
        public function playVideo(userName:String):void
        {
            clearVideoStream();
            
            _nsVideo = new NetStream(Controller.instance.fmser.nc);
            _video = new Video() ;
            _video.width = 320 ;
            _video.height = 240 ;
            _video.attachNetStream(_nsVideo);
            _nsVideo.play("video" + userName);
            _videoContainer.addChild(_video);
        }
        
        public function playAudio(userName:String):void
        {
            clearAudioStream();
            _nsAudio = new NetStream(Controller.instance.fmser.nc);
            _nsAudio.play("audio" + userName);
        }
        
        private function hasPublish(e:FMSEvent):void
        {
            var userName:String = e.data as String ;
            if(userName != Controller.instance.userName)
            {
                playVideo(e.data as String);
                playAudio(e.data as String);
                Controller.instance.hidePublishButton();
            }
        }
        
        private function doNotPublish(e:FMSEvent):void
        {
            var userName:String = e.data as String ;
            if(userName != Controller.instance.userName)
            {
                clearVideoStream();
                clearAudioStream();
                Controller.instance.showPublishButton();
            }
        }
    }
}

官方API:http://help.adobe.com/zh_CN/FlashPlatform/reference/actionscript/3/flash/media/Camera.html
请关注getCamera(),setKeyFrameInterval() 等方法。