Flash Webcam Capture - actionscript-3

I am trying to build AS3 web audio/video capture. I have successfully tried to display the webcam stream with the help of this great tutorial. The next step is how do i capture the video when the user starts recording. Below is my code:
// video stuff
private var camW:int = 300;
private var camH:int = 300;
private var video:Video;
// block stuff
private var rows:int = 3;
private var cols:int = 3;
private var blockW:int = camW/cols;
private var blockH:int = camH/rows;
private var pointArray:Array = new Array();
public function Main():void {
// Checks if camera is installed
if (Camera.names.length > 0) {
trace("User has at least one camera installed.");
var camera:Camera = Camera.getCamera();
camera.setMode(camW, camH, 30);
camera.addEventListener(StatusEvent.STATUS, statusHandler);
video = new Video(camW, camH);
video.attachCamera(camera);
initBlocks();
addEventListener(Event.ENTER_FRAME, updateBlocks);
}else {
trace("User has no cameras installed.");
var text:TextField = new TextField();
text.text = "Device Not Found! Please check if the camera is installed.";
text.x = 20;
text.y = 20;
text.width = 500;
addChild(text);
}
function statusHandler(event:StatusEvent):void {
// This event gets dispatched when the user clicks the "Allow" or "Deny"
// button in the Flash Player Settings dialog box.
trace(event.code); // "Camera.Muted" or "Camera.Unmuted"
switch (event.code) {
case "Camera.Muted":
trace("User clicked Deny.");
var text:TextField = new TextField();
text.text = "Device Denied Permission! Please provide permission to record video!";
text.x = 20;
text.y = 20;
text.width = 500;
addChild(text);
break;
case "Camera.Unmuted":
trace("User clicked Accept.");
break;
}
}
}
private function initBlocks():void {
for (var r:int = 0; r < rows; r++) {
for (var c:int = 0; c < cols; c++) {
var newBlock:Sprite = new Sprite();
newBlock.name = "block" + r + c;
var p:Point = new Point(c * blockW, r * blockH);
newBlock.x = c * (blockW) + 20;
newBlock.y = r * (blockH) + 20;
pointArray[newBlock.name] = p;
var bmpd:BitmapData = new BitmapData(blockW, blockH);
var bmp:Bitmap = new Bitmap(bmpd);
bmp.name = "myBmp";
newBlock.addChild(bmp);
addChild(newBlock);
}
}
}
private function updateBlocks(e:Event):void {
var srcBmpd:BitmapData = new BitmapData(camW, camH);
srcBmpd.draw(video);
for (var r:int = 0; r < rows; r++) {
for (var c:int = 0; c < cols; c++) {
var b_mc:Sprite = this.getChildByName("block" + r + c) as Sprite;
var bmp:Bitmap = b_mc.getChildByName("myBmp") as Bitmap;
var p:Point = pointArray[b_mc.name];
bmp.bitmapData.copyPixels(srcBmpd, new Rectangle(p.x, p.y, blockW, blockH), new Point());
}
}
}
I am completely new to AS3, just started 2 days ago. What is the logic for audio/video capture in AS3? Any pointers/demo/tutorials/books appreciated

I had a very difficult time getting to work on the flash webcam recording. And as couple of posts here ( this one ) suggested to use some kind of flash servers like the Adobe Flash Server / Red5 Server. I did the same. I installed Red5 Server ( Please make sure you use the right JRE for the server to run smoothly after installation - as i had problems installing the demos ) and used Flex with FlashDevelop IDE ( Use Flex 3 Project to create a new project ). Here's below working sample code:
Main.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Script source="Main.as"/>
<mx:VideoDisplay width="300" height="300" autoPlay="true" creationComplete="initCamera()" id="video"></mx:VideoDisplay>
<mx:Button label="Record" click="startRecording()" />
<mx:Button label="Stop" click="stopRecording()" />
</mx:Application>
Main.as
/**
* ...
* #author VishwaKumar
*/
import flash.events.NetStatusEvent;
import flash.media.Microphone;
import flash.net.NetConnection;
import flash.net.NetStream;
import mx.controls.Alert;
import flash.media.Camera;
import flash.media.Video;
import flash.display.Sprite;
public var camera:Camera;
public var nc:NetConnection;
public var ns:NetStream;
public var mic:Microphone;
public function initCamera():void {
var camW:int = 300;
var camH:int = 300;
if (Camera.names.length > 0) {
camera = Camera.getCamera();
camera.setMode(camW, camH, 30);
video.attachCamera(camera);
mic = Microphone.getMicrophone();
}else {
Alert.show("Device Not Found! Please check if the camera is installed.","Hardware Error!");
}
}
public function startRecording():void {
nc = new NetConnection();
nc.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler);
nc.connect("rtmp://127.0.0.1/oflaDemo");
}
public function netStatusHandler(event:NetStatusEvent):void {
trace(event.info.code);
switch(event.info.code) {
case "NetConnection.Connect.Success":
ns = new NetStream(nc);
ns.publish("test","record");
ns.attachAudio(mic);
ns.attachCamera(camera);
break;
default :
Alert.show("NetConnection.Connect.error");
break;
}
}
public function stopRecording():void {
ns.close();
}

Related

Stage dimensions in a new NativeWindow

i'm building a flash desktop App where the user clicks on a button and opens a SWF file (a game) in a new window, i used a NativeWindow to achieve it, i did the folowing:
var windowOptions:NativeWindowInitOptions = new NativeWindowInitOptions();
windowOptions.systemChrome = NativeWindowSystemChrome.STANDARD;
windowOptions.type = NativeWindowType.NORMAL;
var newWindow:NativeWindow = new NativeWindow(windowOptions);
newWindow.stage.scaleMode = StageScaleMode.NO_SCALE;
newWindow.stage.align = StageAlign.TOP_LEFT;
newWindow.bounds = new Rectangle(100, 100, 2000, 800);
newWindow.activate();
var aLoader:Loader = new Loader;
aLoader.load(new URLRequest(path));
newWindow.stage.addChild(aLoader);
the result is this:
the game doesn't take the whole space available. When i change the "NO_SCALE" to "EXACT_FIT":
newWindow.stage.scaleMode = StageScaleMode.EXACT_FIT;
i got this:
it only shows the top-left corner of the game. I also tried "SHOW_ALL" and "NO_BORDER". I got the same result as "EXACT_FIT".
When i open the SWF file of the game separatly it's displayed normally:
any idea how can i display the SWF game as the image above?
The best solution for that is to have the dimensions of your external game in pixel. you have to stretch the loader to fit it in your stage. if you are try to load different games with different sizes to your stage, save the swf dimensions with their URL addresses.
var extSWFW:Number = 550;
var extSWFH:Number = 400;
var extURL:String = "./Data/someSwf.swf";
var mainStageWidth:Number = 1024;
var mainStageHeight:Nubmer = 768;
var aLoader:Loader = new Loader;
aLoader.load(new URLRequest(extURL));
newWindow.stage.addChild(aLoader);
aLoader.scaleY = aLoader.scaleX = Math.min(mainStageWidth/extSWFW,mainStageHeight/extSWFH);
It is not very difficult to figure dimensions of a loaded SWF because it is engraved into it's header, you can read and parse it upon loading. Here's the working sample:
package assortie
{
import flash.display.Loader;
import flash.display.Sprite;
import flash.events.Event;
import flash.geom.Rectangle;
import flash.net.URLRequest;
import flash.utils.ByteArray;
public class Dimensions extends Sprite
{
private var loader:Loader;
public function Dimensions()
{
super();
loader = new Loader;
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoaded);
loader.load(new URLRequest("outer.swf"));
}
private function onLoaded(e:Event):void
{
var aBytes:ByteArray = loader.contentLoaderInfo.bytes;
var aRect:Rectangle = new Rectangle;
var aRead:BitReader = new BitReader(aBytes, 8);
var perEntry:uint = aRead.readUnsigned(5);
aRect.left = aRead.readSigned(perEntry) / 20;
aRect.right = aRead.readSigned(perEntry) / 20;
aRect.top = aRead.readSigned(perEntry) / 20;
aRect.bottom = aRead.readSigned(perEntry) / 20;
aRead.dispose();
aRead = null;
trace(aRect);
}
}
}
import flash.utils.ByteArray;
internal class BitReader
{
private var bytes:ByteArray;
private var position:int;
private var bits:String;
public function BitReader(source:ByteArray, start:int)
{
bits = "";
bytes = source;
position = start;
}
public function readSigned(length:int):int
{
var aSign:int = (readBits(1) == "1")? -1: 1;
return aSign * int(readUnsigned(length - 1));
}
public function readUnsigned(length:int):uint
{
return parseInt(readBits(length), 2);
}
private function readBits(length:int):String
{
while (length > bits.length) readAhead();
var result:String = bits.substr(0, length);
bits = bits.substr(length);
return result;
}
static private const Z:String = "00000000";
private function readAhead():void
{
var wasBits:String = bits;
var aByte:String = bytes[position].toString(2);
bits += Z.substr(aByte.length) + aByte;
position++;
}
public function dispose():void
{
bits = null;
bytes = null;
}
}

Duplicating video Stream Actionscript 3

Good Morning,
i am working on a video class, using a CRTMP Server for streaming. This works fine, but for my solution i need to duplicate the video stream (for some effects).
I googled for duplicate MovieClips and tried to duplicate the video like this.
import flash.display.*;
import flash.events.*;
import flash.net.*;
import flash.media.*;
import flash.system.*;
import flash.utils.ByteArray;
public class Main extends MovieClip
{
public var netStreamObj:NetStream;
public var nc:NetConnection;
public var vid:Video;
public var vid2:Video;
public var streamID:String;
public var videoURL:String;
public var metaListener:Object;
public function Main()
{
init_RTMP();
}
private function init_RTMP():void
{
streamID = "szene3.f4v";
videoURL = "rtmp://213.136.73.230/maya";
vid = new Video(); //typo! was "vid = new video();"
vid2 = new Video();
nc = new NetConnection();
nc.addEventListener(NetStatusEvent.NET_STATUS, onConnectionStatus);
nc.addEventListener(AsyncErrorEvent.ASYNC_ERROR, asyncErrorHandler);
nc.client = {onBWDone: function():void
{
}};
nc.connect(videoURL);
}
private function onConnectionStatus(e:NetStatusEvent):void
{
if (e.info.code == "NetConnection.Connect.Success")
{
trace("Creating NetStream");
netStreamObj = new NetStream(nc);
metaListener = new Object();
metaListener.onMetaData = received_Meta;
netStreamObj.client = metaListener;
netStreamObj.play(streamID);
vid.attachNetStream(netStreamObj);
//vid2.attachNetStream(netStreamObj); // wont work
addChild(vid);
// addChild(vid2); // wont work either
//intervalID = setInterval(playback, 1000);
}
}
private function asyncErrorHandler(event:AsyncErrorEvent):void
{
trace("asyncErrorHandler.." + "\r");
}
private function received_Meta(data:Object):void
{
var _stageW:int = stage.stageWidth;
var _stageH:int = stage.stageHeight;
var _videoW:int;
var _videoH:int;
var _aspectH:int;
var Aspect_num:Number; //should be an "int" but that gives blank picture with sound
Aspect_num = data.width / data.height;
//Aspect ratio calculated here..
_videoW = _stageW;
_videoH = _videoW / Aspect_num;
_aspectH = (_stageH - _videoH) / 2;
vid.x = 0;
vid.y = _aspectH;
vid.width = _videoW;
vid.height = _videoH;
vid2.x = 0;
vid2.y = _aspectH ;
}
}
It should be possible to duplicate the video stream. 2 Instance of the same videoStream. What am i doing wrong ?
Thanks for help.
"This means that i have to double the netstream. This is not what i want."
"I tried to duplicate the video per Bitmap.clone. But i got an sandbox violation."
You can try the workaround suggested here: Netstream Play(null) Bitmapdata Workaround
I'll show a quick demo of how it can be applied to your code.
This demo code assumes your canvas is width=550 & height=400. Keep that ratio if scaling up.
package
{
import flash.display.*;
import flash.events.*;
import flash.net.*;
import flash.media.*;
import flash.system.*;
import flash.utils.ByteArray;
import flash.geom.*;
import flash.filters.ColorMatrixFilter;
public class Main extends MovieClip
{
public var netStreamObj:NetStream;
public var nc:NetConnection;
public var vid:Video;
public var streamID:String;
public var videoURL:String;
public var metaListener:Object;
public var vid1_sprite : Sprite = new Sprite();
public var vid2_sprite : Sprite = new Sprite();
public var vid2_BMP : Bitmap;
public var vid2_BMD : BitmapData;
public var colMtx:Array = new Array(); //for ColorMatrix effects
public var CMfilter:ColorMatrixFilter;
public function Main()
{
init_RTMP();
}
private function init_RTMP():void
{
streamID = "szene3.f4v";
videoURL = "rtmp://213.136.73.230/maya";
vid = new Video();
nc = new NetConnection();
nc.addEventListener(NetStatusEvent.NET_STATUS, onConnectionStatus);
nc.addEventListener(AsyncErrorEvent.ASYNC_ERROR, asyncErrorHandler);
nc.client = { onBWDone: function():void { } };
//nc.connect(null); //for file playback
nc.connect(videoURL); //for RTMP streams
}
private function onConnectionStatus(e:NetStatusEvent):void
{
if (e.info.code == "NetConnection.Connect.Success")
{
trace("Creating NetStream");
netStreamObj = new NetStream(nc);
metaListener = new Object();
metaListener.onMetaData = received_Meta;
netStreamObj.client = metaListener;
//netStreamObj.play("vid.flv"); //if File
netStreamObj.play(streamID); //if RTMP
vid.attachNetStream(netStreamObj);
}
}
private function asyncErrorHandler(event:AsyncErrorEvent):void
{
trace("asyncErrorHandler.." + "\r");
}
private function received_Meta(data:Object):void
{
trace("Getting metadata");
var _stageW:int = stage.stageWidth;
var _stageH:int = stage.stageHeight;
var _videoW:int = data.width;
var _videoH:int = data.height;
var _aspectH:int = 0;
var Aspect_num:Number;
Aspect_num = data.width / data.height;
//Aspect ratio calculated here..
_videoW = _stageW;
_videoH = _videoW / Aspect_num;
_aspectH = (_stageH - _videoH) / 2;
trace("_videoW : " + _videoW);
trace("_videoW : " + _videoH);
trace("_aspectH : " + _aspectH);
vid.x = 0;
vid.y = 0;
vid.width = _videoW;
vid.height = _videoH;
setup_Copy(); //# Do this after video resize
}
public function setup_Copy () : void
{
vid2_BMD = new BitmapData(vid.width, vid.height, false, 0);
vid2_BMP = new Bitmap( vid2_BMD );
vid1_sprite.addChild(vid);
vid1_sprite.x = 0;
vid1_sprite.y = 0;
addChild( vid1_sprite );
vid2_sprite.addChild( vid2_BMP );
vid2_sprite.x = 0;
vid2_sprite.y = vid.height + 5;
addChild( vid2_sprite );
stage.addEventListener(Event.ENTER_FRAME, draw_Video);
}
public function draw_Video (evt:Event) : void
{
if ( netStreamObj.client.decodedFrames == netStreamObj.decodedFrames ) { return; } // Here we skip multiple readings
//# Get bitmapdata directly from container of video
if ( vid1_sprite.graphics.readGraphicsData().length > 0 )
{
vid2_BMD = GraphicsBitmapFill(vid1_sprite.graphics.readGraphicsData()[0]).bitmapData;
}
effect_BitmapData(); //# Do an effect to bitmapdata
}
public function effect_BitmapData ( ) : void
{
//# Matrix for Black & White effect
colMtx = colMtx.concat([1/3, 1/3, 1/3, 0, 0]); // red
colMtx = colMtx.concat([1/3, 1/3, 1/3, 0, 0]); // green
colMtx = colMtx.concat([1/3, 1/3, 1/3, 0, 0]); // blue
colMtx = colMtx.concat([0, 0, 0, 1, 0]); // alpha
CMfilter = new ColorMatrixFilter(colMtx);
vid2_BMP.bitmapData.applyFilter(vid2_BMD, new Rectangle(0, 0, vid.width, vid.height), new Point(0, 0), CMfilter);
}
}
}

Dynamic Gallery to show download and progress bar in as3

My flash project has specific task to show the dynamic gallery items based on an XML list and there is a download option available for each gallery item.
For this I made a movieclip (imageTile) with a Thumbnail, Title, ProgressBar & ProgressText as shown below.
I have two classes named Main.as and FileRef.as
Main.as
var tileMap:Dictionary = new Dictionary();
public var tile:ImageTile;
addChild(wall);
wallWidth = wall.width;
wallHeight = wall.height;
var columns:Number;
var my_x:Number;
var my_y:Number;
var my_thumb_width:Number;
var my_thumb_height:Number;
var images:XMLList;
var total:Number;
var swipe:Number = 0;
var myXMLLoader:URLLoader = new URLLoader();
myXMLLoader.load(new URLRequest("gallery.xml"));
myXMLLoader.addEventListener(Event.COMPLETE, processXML);
function processXML(e:Event):void {
myXML = new XML(e.target.data);
images = myXML.IMAGE;
total = images.length();
myXMLLoader.removeEventListener(Event.COMPLETE, processXML);
myXMLLoader = null;
var loader:Loader;
for (var i:uint = 0; i < total; i++) {
tile = new ImageTile();
wall.addChild(tile);
tile.x = i % 3 * 400 + 180;
tile.y = Math.floor(i / 3) * 650 + 250;
var imageName:String = images[i].#FULL;
path = images[i].#Path;
var title:String = images[i].#Title;
**var caption:TextField = tile.getChildByName("caption_tf") as TextField;**
caption.text = title;
tile.addEventListener(MouseEvent.CLICK, onTileClick(path));
loader = new Loader();
loader.load(new URLRequest("images/" + imageName));
tileMap[loader] = tile;
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onImageLoad);
}
//trace(myXML);
}
var tileMap:Dictionary = new Dictionary();
function onImageLoad(e:Event):void {
var loader:Loader = e.target.loader;
var tile:ImageTile = tileMap[loader] as ImageTile;
var image:Bitmap = loader.content as Bitmap;
image.x = -100;
image.y = -100;
image.width=366;
image.height=418;
var textField:DisplayObject = tile.getChildByName("caption_tf");
var textFieldDepth:int = tile.getChildIndex(textField);
tile.addChildAt(image, textFieldDepth);
tileMap[loader] = null;
image.smoothing = true;
}
function onTileClick(url:String):Function {
return function(me:MouseEvent):void {
path = url;
var download:FileRef = new FileRef();
download.downloadFile(path);
}
FileRef.as code
public var mc_loaded : MovieClip = Main.gameInstance.tile.getChildByName("mc_loaded") as MovieClip,
mc_progress : MovieClip = Main.gameInstance.tile.getChildByName("mc_progress") as MovieClip,
txt_prog : TextField = Main.gameInstance.tile.getChildByName("txt_prog") as TextField;
public function downloadFile(url:String) : void
{
/// Download the gallery item codes using url
}
public function progressHandler( event : ProgressEvent ) : void
{
//mc_loaded.scaleX = (event.bytesLoaded / event.bytesTotal) ;
}
public function completeHandler( event : Event ) : void
{
//reset progress bar after download is finished
mc_loaded.scaleX = 0; // I want to use the imageTile element
txt_prog.text = "download finished";
}
public function OnZipComplete(evt:flash.events.Event):void
{
txt_prog.text = "download finished";
}
The download works fine, but I can not get the progress bar and progress text for every tile created.
I got the answer
Remove onTileClick(url:String) function from Main.as
Main.as
function processXML(e:Event):void {
//// Codes /////
//// Codes /////
var download:FileRefTut = new FileRefTut();
tile.addEventListener(MouseEvent.CLICK, download.downloadFile(path));
}
FileRef.as
public var txt_prog:TextField, mc_loaded:MovieClip;
public function downloadFile(url:String):Function {
return function(me:MouseEvent):void {
var tile:ImageTile = me.currentTarget as ImageTile;
txt_prog = tile.getChildByName("txt_prog") as TextField;
mc_loaded = tile.getChildByName("mc_loaded") as MovieClip;
}
public function progressHandler( event : ProgressEvent ) : void
{
mc_loaded.scaleX = (event.bytesLoaded / event.bytesTotal) ;
}
public function completeHandler( event : Event ) : void
{
//reset progress bar after download is finished
mc_loaded.scaleX = 0; // I want to use the imageTile element
txt_prog.text = "download finished";
}
public function OnZipComplete(evt:flash.events.Event):void
{
txt_prog.text = "download finished";
}

Webcam shows mirror image using action script

Using Flash CS5.5 and action script 3 I have made a small application for image capturing through web cam and integrated it in php page working perfect also save image. But problem is it shows MIRROR image on screen means if I move my right hand on screen it shows left hand. My query is how can I correct this setting. Here is the code -
package take_picture_fla
{
import com.adobe.images.*;
import flash.display.*;
import flash.events.*;
import flash.media.*;
import flash.net.*;
import flash.ui.*;
import flash.utils.*;
dynamic public class MainTimeline extends MovieClip
{
public var capture_mc:MovieClip;
public var bitmap:Bitmap;
public var rightClickMenu:ContextMenu;
public var snd:Sound;
public var video:Video;
public var bitmapData:BitmapData;
public var warn:MovieClip;
public var save_mc:MovieClip;
public var bandwidth:int;
public var copyright:ContextMenuItem;
public var cam:Camera;
public var quality:int;
public function MainTimeline()
{
addFrameScript(0, frame1);
return;
}// end function
public function onSaveJPG(event:Event) : void
{
var myEncoder:JPGEncoder;
var byteArray:ByteArray;
var header:URLRequestHeader;
var saveJPG:URLRequest;
var urlLoader:URLLoader;
var sendComplete:Function;
var e:* = event;
sendComplete = function (event:Event) : void
{
warn.visible = true;
addChild(warn);
warn.addEventListener(MouseEvent.MOUSE_DOWN, warnDown);
warn.buttonMode = true;
return;
}// end function
;
myEncoder = new JPGEncoder(100);
byteArray = myEncoder.encode(bitmapData);
header = new URLRequestHeader("Content-type", "application/octet-stream");
saveJPG = new URLRequest("save.php");
saveJPG.requestHeaders.push(header);
saveJPG.method = URLRequestMethod.POST;
saveJPG.data = byteArray;
urlLoader = new URLLoader();
urlLoader.addEventListener(Event.COMPLETE, sendComplete);
urlLoader.load(saveJPG);
return;
}// end function
public function warnDown(event:MouseEvent) : void
{
navigateToURL(new URLRequest("images/"), "_blank");
warn.visible = false;
return;
}// end function
function frame1()
{
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;
rightClickMenu = new ContextMenu();
copyright = new ContextMenuItem("Developed By www.webinfopedia.com Go to Application");
copyright.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, myLink);
copyright.separatorBefore = false;
rightClickMenu.hideBuiltInItems();
rightClickMenu.customItems.push(copyright);
this.contextMenu = rightClickMenu;
snd = new camerasound();
bandwidth = 0;
quality = 100;
cam = Camera.getCamera();
cam.setQuality(bandwidth, quality);
cam.setMode(320, 240, 30, false);
video = new Video();
video.attachCamera(cam);
video.x = 20;
video.y = 20;
addChild(video);
bitmapData = new BitmapData(video.width, video.height);
bitmap = new Bitmap(bitmapData);
bitmap.x = 360;
bitmap.y = 20;
addChild(bitmap);
capture_mc.buttonMode = true;
capture_mc.addEventListener(MouseEvent.CLICK, captureImage);
save_mc.alpha = 0.5;
warn.visible = false;
return;
}// end function
public function captureImage(event:MouseEvent) : void
{
snd.play();
bitmapData.draw(video);
save_mc.buttonMode = true;
save_mc.addEventListener(MouseEvent.CLICK, onSaveJPG);
save_mc.alpha = 1;
return;
}// end function
public function myLink(event:Event)
{
navigateToURL(new URLRequest("http://www.webinfopedia.com/export-database-data-to-excel-in-php.html"), "_blank");
return;
}// end function
}
}
You can just use video.scaleX = -1; to mirror the image.
You should check your camera's settings at the system level - it is possible that the device driver is set to mirror the image.

flash actionscript error 5007 while file is not linked or included in any way

I created an xfl file called myfile.xfl and linked it to Main.as.
Because my script is kind of extensive, I planned to distribute it over several as-files.
The Main.as looks like this and is linked correctly from the xfl-file:
package {
import flash.net.URLLoader;
import flash.net.URLRequest;
import flash.xml.*;
import flash.events.Event;
import flash.display.Loader;
import flash.display.LoaderInfo;
import flash.display.MovieClip;
import flash.text.*;
import flash.events.MouseEvent;
import flash.media.Sound;
import flash.media.SoundChannel;
public class Main extends MovieClip
{
var bestand:String;
var titelFont:Font = new Titelfont();
var werkFont:Font = new Werkfont();
var titelfmt:TextFormat = new TextFormat();
var werkfmt:TextFormat = new TextFormat();
var inputfmt:TextFormat = new TextFormat();
var snd:Sound;
var cnl:SoundChannel = new SoundChannel();
var xmlLoader:URLLoader;
var myList:XML;
var introClip:Containerclip = new Containerclip();
var dicteeClip:Containerclip = new Containerclip();
public function Main()
{
//DE INFORMATIE UIT DE URL //
//bestand = LoaderInfo(this.root.loaderInfo).parameters["bestand"];
//bestand += ".xml";
bestand = "xml/bron.xml"
loadXml();
}
function loadXml():void
{
xmlLoader = new URLLoader(new URLRequest(bestand));
xmlLoader.addEventListener(Event.COMPLETE,xmlLoaded);
}
function xmlLoaded(event:Event):void
{
myList = new XML(event.target.data);
myList.ignoreWhite = true;
createTextFormat();
createIntro();
createDictee();
createResultaten();
}
include "CreateStuff.as"
include "Dictee.as"
}
}
You can see my includes at the end: createstuff.as and dictee.as.
I was working on a third include, called Sound.as, and tried to preview my file when error 5007 popped up. "5007: An ActionScript file must have at least one externally visible definition"
I removed the include Sound.as line from my Main.as, thinking that must have cause the problem for some reason. When I republished the error popped up again, and flash automatically reopened the Sound.as file. While there is no link from anywhere to it anymore.
My other files are CreateStuff.as :
function createTextFormat() : void {
titelfmt.size = 32;
titelfmt.color = 0x003399;
titelfmt.font = titelFont.fontName;
werkfmt.size = 24;
werkfmt.color = 0x000000;
werkfmt.font = werkFont.fontName;
inputfmt.size = 32;
inputfmt.color = 0x333333;
inputfmt.font = werkFont.fontName;
//inputfmt.
}
function createTextfield (fmt) : TextField {
var tf:TextField = new TextField();
tf.defaultTextFormat = fmt;
if (fmt == titelfmt) {
tf.multiline = false;
tf.autoSize = "center";
tf.selectable = false;
tf.y = 10;
tf.x = stage.stageWidth / 2;
} else if (fmt == werkfmt) {
tf.autoSize = "left";
tf.multiline = true;
} else if (fmt == inputfmt) {
tf.multiline = true;
tf.width = 300;
tf.height = 40;
tf.border = true;
tf.borderColor = 0xCCCCCC;
tf.type = TextFieldType.INPUT;
}
return (tf);
}
function createIntro() : void {
introClip.x = 0;
introClip.y = 0;
introClip.name = "introClip";
var nttf:TextField = createTextfield(titelfmt);
nttf.text = "Instructie"
introClip.addChild(nttf);
var itf:TextField = createTextfield(werkfmt);
itf.text = "Wat weet jij nog?\nLuister naar de woorden.\nSchrijf ze op.";
itf.width = 300;
itf.x = stage.stageWidth / 2 - 150;
itf.y = 120;
itf.selectable = false;
introClip.addChild(itf);
var startBtn:Beginknop = new Beginknop();
startBtn.x = stage.stageWidth / 2 - startBtn.width / 2;
startBtn.y = 300;
startBtn.addEventListener(MouseEvent.CLICK, showDictee);
introClip.addChild(startBtn);
addChild(introClip);
}
function createResultaten() : void {
}
And Dictee.as :
function createDictee () : void {
dicteeClip.x = 0;
dicteeClip.y = 0;
var nttf:TextField = createTextfield(titelfmt);
nttf.text = "Dictee"
dicteeClip.addChild(nttf);
var iptf:TextField = createTextfield(inputfmt);
iptf.x = 135;
iptf.y = 205;
dicteeClip.addChild(iptf)
var dicteeSpeaker:Luidspreker = new Luidspreker();
dicteeSpeaker.x = stage.stageWidth / 2 - dicteeSpeaker.width/2;
dicteeSpeaker.y = iptf.y - dicteeSpeaker.height - 40;
//dicteeSpeaker.addEventListener (MouseEvent.CLICK, playSnd);
dicteeSpeaker.name = dicteeSpeaker;
dicteeClip.addChild(dicteeSpeaker);
var volgendeKnop:Controleknop = new Controleknop();
volgendeKnop.x = iptf.x + iptf.width + 30;
volgendeKnop.y = iptf.y;
dicteeClip.addChild(volgendeKnop);
}
function showDictee(event:MouseEvent) : void {
addChild(dicteeClip);
removeChild(introClip);
speelDictee();
}
function speelDictee() : void {
//bepaal geluid
//afspelen geluid
//volgende knop-actie
}
I initially called the file Sound.as but thought the error might come from that Sound is a reserved word, so I changed it to Sounds.as
I'm well out of my depth here and I have no clue why the error pops up. Or the file Sound.as while it is not linked.
My flash version is Flash-CC but the tag doesn't exist yet so I couldn't specify it in the tags.
#5007 is commonly caused by
Not correctly using a package
Including an import statement any level below the package level
I'm answering this question because for some reason the error disappeared and I have no idea why. I don't want to leave it open, I'd prefer to delete it as it's of no use to anyone but I'm not sure how to do that.