發現:
在之前研究Portfolio Multi Media Tab Gallery的源碼的時候,見到在視頻播放功能的模塊里,有如下結構的代碼:
準備工作:
_netConn = new NetConnection();
_netConn.connect(null);
_metadata = new Object();
_metadata.onMetaData = metaDatadHandler;
_netStrm = new NetStream(_netConn);
_netStrm.client = _metadata;
_netStrm.addEventListener(NetStatusEvent.NET_STATUS, netStrm_netStatusHandler, false, 0, true);
_sizeLsnTimer = new Timer(33, 1);
_sizeLsnTimer.addEventListener(TimerEvent.TIMER, lsnSizeTimerHandler, false, 0, true);
_video = new Video();
_video.attachNetStream(_netStrm);
addChild(_video);
listenForVideoSize方法:
private function listenForVideoSize():void
{
if( _video.videoWidth > 0 && _video.videoHeight )
{
_ognlVidWidth = _video.videoWidth;
_ognlVidHeight = _video.videoHeight;
}
else
{
_sizeLsnTimer.reset();
_sizeLsnTimer.start();
}
}
偵聽視頻元數據的處理方法:
private function metaDatadHandler($info:Object):void
{
if($info.width && $info.height)
{
_ognlVidWidth = Number($info.width);
_ognlVidHeight = Number($info.height);
}
else
{
listenForVideoSize();
}
}
定時器處理方法:
private function lsnSizeTimerHandler($e:TimerEvent):void
{
listenForVideoSize();
}
思路:
首先嘗試利用client對象偵聽到視頻的元數據來獲得視頻的寬與高的信息;如果不成功,那就呼叫listenForVideoSize方法,這個方法會每隔33毫秒運行一次,它嘗試通過video.videoWidth和video.videoHeight來得到寬高信息,直到成功為止。
注意:
這個做法有兩個前提,第一個就是假設metaDataHandler一定會被執行,因為那裡是觸動計時器偵聽的地方;第二個就是假設video.videoWidth和video.videoHeight能提供正確的信息。
實際情況:
把我上次遇見的有問題的flv檔案拿來測試,metaDataHandler方法從未被執行過,所以我將觸動listenForVideoSize的代碼放在NetStatusEvent的處理函數里:
private function netStrm_netStatusHandler($e:NetStatusEvent):void
{
switch ($e.info.code)
{
case "NetStream.Play.Start" :
listenForVideoSize();
break;
}
}
於是我得到一組數據:
meta width: 550
meta height: 402
然後將播放視頻的畫面截圖,放在Photoshop里測量視頻範圍的寬和高,我得到的大小是320×240。所以我不再使用videoWidth和videoHeight,而是直接獲取video自己的寬和高video.width和video.height,得到的結果是320×240。
新發現:
但是,其實上面的結論也是錯誤的,之所以會得出320×240這個數據,是因為Video的構造函數的參數默認值:
所以,即是說,video.width和video.height所提供的信息應該是正確的。