-
-
Save claus/218226 to your computer and use it in GitHub Desktop.
// Author: Claus Wahlers | |
// License: Public Domain | |
// Dependencies: | |
// as3commons-bytecode-1.0-RC1.swc | |
// as3commons-lang-0.3.2.swc | |
// as3commons-logging-2.0.swc | |
// as3commons-reflect-1.3.4.swc | |
// as3swf.swc | |
// MinimalComps_0_9_9.swc | |
package | |
{ | |
import com.bit101.components.PushButton; | |
import com.codeazur.as3swf.SWF; | |
import com.codeazur.as3swf.SWFData; | |
import com.codeazur.as3swf.data.SWFSymbol; | |
import com.codeazur.as3swf.tags.TagDefineSound; | |
import com.codeazur.as3swf.tags.TagDoABC; | |
import com.codeazur.as3swf.tags.TagEnd; | |
import com.codeazur.as3swf.tags.TagFileAttributes; | |
import com.codeazur.as3swf.tags.TagShowFrame; | |
import com.codeazur.as3swf.tags.TagSymbolClass; | |
import org.as3commons.bytecode.abc.AbcFile; | |
import org.as3commons.bytecode.emit.IAbcBuilder; | |
import org.as3commons.bytecode.emit.IClassBuilder; | |
import org.as3commons.bytecode.emit.IPackageBuilder; | |
import org.as3commons.bytecode.emit.impl.AbcBuilder; | |
import org.as3commons.bytecode.io.AbcSerializer; | |
import flash.display.Loader; | |
import flash.display.LoaderInfo; | |
import flash.display.Sprite; | |
import flash.display.StageAlign; | |
import flash.display.StageScaleMode; | |
import flash.events.Event; | |
import flash.media.Sound; | |
import flash.net.FileFilter; | |
import flash.net.FileReference; | |
import flash.utils.ByteArray; | |
public class MP3FileRefLoader extends Sprite | |
{ | |
private static const PACKAGENAME:String = "tmp"; | |
private static const CLASSNAME:String = "SoundClass"; | |
private static const QNAME:String = PACKAGENAME + "." + CLASSNAME; | |
public function MP3FileRefLoader() | |
{ | |
stage.align = StageAlign.TOP_LEFT; | |
stage.scaleMode = StageScaleMode.NO_SCALE | |
addChild(new PushButton(this, 10, 10, "Load MP3", function():void { | |
var ref:FileReference = new FileReference(); | |
ref.addEventListener(Event.SELECT, function(e:Event):void { ref.load(); }); | |
ref.addEventListener(Event.COMPLETE, function(e:Event):void { loadBytes(ref.data); }); | |
ref.browse([new FileFilter("MP3 (*.mp3)", "*.mp3")]); | |
})); | |
} | |
protected function loadBytes(mp3:ByteArray):void { | |
// Wrap the MP3 with a SWF | |
var swf:ByteArray = createSWFFromMP3(mp3); | |
// Load the SWF with Loader::loadBytes() | |
var loader:Loader = new Loader(); | |
loader.contentLoaderInfo.addEventListener(Event.INIT, initHandler); | |
loader.loadBytes(swf); | |
} | |
protected function initHandler(e:Event):void { | |
// Get the sound class definition | |
var SoundClass:Class = LoaderInfo(e.currentTarget).applicationDomain.getDefinition(QNAME) as Class; | |
// Instantiate the sound class | |
var sound:Sound = new SoundClass() as Sound; | |
// Play the sound | |
sound.play(); | |
} | |
protected function createSWFFromMP3(mp3:ByteArray):ByteArray | |
{ | |
// Create an empty SWF | |
// Defaults to v10, 550x400px, 50fps, one frame (works fine for us) | |
var swf:SWF = new SWF(); | |
// Add FileAttributes tag | |
// Defaults: as3 true, all other flags false (works fine for us) | |
swf.tags.push(new TagFileAttributes()); | |
// Add DefineSound tag | |
// The ID is 1, all other parameters are automatically | |
// determined from the mp3 itself. | |
swf.tags.push(TagDefineSound.createWithMP3(1, mp3)); | |
// Create and add DoABC tag | |
// Contains the AS3 byte code for the class definition for the embedded sound: | |
// package tmp { | |
// public dynamic class SoundClass extends flash.media.Sound { | |
// } | |
// } | |
var abcBuilder:IAbcBuilder = new AbcBuilder(); | |
var packageBuilder:IPackageBuilder = abcBuilder.definePackage(PACKAGENAME); | |
var classBuilder:IClassBuilder = packageBuilder.defineClass(CLASSNAME, "flash.media.Sound"); | |
var abcFile:AbcFile = abcBuilder.build(); | |
var abcSerializer:AbcSerializer = new AbcSerializer(); | |
var abcBytes:ByteArray = abcSerializer.serializeAbcFile(abcFile); | |
swf.tags.push(TagDoABC.create(abcBytes)); | |
// Add SymbolClass tag | |
// Binds the sound class definition to the embedded sound | |
var symbolClass:TagSymbolClass = new TagSymbolClass(); | |
symbolClass.symbols.push(SWFSymbol.create(1, QNAME)); | |
swf.tags.push(symbolClass); | |
// Add ShowFrame tag | |
swf.tags.push(new TagShowFrame()); | |
// Add End tag | |
swf.tags.push(new TagEnd()); | |
// Publish the SWF | |
var swfData:SWFData = new SWFData(); | |
swf.publish(swfData); | |
return swfData; | |
} | |
} | |
} |
(thanks for your swift answer :) )
I see...
so the the ID3 tags must be located somewhere between 0 and 10 + ((mp3[i + 6] << 21) | (mp3[i + 7] << 14) | (mp3[i + 8] << 7) | mp3[i + 9]); in the ByteArray.
this is really way beyond my understanding ;)
I found an ID3Reader lib here : http://blog.benstucki.net/?p=3 ( metaphile on the SVN is up to date )
combining your scripts with his might do the trick.
again thanks a bunch for this,
cheers,
Nicolas
I should have documented that piece of code, because it's even beyond my understanding today, lol.
You should be able to use the MP3 as is, btw. FP should handle it fine. So you could try and just copy the MP3 bytearray to TagDefineSound.soundData. The main thing processMP3() does (apart from stripping non-frame stuff) is determining the MP3's parameters.
Nicolas, yeah i'm stripping anything that's not an MPEG frame.
The relevant code is in TagDefineSound.processMP3.