這是以 ActionScript 啟動 FLVPlayback 組件所有按鈕功能的範例,除了設定組件檢測器外,還可以用這種方式播放 FLV 影片。以最簡易作法盡可能達到最佳影片播放效果是本篇重點。
關於 FLVPlayback Skin 因為是全功能 FLV 播放器,因此選擇 SkinUnderAll(SkinOverAll 有可能擋住預設字幕)
FLVPlayback skin 可在以下位置找到:
Adobe\Adobe Flash CS4\Common\Configuration
本機測試可以這樣搞(使用正斜線),但測試結束一定要改掉,僅限本機測試使用。
FLVPlayback.skin = "C:/Program Files/Adobe/Adobe Flash CS4/Common/Configuration/FLVPlayback Skins/ActionScript 3.0/SkinOverPlaySeekMute.swf";
關於全螢幕 FLVPlayback 的全螢幕按鈕不需設定,只要在嵌入 swf 的 Html 上設定全螢幕即可。
IE, Firefox, Chrome 皆能接受的 Fullscreen for Flash 語法:
<object width="400" height="300" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=10,0,0,0"> <param name="wmode" value="transparent"> <param name="allowFullscreen" value="true"> <param name="quality" value="high"> <param name="movie" value="sample.swf"> <embed width="400" height="300" allowFullscreen="true" quality="high" src="sample.swf" pluginspage="http://www.macromedia.com/go/getflashplayer" type="application/x-shockwave-flash"></embed> </object>關於字幕 字幕內建 autoLayout 屬性為 true,它可以讓 Flash 自動控制字幕位置,若改為 false 切換到全螢幕時要重新設定字幕位置,為了以最簡易的方式控制字幕,這裡開啟 autoLayout,並採用 SkinUnderAll 避免擋到字幕(使用 Under 系列 Skin 需預留播放器位置,需將 Flash 高度調高 36 pixel),在切換全螢幕時字幕會有小飄移,可能是 autoLayout 的 Bug。
將新細明體當作影片字幕真的是慘不忍睹,至少要換成微軟正黑體(或系統有的黑體字型),另外 Time Text XML 語法 tts:FontFamily 無法順利指定字型,改在 CaptionChangeEvent 設定,美中不足的是,字幕首行要空著才不會露出破綻。
FLVPlayback.fla(先將 FLVPlayback, FLVPlaybackCaptioning 組件拉到元件庫) import fl.video.FLVPlayback; import fl.video.FLVPlaybackCaptioning; import fl.video.CaptionChangeEvent; var fpb:FLVPlayback = new FLVPlayback(); fpb.width = 400; fpb.height = 300; fpb.skin = "SkinUnderAll.swf"; fpb.source = "wii.flv"; fpb.skinBackgroundColor = 0x00004F; fpb.autoPlay = false; fpb.skinAutoHide = false; fpb.addEventListener(VideoEvent.COMPLETE, completeHandler); addChild(fpb); var fpbcap:FLVPlaybackCaptioning = new FLVPlaybackCaptioning(); fpbcap.source = "Caption.xml"; fpbcap.flvPlayback = fpb; fpbcap.addEventListener(CaptionChangeEvent.CAPTION_CHANGE,onCaptionChange); addChild(fpbcap); function completeHandler(event:VideoEvent):void{ fpb.seek(0); } function onCaptionChange(event:CaptionChangeEvent):void { var captxt:TextField = event.target.captionTarget; var captf:TextFormat = new TextFormat(); var captxtDropShadow:DropShadowFilter = new DropShadowFilter(2, 45, 0x000000, 25, 3, 3, 2, 2); captf.font = "微軟正黑體"; captxt.defaultTextFormat = captf; captxt.filters = [captxtDropShadow]; }Caption.xml <?xml version="1.0" encoding="UTF-8"?> <tt xml:lang="zh-TW" xmlns="http://www.w3.org/2006/04/ttaf1" xmlns:tts="http://www.w3.org/2006/04/ttaf1#styling"> <head> <styling> <style id="myStyle" tts:FontFamily="Arial" tts:backgroundColor="transparent" tts:fontSize="14" tts:fontWeight="bold" tts:textAlign="center"/> </styling> </head> <body> <div xml:lang="en"> <p begin="00:00:00.10" style="myStyle"></p> <p begin="00:00:01.00" style="myStyle">影片開始</p> <p begin="00:00:03.30" style="myStyle">這是 Wii 早期的宣傳影片</p> <p begin="00:00:08.30" style="myStyle">示範 AS3 播放 FLV 加上字幕的作法</p> <p begin="00:00:16.00" style="myStyle">打桌球</p> <p begin="00:00:22.00" style="myStyle">煮菜</p> <p begin="00:00:28.50" style="myStyle">演奏</p> <p begin="00:00:33.70" style="myStyle">太鼓達人</p> <p begin="00:00:36.70" style="myStyle">打棒球</p> <p begin="00:00:39.50" style="myStyle">釣魚</p> <p begin="00:00:45.20" style="myStyle">??</p> <p begin="00:00:51.00" style="myStyle">超級瑪莉</p> <p begin="00:00:58.00" style="myStyle">特異功能啟動</p> <p begin="00:01:04.00" style="myStyle">鬼屋探險</p> <p begin="00:01:10.30" style="myStyle">四人對戰</p> <p begin="00:01:18.50" style="myStyle">槍戰</p> <p begin="00:01:26.00" style="myStyle">打蚊子</p> <p begin="00:01:35.00" style="myStyle">武士決鬥</p> <p begin="00:01:43.50" style="myStyle">電話來了...</p> <p begin="00:01:51.00" style="myStyle">非常神奇</p> <p begin="00:01:54.00" style="myStyle">Wii</p> <p begin="00:02:00.00" style="myStyle">示範結束</p> </div> </body> </tt>相關連結:
Adobe Flash Professional * Use Timed Text captions (Time Text XML)
Raie
2010/05/12 14:49
2010/05/12 14:49
Trackback Address :: http://blog.raienet.com/trackback/442
錯誤訊息
*** Security Sandbox Violation *** SecurityDomain 'http://test.com/test1.swf' 嘗試存取不相容的內容 'file:///C|/website/test2.swf'
發生原因 為了安全性理由,Flash 不允許跨網域存取,需加入安全性語法以啟用跨網域存取。
解決方式 允許 test.com 網域存取(不含 http to https)
Security.allowDomain("test.com");允許所有網域存取(不含 http to https)
Security.allowDomain("*");允許 http 連接 https 的存取方式
Security.allowInsecureDomain ("*");相關連結:
ActionScript 3.0 語言和組件參考,Security
Raie
2010/05/12 14:24
2010/05/12 14:24
Trackback Address :: http://blog.raienet.com/trackback/443
[Flash] http://raienet.com/amfphp/services/swf2swf/parent.swf
ActionScript3 如何在 swf 之間互相傳遞變數呢? 首先你要瞭解的是,Parent.swf 載入 Child.swf,它們之間是父子關係 = = 這裡的做法是將父子swf 都拉到場景之中,然後在按鈕的同時交換信物,大致上是這樣的狀況。
Parent.fla(先將 Button 組件拉到元件庫)import fl.controls.Button;
var childSWF:MovieClip; var Parentvar:String = "parent variable";
//Parent TextField(上方, 準備置入Child Variable) var ParentTF:TextField = new TextField(); ParentTF.y = 60; addChild(ParentTF);
//Button var btn:Button = new Button(); btn.move(20,20); btn.label = "Passing Variables"; btn.addEventListener(MouseEvent.CLICK, clickBtn); addChild(btn);
//swf載入 var loader:Loader = new Loader(); var urlrequest:URLRequest=new URLRequest("Child.swf"); loader.load(urlrequest); loader.contentLoaderInfo.addEventListener(Event.COMPLETE, LoadComplete); loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
//swf載入成功時, 顯示子swf在父swf上(調低子swf,以避免疊在一起擋到按鈕) function LoadComplete(event:Event):void{ childSWF = event.target.content; childSWF.y = 80; addChild(childSWF); } //偵錯 function ioErrorHandler(event:IOErrorEvent):void { ParentTF.text = "ioErrorHandler: " + event; }
//按鈕後, 父子swf互換變數 function clickBtn(e:MouseEvent):void{ //呼叫父swf Variable, 傳到子swf TextField if (childSWF != null){ childSWF.SetParentValue(Parentvar); } //呼叫子swf Variable, 傳到父swf TextField if (childSWF != null){ ParentTF.text = childSWF.Childvar; } }
Child.fla var Childvar:String = "child variable";
//Child TextField(下方, 準備置入 Parent Variable) var ChildTF:TextField = new TextField(); addChild(ChildTF);
function SetParentValue(string:String):void{ ChildTF.text = string; }
Raie
2010/05/08 16:44
2010/05/08 16:44
Trackback Address :: http://blog.raienet.com/trackback/440
此錯誤發生在你呼叫 Loader.load() 方法的時候,找不到你要載入的檔案,並且因為程式缺少 IOErrorEvent 偵錯事件時會收到此錯誤。若你有建立 Loader 的 IOErrorEvent 偵錯事件時,即可得到正確的錯誤訊息回饋。
每次建立 Loader.load() 同時,也應依下列方式建立 IOErrorEvent 偵錯事件(舉例):
loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler); function ioErrorHandler(event:Event):void{ trace("ioErrorHandler: "+event); }
Raie
2010/05/08 16:25
2010/05/08 16:25
Trackback Address :: http://blog.raienet.com/trackback/441
[Flash] http://blog.raienet.com/attach/1/1227882343.swf
滑鼠拖曳和鍵盤控制(W:上 , S:下 , A:左 , D:右),請先點選圓形讓 Flash 成為瀏覽器焦點。
var mc:Sprite = new Sprite(); function Control_mc(){ init(); } function init():void{ mc.buttonMode = true; mc.graphics.lineStyle(2); mc.graphics.beginFill(0xFFCC00); mc.graphics.drawCircle(0,0,50); mc.x = 200; mc.y = 150; addChild(mc); mc.addEventListener(MouseEvent.MOUSE_DOWN, onMyMouseDown); stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyboardEvent); } //滑鼠事件 function onMyMouseDown(event:MouseEvent):void{ stage.addEventListener(MouseEvent.MOUSE_UP, onMyMouseUp); mc.startDrag(false, new Rectangle(50, 50, 300, 200)); } function onMyMouseUp(event:MouseEvent):void{ stage.removeEventListener(MouseEvent.MOUSE_UP, onMyMouseUp); mc.stopDrag(); } //鍵盤事件 function onKeyboardEvent(event:KeyboardEvent):void{ switch(event.keyCode) { case 87:if (mc.y > 50){mc.y -= 5}break; case 83:if (mc.y < 250){mc.y += 5}break; case 65:if (mc.x > 50){mc.x -= 5}break; case 68:if (mc.x < 350){mc.x += 5}break; default:break; } } Control_mc();
不用方向鍵理由在於瀏覽器以方向鍵控制捲軸,Flash 與作業系統或瀏覽器按鍵衝突時,Flash 將處於劣勢。
Raie
2007/08/16 17:29
2007/08/16 17:29
Trackback Address :: http://blog.raienet.com/trackback/358
[Flash] http://blog.raienet.com/attach/1/1393123020.swf
var i:int; var mc_number:int = 10; function duplicate_mc(){ init(); } function init():void { var myTimer:Timer = new Timer(1000); myTimer.addEventListener(TimerEvent.TIMER, onMyTimer); myTimer.start(); } function onMyTimer(event:TimerEvent):void { i++; var mc:Sprite = new Sprite(); mc.graphics.lineStyle(2,0x000000,0.4); mc.graphics.beginFill(0xFFCC00,0.4); mc.graphics.drawCircle(0,0,10); mc.x = stage.stageWidth/2 + Math.random()*200-100; mc.y = stage.stageHeight/2 + Math.random()*200-100; addChild(mc); if (i > mc_number){ removeChild(getChildAt(getChildIndex(mc)-mc_number)); } } duplicate_mc();
聽說 AS2 的 duplicateMovieClip() 不能用了,所以首先想到要試的就是複製了,其實這麼改也很合理(無限複製時請別忘了用 removeChild() 移除喔),另試用了 AS3 新類別 Timer。
Raie
2007/08/15 03:12
2007/08/15 03:12
Trackback Address :: http://blog.raienet.com/trackback/357
[Flash] http://blog.raienet.com/attach/1/1259740437.swf
var mc:Sprite = new Sprite(); var goback:int = 0; function moveCircle() { init(); } function init():void { mc.graphics.lineStyle(2,0x000000); mc.graphics.beginFill(0xFFCC00); mc.graphics.drawCircle(0,0,50); mc.graphics.endFill(); addChild(mc); mc.x = 200; mc.y = stage.stageHeight / 2; mc.addEventListener(Event.ENTER_FRAME, onMyEnterFrame); } function onMyEnterFrame(event:Event):void { if (mc.x > 250){ goback = 1; } else if (mc.x < 150){ goback = 0; } if (goback == 0){ mc.x += 2; } else { mc.x -= 2; } } moveCircle();
init() 初始化讓程式更容易控制。a = a + 2 縮寫→ a += 2;i = i + 1 縮寫→ i++ 。
Raie
2007/08/14 03:05
2007/08/14 03:05
Trackback Address :: http://blog.raienet.com/trackback/356
[Flash] http://blog.raienet.com/attach/1/1376646496.swf
function createCircle(x1,y1,r1,borderSize1,borderColor1,bgColor1){ var mc1:Shape = new Shape(); mc1.graphics.lineStyle(borderSize1,borderColor1); mc1.graphics.beginFill(bgColor1); mc1.graphics.drawCircle(x1,y1,r1); mc1.graphics.endFill(); addChild(mc1); } function createEllipse(x2,y2,w2,h2,borderSize2,borderColor2,bgColor2){ var mc2:Shape = new Shape(); mc2.graphics.lineStyle(borderSize2,borderColor2); mc2.graphics.beginFill(bgColor2); mc2.graphics.drawEllipse(x2,y2,w2,h2); mc2.graphics.endFill(); addChild(mc2); } createCircle(100,150,50,2,0x000000,0xFFCC00); createEllipse(240,110,120,80,2,0x000000,0xFFCC00);
好簡單喔 T_T .. 圓的定位點在圓心,橢圓定位點和矩形相同,都在左上角。endFill()封閉路徑並填滿顏色,在這裡非必要,也是寫繪圖程式的好習慣。
Raie
2007/08/10 11:13
2007/08/10 11:13
Trackback Address :: http://blog.raienet.com/trackback/355
[Flash] http://blog.raienet.com/attach/1/1209488003.swf
var mytxt:TextField = new TextField(); //建立文字框 mytxt.border = true; mytxt.text = "HelloWorld"; mytxt.x = 150; mytxt.y = 20; mytxt.visible = false; addChild(mytxt); function createRect(x1,y1,w1,h1,borderSize,borderColor,bgColor){ var myButton:Sprite = new Sprite(); //建立按鈕 myButton.buttonMode = true; addChild(myButton); var mc:Shape = new Shape(); //建立形狀 mc.graphics.lineStyle(borderSize, borderColor); mc.graphics.beginFill(bgColor); mc.graphics.drawRect(x1, y1, w1, h1); mc.graphics.endFill(); myButton.addChild(mc); //指定為按鈕 myButton.addEventListener(MouseEvent.CLICK, clickBtn); //建立監聽器 } createRect(150,150,100,40,2,0x000000,0xFFCC00); function clickBtn(myMouseEvent:Event):void{ if (mytxt.visible){ mytxt.visible = false; }else{ mytxt.visible = true; } }
本範例把矩形指定為按鈕,(變數:資料類型) 宣告變數時同時指定資料類型也是寫 ActionScript 的好習慣,以後檢查只要一看就清楚明瞭。
Raie
2007/08/09 18:43
2007/08/09 18:43
Trackback Address :: http://blog.raienet.com/trackback/354
[Flash] http://blog.raienet.com/attach/1/1154574164.swf
function createRect(x1,y1,w1,h1,borderSize,borderColor,bgColor){ var mc:Shape = new Shape(); mc.graphics.lineStyle(borderSize, borderColor); mc.graphics.beginFill(bgColor); mc.graphics.drawRect(x1, y1, w1, h1); mc.graphics.endFill(); addChild(mc); } createRect(150,150,100,40,2,0x000000,0xFFCC00);
看得見的程式還是我的最愛,符合 Flash 的視覺特性,w1 = h1 時圖形為正方形,結尾處不加分號也OK,不過那是編寫程式的良好習慣。
Raie
2007/08/08 14:00
2007/08/08 14:00
Trackback Address :: http://blog.raienet.com/trackback/353