Categories |
Categories |
FileReference.upload() function is a handy addition to Flash. In conjunction with server-side language, it can be used to upload files to the server or to a database. In this example, we will use a PHP script to retrieve the file data and save the file onto the server.
Outline:
Example:
// www.permadi.com
import flash.events.MouseEvent;
import flash.net.FileReference;
import flash.net.FileFilter;
import flash.utils.ByteArray;
import flash.events.MouseEvent;
import flash.events.Event;
import flash.events.IOErrorEvent;
import flash.display.MovieClip;
import fl.controls.ProgressBarMode;
var mFileReference:FileReference;
// Setup button to handle browsing
browseButton.buttonMode=true;
browseButton.mouseChildren=false;
browseButton.addEventListener(MouseEvent.CLICK, onBrowseButtonClicked);
// Hide progress bar
progressBar.visible=false;
// This function is called when the BROWSE button is clicked.
function onBrowseButtonClicked(event:MouseEvent):void
{
trace("onBrowse");
mFileReference=new FileReference();
mFileReference.addEventListener(Event.SELECT, onFileSelected);
var swfTypeFilter:FileFilter = new FileFilter("SWF/JPG/PNG Files","*.jpeg; *.jpg;*.gif;*.png");
var allTypeFilter:FileFilter = new FileFilter("All Files (*.*)","*.*");
mFileReference.browse([swfTypeFilter, allTypeFilter]);
}
// This function is called after user selected a file in the file browser dialog.
function onFileSelected(event:Event):void
{
trace("onFileSelected");
// This callback will be called when the file is uploaded and ready to use
mFileReference.addEventListener(Event.COMPLETE, onFileLoaded);
// This callback will be called if there's error during uploading
mFileReference.addEventListener(IOErrorEvent.IO_ERROR, onFileLoadError);
// Optional callback to track progress of uploading
mFileReference.addEventListener(ProgressEvent.PROGRESS, onProgress);
// Tells the FileReference to load the file
mFileReference.load();
if (mFileReference.size > 500*1024)
{
trace("File too big");
}
// Show progress bar
progressBar.visible=true;
progressBar.mode=ProgressBarMode.MANUAL;
progressBar.minimum=0;
progressBar.maximum=100;
}
// This function is called to notify us of the uploading progress
function onProgress(event:ProgressEvent):void
{
var percentLoaded:Number=event.bytesLoaded/event.bytesTotal*100;
trace("loaded: "+percentLoaded+"%");
progressBar.setProgress(percentLoaded, 100);
}
// This function is called after the file has been uploaded.
function onFileLoaded(event:Event):void
{
var fileReference:FileReference=event.target as FileReference;
// These steps below are to pass the data as DisplayObject
// These steps below are specific to this example.
var data:ByteArray=fileReference["data"];
trace("File loaded");
var movieClipLoader:Loader=new Loader();
movieClipLoader.loadBytes(data);
movieClipLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, onMovieClipLoaderComplete);
mFileReference.removeEventListener(Event.COMPLETE, onFileLoaded);
mFileReference.removeEventListener(IOErrorEvent.IO_ERROR, onFileLoadError);
mFileReference.removeEventListener(ProgressEvent.PROGRESS, onProgress);
}
function onFileLoadError(event:Event):void
{
// Hide progress bar
progressBar.visible=false;
mFileReference.removeEventListener(Event.COMPLETE, onFileLoaded);
mFileReference.removeEventListener(IOErrorEvent.IO_ERROR, onFileLoadError);
mFileReference.removeEventListener(ProgressEvent.PROGRESS, onProgress);
browseButton.visible=true;
progressBar.visible=false;
trace("File load error");
}
// This function below is specific to this example.
// It does the processing required to display the swf/png/jpeg file that we have just loaded.
function onMovieClipLoaderComplete(event:Event):void
{
var loadedContent:DisplayObject=event.target.content;
var loader:Loader=event.target.loader as Loader;
// Fit to stage
trace("loadedContent.width="+loadedContent.width);
loadedContent.scaleX=container.width/loadedContent.width;
loadedContent.scaleY=container.height/loadedContent.height;
trace("loadedContent.scaleX="+loadedContent.scaleX);
trace("loadedContent.width="+loadedContent.width);
trace("this.stage.width="+this.stage.width);
container.addChild(loader);
var filename:String=mFileReference.name;
var urlRequest:URLRequest = new URLRequest("uploadFile.php");
urlRequest.method = URLRequestMethod.POST;
browseButton.visible=false;
// Optional callback to track progress of uploading
mFileReference.addEventListener(ProgressEvent.PROGRESS, onProgress);
mFileReference.addEventListener(DataEvent.UPLOAD_COMPLETE_DATA,onUploadComplete);
mFileReference.upload(urlRequest);
}
function onUploadComplete(event:Event):void
{
// Optional callback to track progress of uploading
mFileReference.removeEventListener(ProgressEvent.PROGRESS, onProgress);
mFileReference.removeEventListener(DataEvent.UPLOAD_COMPLETE_DATA,onUploadComplete);
browseButton.visible=true;
progressBar.visible=false;
}
Much of the code above is explained here: http://www.permadi.com/blog/2010/06/flash-as3-using-filereference-to-load-files-example-for-flash-cs4-and-above/. The new additions are code this portion, which calls FileReference.upload().
var filename:String=mFileReference.name;
var urlRequest:URLRequest = new URLRequest("uploadFile.php");
urlRequest.method = URLRequestMethod.POST;
// Optional callback to track progress of uploading
mFileReference.addEventListener(ProgressEvent.PROGRESS, onProgress);
mFileReference.addEventListener(DataEvent.UPLOAD_COMPLETE_DATA,onUploadComplete);
mFileReference.upload(urlRequest);
The code references a php file named uploadFile.php, which is shown below. This uploadFile.php simply copies the file into the same folder.
<?php
$uploadPath = basename( $_FILES['Filedata']['name']);
if (move_uploaded_file($_FILES['Filedata']['tmp_name'], $uploadPath))
{
echo "OK";
}
else
{
echo "ERROR";
}
?>
Notes:
Using FileReference, you can allow user to upload files from their computer to be used. This can be useful in applications such as photo processing applications, image manipulation applications, etc. For more information, see:
http://www.permadi.com/blog/2009/05/actionscript-3-using-file-reference-to-load-local-swf/
Here’s the general outline of the steps required to load a file from user’s computer. Note that these steps require user’s approval, meaning that the user must click a button to “approve” the process.
- Call FileReference.browse() in response to a user action (such as clicking a button).
- Listen to Event.SELECT, which indicates thet the user has selected a file.
- Call FileReference.load() to load the file.
- Listen to Event.COMPLETE, which indicates thet the file is uploaded and ready to use.
This example allows user to select an text file (txt, html, or php) into the application. The example below is written in Flash CS4. The FLA can be downloaded here.
// www.permadi.com
import flash.events.MouseEvent;
import flash.net.FileReference;
import flash.net.FileFilter;
import flash.utils.ByteArray;
import flash.events.MouseEvent;
import flash.events.Event;
import flash.events.IOErrorEvent;
import flash.display.MovieClip;
import fl.controls.ProgressBarMode;
import fl.controls.TextArea;
var mFileReference:FileReference;
// Setup button to handle browsing
browseButton.buttonMode=true;
browseButton.mouseChildren=false;
browseButton.addEventListener(MouseEvent.CLICK, onBrowseButtonClicked);
// Hide progress bar
progressBar.visible=false;
// This function is called when the BROWSE button is clicked.
function onBrowseButtonClicked(event:MouseEvent):void
{
trace("onBrowse");
mFileReference=new FileReference();
mFileReference.addEventListener(Event.SELECT, onFileSelected);
var swfTypeFilter:FileFilter = new FileFilter("Text Files","*.txt; *.html;*.htm;*.php");
var allTypeFilter:FileFilter = new FileFilter("All Files (*.*)","*.*");
mFileReference.browse([swfTypeFilter, allTypeFilter]);
}
// This function is called after user selected a file in the file browser dialog.
function onFileSelected(event:Event):void
{
trace("onFileSelected");
// This callback will be called when the file is uploaded and ready to use
mFileReference.addEventListener(Event.COMPLETE, onFileLoaded);
// This callback will be called if there's error during uploading
mFileReference.addEventListener(IOErrorEvent.IO_ERROR, onFileLoadError);
// Optional callback to track progress of uploading
mFileReference.addEventListener(ProgressEvent.PROGRESS, onProgress);
// Tells the FileReference to load the file
mFileReference.load();
// Show progress bar
progressBar.visible=true;
progressBar.mode=ProgressBarMode.MANUAL;
progressBar.minimum=0;
progressBar.maximum=100;
browseButton.visible=false;
}
// This function is called to notify us of the uploading progress
function onProgress(event:ProgressEvent):void
{
var percentLoaded:Number=event.bytesLoaded/event.bytesTotal*100;
trace("loaded: "+percentLoaded+"%");
progressBar.setProgress(percentLoaded, 100);
}
// This function is called after the file has been uploaded.
function onFileLoaded(event:Event):void
{
var fileReference:FileReference=event.target as FileReference;
// These steps below are to pass the data as DisplayObject
// These steps below are specific to this example.
var data:ByteArray=fileReference["data"];
textArea.text=data.toString();
browseButton.visible=true;
progressBar.visible=false;
mFileReference.removeEventListener(Event.COMPLETE, onFileLoaded);
mFileReference.removeEventListener(IOErrorEvent.IO_ERROR, onFileLoadError);
mFileReference.removeEventListener(ProgressEvent.PROGRESS, onProgress);
}
function onFileLoadError(event:Event):void
{
// Hide progress bar
progressBar.visible=false;
browseButton.visible=true;
mFileReference.removeEventListener(Event.COMPLETE, onFileLoaded);
mFileReference.removeEventListener(IOErrorEvent.IO_ERROR, onFileLoadError);
mFileReference.removeEventListener(ProgressEvent.PROGRESS, onProgress);
trace("File load error");
}
This example allows user to select an image file (PNG, SWF, or JPEG) into the application. The example below is written in Flash CS4. The FLA can be downloaded here.
The code is similar to the first example, the only difference is some additions to display the image.
import flash.events.MouseEvent;
import flash.net.FileReference;
import flash.net.FileFilter;
import flash.utils.ByteArray;
import flash.events.MouseEvent;
import flash.events.Event;
import flash.events.IOErrorEvent;
import flash.display.MovieClip;
import fl.controls.ProgressBarMode;
var mFileReference:FileReference;
// Setup button to handle browsing
browseButton.buttonMode=true;
browseButton.mouseChildren=false;
browseButton.addEventListener(MouseEvent.CLICK, onBrowseButtonClicked);
// Hide progress bar
progressBar.visible=false;
// This function is called when the BROWSE button is clicked.
function onBrowseButtonClicked(event:MouseEvent):void
{
trace("onBrowse");
mFileReference=new FileReference();
mFileReference.addEventListener(Event.SELECT, onFileSelected);
var swfTypeFilter:FileFilter = new FileFilter("SWF/JPG/PNG Files","*.jpeg; *.jpg;*.gif;*.png");
var allTypeFilter:FileFilter = new FileFilter("All Files (*.*)","*.*");
mFileReference.browse([swfTypeFilter, allTypeFilter]);
}
// This function is called after user selected a file in the file browser dialog.
function onFileSelected(event:Event):void
{
trace("onFileSelected");
// This callback will be called when the file is uploaded and ready to use
mFileReference.addEventListener(Event.COMPLETE, onFileLoaded);
// This callback will be called if there's error during uploading
mFileReference.addEventListener(IOErrorEvent.IO_ERROR, onFileLoadError);
// Optional callback to track progress of uploading
mFileReference.addEventListener(ProgressEvent.PROGRESS, onProgress);
// Tells the FileReference to load the file
mFileReference.load();
// Show progress bar
progressBar.visible=true;
progressBar.mode=ProgressBarMode.MANUAL;
progressBar.minimum=0;
progressBar.maximum=100;
browseButton.visible=false;
}
// This function is called to notify us of the uploading progress
function onProgress(event:ProgressEvent):void
{
var percentLoaded:Number=event.bytesLoaded/event.bytesTotal*100;
trace("loaded: "+percentLoaded+"%");
progressBar.setProgress(percentLoaded, 100);
}
// This function is called after the file has been uploaded.
function onFileLoaded(event:Event):void
{
var fileReference:FileReference=event.target as FileReference;
// These steps below are to pass the data as DisplayObject
// These steps below are specific to this example.
var data:ByteArray=fileReference["data"];
trace("File loaded");
mFileReference.removeEventListener(Event.COMPLETE, onFileLoaded);
mFileReference.removeEventListener(IOErrorEvent.IO_ERROR, onFileLoadError);
mFileReference.removeEventListener(ProgressEvent.PROGRESS, onProgress);
browseButton.visible=true;
var movieClipLoader:Loader=new Loader();
movieClipLoader.loadBytes(data);
movieClipLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, onMovieClipLoaderComplete);
}
function onFileLoadError(event:Event):void
{
// Hide progress bar
progressBar.visible=false;
browseButton.visible=true;
mFileReference.removeEventListener(Event.COMPLETE, onFileLoaded);
mFileReference.removeEventListener(IOErrorEvent.IO_ERROR, onFileLoadError);
mFileReference.removeEventListener(ProgressEvent.PROGRESS, onProgress);
trace("File load error");
}
// This function below is specific to this example.
// It does the processing required to display the swf/png/jpeg file that we have just loaded.
function onMovieClipLoaderComplete(event:Event):void
{
// Hide progress bar
progressBar.visible=false;
var loadedContent:DisplayObject=event.target.content;
var loader:Loader=event.target.loader as Loader;
// Fit to stage
trace("loadedContent.width="+loadedContent.width);
loadedContent.scaleX=container.width/loadedContent.width;
loadedContent.scaleY=container.height/loadedContent.height;
trace("loadedContent.scaleX="+loadedContent.scaleX);
trace("loadedContent.width="+loadedContent.width);
trace("this.stage.width="+this.stage.width);
container.addChild(loader);
}
Note:
In order to load a file, user must perform an action such as clicking a button. This is for security reason since no-one would want a Flash application that silently loads something from their hard-drive.
WebM is the new media-container format announced by Google during the Google I/O conference this year. For a broad overview of WebM, see this post: http://www.permadi.com/blog/2010/05/webm-overview/
WebM is based on MKV (Matroska) container format, which uses EBML structure to store informations, tagging and organizing data in hierachial tree-like structure. EBML is a basically binary version (non human readable) of XML, while XML is text-based. For more EBML info, see http://ebml.sourceforge.net/
All WebM files must follow a recommended set of tags to be considered a valid WebM file (for example, a WebM file without the Header element is not valid). For example, every WebM file must at least have two Level 0 elements: an EBML and a Segment element. To best illustrate this, let’s dissect a .webm video file. This file contains an audio and a video track, there is no subtitle track. There are several software that dissects EBML files, two that I used are: MKVInfo (http://www.bunkus.org/videotools/mkvtoolnix/doc/mkvinfo.html) and EBML-Viewer (requires Java): http://code.google.com/p/ebml-viewer/.
Here’s an example of a WebM file, parsed using MKVViewer GUI:
You can see the two Level 0 elments there: EBML and Segment (yes, that is an element name). The EBML element basically tells that the file is actually a valid EBML file, what version is the EBML (so that a parser won’t attempt to read EBML file that it does not support).
Let’s see the Segment element.
As you can see, the Segment element is a lot more complex, but there are four basic elements that a well-formed WebM file should contain:
Level 1 Element: Meta Seek Information (Seek Head element):
This element contains information (offset to the seek position) to other Level 1 elements. The KaxCues sub-element is used for seeking/scrubbing support, so that a player can examine the cues (in WemB, all cues are keyframes) and jump to the nearest one. A Seek Entry can point to another Seek Head, as you see in the example, denoted by KaxSeekHead.
Level 1 Element: Segment Information
This contains top level information about this segment, such as duration, MuxingApp and WritingApp (string identifiers of the applications that created the media).
Level 1 Element: Tracks Information
Contains track(s) definitions. There are quite a lot of stuff here but they are self explanatory as shown in the example below. There are two tracks in this example. Several things worth pointing out: – UID is a unique track identifier, no two tracks should have the same UID.
In a WebM file, the video track Codec ID must be V_VP8, and the audio track Codec ID must be A_VORBIS.

Following the above elements is usually the actual tracks data organized in Clusters.
Level 1 Element: Clusters
Expanding one of the Clusters, we see blocks of data. The timecode must always be increasing. Note that the blocks do not have to be SimpleBlock elements as WebM also support Block and BlockGroup elements. 