當(dāng)然,Flv格式視屏也是可以播放的。
推薦參考文檔:http://livedocs.adobe.com/fms/2/docs/wwhelp/wwhimpl/common/html/wwhelp.htm?context=LiveDocs_Parts&file=00000788.html
目前自己也是初學(xué)者,不過希望分享一下,如果是高手,就大可在此打住(*^__^*) 嘻嘻……。
先看下效果:

實(shí)現(xiàn)的幾個(gè)基本功能:
第一 和javascript交互,顯示進(jìn)度。
第二 實(shí)現(xiàn)自動(dòng)播放下一首
當(dāng)然 當(dāng)你點(diǎn)擊播放按鈕他肯定要能切換歌曲。
功能很簡(jiǎn)單了。不過還是有很多細(xì)節(jié)要注意的,呵呵。
我們先分析一下ActionScript需要用到的幾個(gè)類,以及構(gòu)建流程。
NetConnection -> NetStream
就這兩個(gè)核心類。其中關(guān)鍵是時(shí)間的處理。通常NetStream有比如 NetSream.Player.Start事件,這些很重要。我們貼出部分代碼:
publicfunction init():void {
registerJavaScriptFunction();
createConnection();
}
privatefunction registerJavaScriptFunction():void
{
ExternalInterface.addCallback("pauseAndResume_flex",pauseAndResume);
ExternalInterface.addCallback("stop_flex",stop);
ExternalInterface.addCallback("play_flex",play);
MSG("注冊(cè)函數(shù)給javascript用");
}
privatefunction createConnection():void {
NetConnection.defaultObjectEncoding =
flash.net.ObjectEncoding.AMF0;
connection = new NetConnection();
connection.connect(streamLink);
connection.addEventListener
(NetStatusEvent.NET_STATUS,netStatusHandler);
connection.addEventListener
(SecurityErrorEvent.SECURITY_ERROR,securityErrorHandler);
connection.addEventListener(AsyncErrorEvent.ASYNC_ERROR,onBWDone);
MSG("創(chuàng)建Connection以及注冊(cè)必要的監(jiān)聽器");
}
代碼格式稍微有點(diǎn)亂,Word用的不行。
init是初始化函數(shù),主要注冊(cè)javascript回調(diào)函數(shù)以及創(chuàng)建Connnection連接。
connection.connect(streamLink)中的streamLink是類似于rtmp://ip//name的地址。ActionScript面向?qū)ο蟛糠趾芟?/span>C#或者Java,不過動(dòng)態(tài)性方面則和javascript一樣,很酷。
初始化后就要通過NetStream連接具體的對(duì)象了(對(duì)了前面的事件處理函數(shù)函數(shù)比如securityErrorHandler之類的,我們放在后面講).
privatefunction connectStream():void {
stream = new
NetStream(connection);
stream.bufferTime=15;
stream.addEventListener(NetStatusEvent.NET_STATUS,netStatusHandler);
var nsClient:Object = {};
nsClient.onMetaData =
ns_onMetaData;
nsClient.onCuePoint =
ns_onCuePoint;
nsClient.onPlayStatus=ns_ononPlayStatus;
video.attachNetStream(stream);
stream.client = nsClient;
//uic.setActualSize(320,240);
uic.addChild(video);
MSG("NetStream創(chuàng)建完畢");
// addChild(video);
}
需要注意的是,nsClient.onPlayStatus=ns_ononPlayStatus;也就是onPlayStatus事件還是蠻重要的。通常事件,比如NetStream.Play.Start
NetStream.Play.Stop(嚴(yán)格來看這些當(dāng)然不是事件,而只是時(shí)間發(fā)布時(shí)附帶的一個(gè)標(biāo)志),但Adobe得開發(fā)人員不知道吃錯(cuò)藥了還是怎么著,把NetStream.Play.Complete 和NetStream.Play.Switch放到了OnPlayStatus屬性中。
很多人都以為Complete事件簿其作用呢。
現(xiàn)在我們看看在Connection以及NetStream的創(chuàng)建過程中安裝的監(jiān)聽器的具體處理。
privatefunction ns_ononPlayStatus(item:Object):void
{
for (var prop in item) {
MSG(""t"+prop+":"t"+item[prop]);
if(item[prop]== "NetStream.Play.Complete")
{
if(interval!=0)
{
clearInterval(interval);
}
MSG("完成播放"+this.linkName);
noticeJavascript();
}
}
}
privatefunction netStatusHandler(event:NetStatusEvent):void {
switch (event.info.code) {
case"NetConnection.Connect.Success":
connectStream();
break;
case"NetStream.Play.StreamNotFound":
Alert.show("沒有找到媒體");
case"NetStream.Play.Stop":
{
MSG("已近停止播放"+this.linkName);
if(interval!=0)
{
clearInterval(interval);
}
MSG(stream.time+"--"+(duration-2))
if (stream.time >
duration-2){
MSG("完成播放"+this.linkName);
noticeJavascript();
}
}
case"NetStream.Play.Start":
{
interval=setInterval(configProgressBar,300);
}
default:
//message.text+=""n"+("netStatusHandler:code:
" + event.info.code);
break;
}
}
還有幾個(gè)回調(diào)事件函數(shù),你可以給個(gè)空實(shí)現(xiàn),這不影響。
要實(shí)現(xiàn)自動(dòng)播放下一首,必須觸發(fā)NetStream.Play.Complete事件,當(dāng)然你也可以用Stop模擬,方式如下(有人成功過,我沒有):
If(stream.time>duration-2)
{
MSG(“播放結(jié)束”)
}
個(gè)人做過試驗(yàn),該方法似乎不起作用,歌曲播放結(jié)束后time要小于duration很多。網(wǎng)上有人說可以通過上面的模擬。大家可以自己嘗試一下。
播放結(jié)束后,可以通知javascript播放結(jié)束,這個(gè)時(shí)候回調(diào)一個(gè)noticeJavascript函數(shù)通知javascript.JavaScript則調(diào)用Flex的Play函數(shù),這樣可以輕松實(shí)現(xiàn)連續(xù)播放。當(dāng)然這種便利性得利于Flex與Javascript的良好交互性。他們之間的調(diào)用可以參考官方文檔。我這里給出基本用法。
注冊(cè)一個(gè)函數(shù)讓Javascipt調(diào)用的格式:
ExternalInterface.addCallBack(“給javascript調(diào)用的函數(shù)名”,Flex中的函數(shù)名);
調(diào)用一個(gè)Javascript函數(shù)的方式則更簡(jiǎn)單直觀:
ExternalInterface.call(“javascript函數(shù)名”,參數(shù));
參數(shù)是個(gè)不定參數(shù),可以任意多個(gè),不過記得順序需要和Javascript申明的一樣。
自動(dòng)播放解決了。那么在html頁面顯示歌曲精度問呢。細(xì)心的話,大家在前面應(yīng)該看到這一段代碼:
interval=setInterval(configProgressBar,300);
我們調(diào)用了一個(gè)每隔300毫秒執(zhí)行的一個(gè)configProgressBar的函數(shù),該函數(shù)內(nèi)部調(diào)用了Javascript函數(shù)繪制界面。
內(nèi)部代碼為:
buffer_bar.setProgress(stream.bufferLength/stream.bufferTime*290
as Number,290);
time_b.setProgress(stream.time/duration*290
as Number,290);
ExternalInterface.call("setProgressBar",stream.time,duration,stream.bufferLength,stream.bufferTime);
這樣進(jìn)度繪制的問題就解決了。
前面的停止播放暫停很簡(jiǎn)單,大家可以看看源碼。
之前我遇到一個(gè)問題,每次播放當(dāng)用戶手動(dòng)播放某一首歌曲的時(shí)候,如何停掉前面的一首歌曲,當(dāng)時(shí)有兩個(gè),通過netStream.close()關(guān)閉流,但不關(guān)閉connection.第二種則是通過netStream.play(false)讓后再播放另一首,我嘗試過似乎都可以,但是第一種會(huì)導(dǎo)致進(jìn)度繪制停頓,沒鬧明白什么原因,初步猜測(cè)應(yīng)該是監(jiān)聽器注冊(cè)地問題,可能需要將監(jiān)聽器重新注冊(cè)一遍。
先寫到這吧。在上班的時(shí)候?qū)懙模悬c(diǎn)急,不過我會(huì)不斷地修改這篇文章。大家有時(shí)間也可以共同修改。