Categories

  • ActionScript (20)
  • Adobe Flash (24)
  • Flex (18)
  • Games (4)
  • General (35)
  • Google Android (9)
  • HTML (34)
  • iPhone (28)
  • Java (5)
  • JavaScript (15)
  • Mac (31)
  • PHP (8)
  • Programming (75)
  • PSP (1)
  • RSS (3)
  • Technology (77)
  • Uncategorized (3)
  • WordPress (6)
  • xCode (10)
  • Jun
    09
    2010

    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:

    • 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 (in Flash) and ready to send to the server.
    • Call FileReference.upload() to upload the file.
    • Listen to DataEvent.UPLOAD_COMPLETE_DATA, which indicates that the upload (to server) is complete.

      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:

      • Make sure the folder where the file is being written to has write permission (this can pose security risk, so beware).
      • There is no checking in the example php script for duplicate filenames.
      • FileReference.size can be used to check the size of the file. This variable is valid after Event.SELECT is fired.

    Jun
    08
    2010

    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.

    Example1

    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");
    }
    

    Example 2

    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.

    Jun
    03
    2010

    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.