blog.ashier.com flash / flex / air development
rss rss comment

Archive for the ‘AIR’ Category

I've been trying to develop an ID3 parser and here's what i got so far.

I've update the ID3Parser. It is much faster now.

Actionscript:
  1. package libs.ashier.id3 {
  2.    
  3.     package libs.ashier.id3 {
  4.    
  5.     import flash.events.EventDispatcher;
  6.     import flash.filesystem.File;
  7.     import flash.filesystem.FileMode;
  8.     import flash.filesystem.FileStream;
  9.     import flash.utils.ByteArray;
  10.     import flash.utils.Dictionary;
  11.     import flash.utils.clearInterval;
  12.     import flash.utils.setInterval;
  13.    
  14.     public class ID3Parser extends EventDispatcher{
  15.        
  16.         public function ID3Parser():void {}
  17.        
  18.         /**
  19.          * Bit 7 in the 'ID3v2 flags' indicates whether or not
  20.          * unsynchronisation is applied on all frames.
  21.          */
  22.         private var unsynchronisation:uint;
  23.        
  24.         /**
  25.          * The second bit (bit 6) indicates whether or not the header is
  26.          * followed by an extended header.
  27.          * A set bit indicates the presence of an extended header.
  28.          */
  29.         private var extendedHeader:uint;
  30.        
  31.         /**
  32.          * The third bit (bit 5) is used as an 'experimental indicator'. This
  33.          * flag SHALL always be set when the tag is in an experimental stage.
  34.          */
  35.         private var experimental:uint;
  36.        
  37.         /**
  38.          * FileStream / Bytes
  39.          */       
  40.         private var fs:FileStream;
  41.        
  42.         /**
  43.          * Id3 Version
  44.          */       
  45.         private var version:Number;
  46.        
  47.         /**
  48.          * Available Genres
  49.          */       
  50.         private var genres:Array = [
  51.                                 "Blues", "Classic Rock", "Country", "Dance", "Disco", "Funk",
  52.                                 "Grunge", "Hip-Hop", "Jazz", "Metal", "New Age", "Oldies", "Other",
  53.                                 "Pop", "R&B", "Rap", "Reggae", "Rock", "Techno", "Industrial",
  54.                                 "Alternative", "Ska", "Death Metal", "Pranks", "Soundtrack",
  55.                                 "Euro-Techno", "Ambient", "Trip-Hop", "Vocal", "Jazz+Funk", "Fusion",
  56.                                 "Trance", "Classical", "Instrumental", "Acid", "House", "Game",
  57.                                 "Sound Clip", "Gospel", "Noise", "Alt. Rock", "Bass", "Soul",
  58.                                 "Punk", "Space", "Meditative", "Instrum. Pop", "Instrum. Rock",
  59.                                 "Ethnic", "Gothic", "Darkwave", "Techno-Indust.", "Electronic",
  60.                                 "Pop-Folk", "Eurodance", "Dream", "Southern Rock", "Comedy",
  61.                                 "Cult", "Gangsta", "Top 40", "Christian Rap", "Pop/Funk", "Jungle",
  62.                                 "Native American", "Cabaret", "New Wave", "Psychadelic", "Rave",
  63.                                 "Showtunes", "Trailer", "Lo-Fi", "Tribal", "Acid Punk", "Acid Jazz",
  64.                                 "Polka", "Retro", "Musical", "Rock & Roll", "Hard Rock", "Folk",
  65.                                 "Folk/Rock", "National Folk", "Swing", "Fusion", "Bebob", "Latin",
  66.                                 "Revival", "Celtic", "Bluegrass", "Avantgarde", "Gothic Rock",
  67.                                 "Progress. Rock", "Psychadel. Rock", "Symphonic Rock", "Slow Rock",
  68.                                 "Big Band", "Chorus", "Easy Listening", "Acoustic", "Humour",
  69.                                 "Speech", "Chanson", "Opera", "Chamber Music", "Sonata", "Symphony",
  70.                                 "Booty Bass", "Primus", "Porn Groove", "Satire", "Slow Jam",
  71.                                 "Club", "Tango", "Samba", "Folklore", "Ballad", "Power Ballad",
  72.                                 "Rhythmic Soul", "Freestyle", "Duet", "Punk Rock", "Drum Solo",
  73.                                 "A Capella", "Euro-House", "Dance Hall", "Goa", "Drum & Bass",
  74.                                 "Club-House", "Hardcore", "Terror", "Indie", "BritPop", "Negerpunk",
  75.                                 "Polsk Punk", "Beat", "Christian Gangsta Rap", "Heavy Metal",
  76.                                 "Black Metal", "Crossover", "Contemporary Christian", "Christian Rock",
  77.                                 "Merengue", "Salsa", "Thrash Metal", "Anime", "Jpop", "Synthpop"
  78.                                 ];
  79.        
  80.        
  81.         /**
  82.          * Get ID3 Profile
  83.          *
  84.          */  
  85.         private function getID3Profile():void {
  86.             fs = new FileStream();
  87.             try {
  88.                 fs.open(_file, FileMode.READ);
  89.             }catch (e:Error) {}
  90.             if(_file) {
  91.                 clearInterval(interval);
  92.                 interval = setInterval(checkID3, 10, fs);
  93.             }
  94.         }
  95.        
  96.         /**
  97.          * ID3 Flag
  98.          */       
  99.         private var flags:uint;
  100.         private var interval:uint;
  101.         private var interval2:uint;
  102.        
  103.         /**
  104.          * Check if ID3 is Valid.
  105.          * @param fs
  106.          *
  107.          */
  108.         public function checkID3(fs:FileStream):void {
  109.             clearInterval(interval);
  110.             fs.position = 0;
  111.             var type:String = fs.readUTFBytes(3);
  112.             if(type.toLocaleUpperCase() == "ID3") {
  113.                 version = fs.readByte() + fs.readByte()/100;
  114.                 if(version>= 3) {
  115.                     frameIdSize = 4;
  116.                 }
  117.                
  118.                 flags = fs.readByte();
  119.                 unsynchronisation = flags>> 7;
  120.                 extendedHeader = flags>> 6 && 01;
  121.                 experimental = flags>> 5 && 001;
  122.                 clearInterval(interval2);
  123.                 interval2 = setInterval(readFrames, 10);
  124.             }else {
  125.                 dispatchEvent(new ID3ParserEvent(ID3ParserEvent.ERROR, {message:"Not a valid ID3."}));
  126.             }
  127.         }
  128.        
  129.         /**
  130.          * Declared ID3v2 frames
  131.          */       
  132.         private var frames:Object;
  133.        
  134.         /**
  135.          * First FrameId Size. Default is 3.
  136.          */       
  137.         private var frameIdSize:uint = 3;
  138.        
  139.         /**
  140.          * Parse all types of frames in an ID3.
  141.          *
  142.          */   
  143.        
  144.         private var length:int = 0;
  145.         private var lastFSPosition:int = 0;
  146.        
  147.         private function readFrames():void {
  148.             clearInterval(interval2);
  149.             if(!frames) {
  150.                 frames = new Object();
  151.             }
  152.             length = convertSynchsafe(fs.readUnsignedInt()) + 10;
  153.             parseFrames();
  154.             lastFSPosition = fs.position;
  155.             fs.close();
  156.             dispatchEvent(new ID3ParserEvent(ID3ParserEvent.ID3, ID3Info));
  157.         }
  158.        
  159.          private var regEx:RegExp = new RegExp("" +
  160.                         "/AENC|APIC|PIC|" +
  161.                         "COMM|COMR|" +
  162.                         "ENCR|EQUA|ETCO|" +
  163.                         "GEOB|GRID|" +
  164.                         "IPLS|" +
  165.                         "LINK|" +
  166.                         "MCDI|MLLT|" +
  167.                         "OWNE|" +
  168.                         "PRIV|PCNT|POPM|POSS|" +
  169.                         "RBUF|RVAD|RVRB|" +
  170.                         "SYLT|SYTC|" +
  171.                         "T*" +
  172.                         "UFID|USER|USLT|" +
  173.                         "W*/", "ig");
  174.        
  175.         private function parseFrames():void {
  176.             var id:String = "";
  177.             var size:uint = 0;
  178.             if(fs.position <length) {
  179.                 try {
  180.                     id = fs.readUTFBytes(frameIdSize);
  181.                     size = fs.readUnsignedInt();
  182.                     if (version>= 3) {
  183.                         fs.readByte();
  184.                         fs.readByte();
  185.                     }
  186.                     if(id.match(regEx)) {
  187.                         var obj:Object = new Object();
  188.                         obj.encoding = fs.readByte();
  189.                         obj.text = fs.readUTFBytes(size - 1);
  190.                         frames[id] = obj;
  191.                     }
  192.                     parseFrames();
  193.                 }catch(e:Error) {}
  194.             }
  195.         }
  196.        
  197.         /**
  198.          * Get value from a ID3 frame.
  199.          * @param frameType
  200.          * @return
  201.          *
  202.          */       
  203.         public function getFrameType(frameType:String):Object {
  204.             return frames[frameType];
  205.         }
  206.         private var ID3Frames:Object = {GENRE:”TCON”,ALBUM:”TALB”,ARTIST:”TPE1″,COMMENT:”COMM”,TITLE:”TIT2″,TRACK_NUMBER:”TRCK”,LYRICIST:”TOLY”,YEAR:”TYER”};
  207.         /**
  208.          * Returns ID3Info.
  209.          * @return
  210.          *
  211.          */       
  212.         public function get ID3Info():Object {
  213.             if(frames) {
  214.                 var genreType:String = "";
  215.                 if(frames[ID3Frames.GENRE]) {
  216.                     try {
  217.                         genreType = frames[ID3Frames.GENRE].text;
  218.                         if(genreType.indexOf("(") != -1) {
  219.                             genreType = genreType.substr(1, genreType.indexOf(")") - 1);
  220.                             genreType = genres[Number(genreType)];
  221.                         }
  222.                     }catch(e:Error) {
  223.                         genreType = "";
  224.                     }
  225.                 }
  226.                 return {
  227.                             album:frames[ID3Frames.ALBUM] ? frames[ID3Frames.ALBUM].text : "",
  228.                             artist:frames[ID3Frames.ARTIST] ? frames[ID3Frames.ARTIST].text : "",
  229.                             comment:frames[ID3Frames.COMMENT] ? frames[ID3Frames.COMMENT].text : "",
  230.                             genre:genreType,
  231.                             title:frames[ID3Frames.TITLE] ? frames[ID3Frames.TITLE].text : "",
  232.                             track:frames[ID3Frames.TRACK_NUMBER] ? frames[ID3Frames.TRACK_NUMBER].text : "",
  233.                             lyrics:frames[ID3Frames.LYRICIST] ? frames[ID3Frames.LYRICIST].text : "",
  234.                             year:frames[ID3Frames.YEAR] ? frames[ID3Frames.YEAR].text : ""
  235.                         };
  236.             }
  237.             return new Object();
  238.         }
  239.        
  240.         private function convertSynchsafe(value:uint):uint {
  241.             return (value & 127) + 128 * ((value>> 8) & 127) + 16384 * ((value>>16) & 127) + 2097152 * ((value>> 24) & 127);
  242.         }
  243.        
  244.         private var _file:File;
  245.         public function set file(f:File):void {
  246.             _file = f;
  247.             getID3Profile();
  248.         }
  249.        
  250.         public function get file():File {
  251.             return _file;
  252.         }
  253.     }
  254. }

ID3 Parser Event

Actionscript:
  1. package libs.ashier.id3 {
  2.    
  3.     import flash.events.Event;
  4.  
  5.     public class ID3ParserEvent extends Event {
  6.        
  7.         public static const ERROR:String = "error";
  8.         public static const ID3:String = "id3";
  9.        
  10.         public function ID3ParserEvent(type:String, value:Object = null) {
  11.             super(type);
  12.             this.data = value;
  13.         }
  14.  
  15.         public var data:Object;
  16.         override public function clone():Event {
  17.             return new ID3ParserEvent(type, data);
  18.         }
  19.  
  20.     }
  21. }

Usage:

Actionscript:
  1. private var file:File = new File();
  2. private function initialize():void {
  3.         file.browseForDirectory("Browse...");
  4.     file.addEventListener(Event.SELECT, onDirectory);
  5. }
  6.  
  7. private function onDirectory(event:Event):void {
  8.      var files:Array = File(event.target).getDirectoryListing();
  9.          for( var i:Number = 0; i <files.length; i++ ){
  10.         var file:File = File(files[i]);
  11.         var prof:ID3Parser = new ID3Parser();
  12.         prof.addEventListener(ID3ParserEvent.ID3, onID3);
  13.         prof.file = file;
  14.          }
  15. }
  16. private function onID3(event:ID3ParserEvent):void {
  17.         //event.data
  18. }

This is written for an AIR application.

Codename "Apollo" has been replaced with AIR (Adobe Integrated Runtime). Adobe AIR is now available on Adobe Labs. An Adobe AIR extension for Adobe Dreamweaver is also availabel

Flex 3 Beta is also available.

Grab your copies now!

I have developed my first Apollo application. Yey! :). Its a mini Apollo application that lets you convert currency by country.

You can download the application here.

Screenshot:
Currency Converter

To run this application, you'll first need to install Apollo Runtime from Adobe and run my application.

According to PC World, Adobe Apollo beta will be out in March.
PC World
Adobe plans to later this month launch the beta of a new runtime that will allow rich web-based applications to run offline, technology that could threaten the popularity of programming platforms such as Java and Microsoft's .NET.
Apollo

Link here