這是以 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)
2010/05/12 14:49 2010/05/12 14:49
2010/05/12 14:49 

錯誤訊息
*** 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
2010/05/12 14:24 2010/05/12 14:24
2010/05/12 14:24 

[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;
}

2010/05/08 16:44 2010/05/08 16:44
2010/05/08 16:44 

사용자 삽입 이미지

此錯誤發生在你呼叫 Loader.load() 方法的時候,找不到你要載入的檔案,並且因為程式缺少 IOErrorEvent 偵錯事件時會收到此錯誤。若你有建立 Loader 的 IOErrorEvent 偵錯事件時,即可得到正確的錯誤訊息回饋。

每次建立 Loader.load() 同時,也應依下列方式建立 IOErrorEvent 偵錯事件(舉例):
loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
function ioErrorHandler(event:Event):void{
trace("ioErrorHandler: "+event);
}
2010/05/08 16:25 2010/05/08 16:25
2010/05/08 16:25 

[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 將處於劣勢。
2007/08/16 17:29 2007/08/16 17:29
2007/08/16 17:29 

[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。
2007/08/15 03:12 2007/08/15 03:12
2007/08/15 03:12 

[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++ 。
2007/08/14 03:05 2007/08/14 03:05
2007/08/14 03:05 

[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()封閉路徑並填滿顏色,在這裡非必要,也是寫繪圖程式的好習慣。
2007/08/10 11:13 2007/08/10 11:13
2007/08/10 11:13 

[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 的好習慣,以後檢查只要一看就清楚明瞭。
2007/08/09 18:43 2007/08/09 18:43
2007/08/09 18:43 

[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,不過那是編寫程式的良好習慣。
2007/08/08 14:00 2007/08/08 14:00
2007/08/08 14:00