播放本地mp4文件
使用NetStream+Video
大致流程如下:
1. 实例化NetConnection对象,在其上添加“NetStatusEvent.NET_STATUS”事件监听,监听到“NetConnection.Connect.Success”码后做下一步。
2. 实例化NetStream对象,指定它的“client”和“videoStreamSettings”属性,在其上添加“NetStatusEvent.NET_STATUS”事件监听。在这步,NetConnection实例是NetStream构造方法的必要参数。”client”参数可以指定多个回调方法,可以处理流或者文件的信息或者状态。本示例中就在获取MP4文件后,对其文件编码格式做了检查;在视频播放完毕后,根据设置做了是否回放的操作。
3. 添加视频可视化组件到显示列表。
4. 播放视频。
关键点:
如何判断视频播放完?
虽然监听NetStream实例上的“NetStatusEvent.NET_STATUS”事件,能捕获到“NetStream.Play.Stop”状态,但此时对NetStream实例调用seek、resume等操作,程序变得不正常。正确的做法是在“client”的“onPlayStatus”回调中监听到“NetStream.Play.Complete”时,做上述操作,这样处理,视频回放自然。
<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
width="1000" height="900"
applicationComplete="windowedapplication1_applicationCompleteHandler(event)">
<fx:Script>
<![CDATA[
import mx.events.FlexEvent;
import spark.components.VideoDisplay;
protected var _netConnection:NetConnection;
protected var _netStream:NetStream;
protected var _video:Video;
protected var _videoDisplay:VideoDisplay;
protected var _customClient:Object;
protected var _isFristInsert:Boolean = false;
protected var _isLoad:Boolean = false;
protected var _totalPosition:Number = 0;// 视频总时长
protected var _multiMediaUrl:String="C:\\\Users\\\yourname\\\Desktop\\\34A68E1A-AA4B-D2C5-59E9-BDBC18D8108E.mp4";// 视频url地址
private var _isLoop:Boolean=false;
protected function windowedapplication1_applicationCompleteHandler(event:FlexEvent):void
{
this._netConnection = new NetConnection();
this._netConnection.addEventListener(NetStatusEvent.NET_STATUS,netConnectionStatusHandler);
this._netConnection.connect(null);
}
protected function netConnectionStatusHandler(event:NetStatusEvent):void
{
if(event.info.code == "NetConnection.Connect.Success")
{
this._netConnection.removeEventListener(NetStatusEvent.NET_STATUS,netConnectionStatusHandler);
this._customClient = new Object();
this._customClient.onMetaData = metaDataHandler;
this._customClient.onPlayStatus = playStausHandler;
this._netStream = new NetStream(this._netConnection);
this._netStream.client = this._customClient;
this._netStream.videoStreamSettings = this.h264Setting();
this._netStream.addEventListener(NetStatusEvent.NET_STATUS,netStreamStausHandler);
this._video = new Video();
if(!this._isFristInsert)
{
this._video.width = this.width;
this._video.height = this.height;
}
this._video.attachNetStream(this._netStream);
this._video.smoothing = true;
this._videoDisplay = new VideoDisplay();
this._videoDisplay.addChild(this._video);
this.addEventListener(FlexEvent.UPDATE_COMPLETE, updateCompleteLoaded);
this.videoGroup.addElement(this._videoDisplay);
}
}
private function metaDataHandler(infoObject:Object):void
{
if(this._isFristInsert)
{
try
{
if(infoObject.width >= 0)
{
}
else
{
// 不是h264格式视频
}
}
catch(e:Error)
{
// 不是h264格式视频
}
this._isFristInsert = false;
}
this._totalPosition = infoObject.duration;
}
private function playStausHandler(e:Object):void
{
trace("playStausHandler:"+e.code);
if(e.code== "NetStream.Play.Complete")
{
// 播放到最末端
this._netStream.seek(0);
this._netStream.pause();
// 如果需要循环播放,则从头开始播放
if(_isLoop)
{
this._netStream.resume();
}
}
}
protected function h264Setting():H264VideoStreamSettings
{
var h264Settings:H264VideoStreamSettings = new H264VideoStreamSettings();
h264Settings.setProfileLevel(H264Profile.MAIN,H264Level.LEVEL_5_1);
h264Settings.setMode(1280,720,24);
h264Settings.setQuality(0,80);
return h264Settings;
}
protected function netStreamStausHandler(evt:NetStatusEvent):void
{
trace(evt.info.code);
if(evt.info.code == "NetStream.Play.Start")
{
}
else if(evt.info.code == "NetStream.Play.StreamNotFound")
{
}
}
protected function updateCompleteLoaded(event:FlexEvent):void
{
if(this._netStream)
{
this._netStream.play(this._multiMediaUrl);
this._netStream.bufferTime = 5;
this.removeEventListener(FlexEvent.UPDATE_COMPLETE, updateCompleteLoaded);
//this._isLoadVideoComplete = true;
}
}
protected function button1_clickHandler(event:MouseEvent):void
{
this._netStream.togglePause();
}
protected function checkbox1_changeHandler(event:Event):void
{
// TODO Auto-generated method stub
this._isLoop=!this._isLoop;
}
]]>
</fx:Script>
<s:VGroup width="100%" height="100%">
<s:HGroup width="100%" height="60">
<s:Button label="播放/暂停" click="button1_clickHandler(event)"/>
<s:CheckBox label="是否循环播放" change="checkbox1_changeHandler(event)"/>
</s:HGroup>
<s:Spacer height="30"/>
<s:HGroup id="videoGroup" width="100%" height="600">
</s:HGroup>
</s:VGroup>
</s:WindowedApplication>