<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute" width="828" height="418"
creationComplete="init()">
<mx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
import flash.filesystem.File;
import flash.filesystem.FileStream;
import flash.filesystem.FileMode;
private var file:File;
private var saveFile:File;
private var fileStream:FileStream;
private var flvData:ByteArray;
private var tags:ArrayCollection;
private var soundBytes:ByteArray = new ByteArray();
private var formatTable:Object;
private var soundRateTable:Array;
private function init():void{
formatTable = new Object();
formatTable[0] = "uncompressed";
formatTable[1] = "ADPCM";
formatTable[2] = "MP3";
formatTable[5] = "Nellymoser 8kHz mono";
formatTable[6] = "Nellymoser";
soundRateTable = new Array();
soundRateTable[0] = ["5.5 kHz"];
soundRateTable[1] = ["11 kHz"];
soundRateTable[2] = ["22 kHz"];
soundRateTable[3] = ["44 kHz"];
}
private function openFile():void{
file = File.desktopDirectory;
file.addEventListener(Event.Select, onFlvSelected);
file.browseForOpen("Select FLV",[new FileFilter("FLV Video","*.flv")]);
}
private function onFlvSelected(evt:Event):void{
fileStream = new FileStream();
fileStream.open(file, FileMode.READ);
flvData = new ByteArray();
fileStream.readBytes(flvData);
analyzeFLV(flvData);
}
private function saveSound():void{
saveFile= File.desktopDirectory.resolvePath("out.mp3");
saveFile.addEventListener(Event.Select, onMp3PathSelected);
saveFile.browseForSave("Save Mp3 file");
}
private function onMp3PathSelected(evt:Event):void{
var outStream:FileStream = new FileStream();
outStream.open(saveFile, FileMode.WRITE);
outStream.writeBytes(soundBytes);
outStream.close();
}
private function analyzeFLV(flvData:ByteArray):void{
tags = new ArrayCollection();
// Start analyzing Flv Header
var signatureByte1:String = flvData.readMultiByte(3,"utf-8");
var version:uint = flvData.readUnsignedByte();
var typeFlags:uint = flvData.readUnsignedByte();
var flagsReserved:int = (typeFlags >>>3) & 0x1f;
var typeFlagsAudio:uint = (typeFlags >>> 2) & (0x1);
var typeFlagsReserved:uint = (typeFlags >>> 1) & (0x1);
var typeFlagsVideo:uint = typeFlags & (0x1);
var dataOffset:uint = flvData.readUnsignedInt();
flvData.position = dataOffset;
// End FLV Header
// Start looping through tags
while( flvData.bytesAvailable > 15){
var tagStartPos:int = flvData.position;
//Tag Header
var previousTagSize:uint = flvData.readUnsignedInt();
var tagType:uint = flvData.readUnsignedByte();
var tagBodyLength:int = readUI24(flvData);
var timestamp:int = readUI24(flvData);
var reserved:int = flvData.readUnsignedByte();
var streamId:int = readUI24(flvData);
// end of Tag Header
// Tag Body
if(tagType == 8){
var soundProperties:int = flvData.readByte();
var soundFormat:int = (soundProperties >> 4) & 0xf; // 0 = uncompressed, 1 = ADPCM, 2 = MP3, 5 = Nellymoser 8kHz mono, 6 = Nellymoser
var soundRate:int = (soundProperties >> 2) & 0x3; // 0 = 5.5 kHz, 1 = 11 kHz, 2 = 22 kHz, 3 = 44 kHz
var soundSize:int = (soundProperties >> 1) & 0x1; // 0 = snd8Bit, 1 = snd16Bit
var soundType:int = soundProperties & 0x1; // 0 = sndMono, 1 = sndStereo
soundBytes.writeBytes(flvData,flvData.position,tagBodyLength-1);
tags.addItem({timestamp:timestamp/1000,tagType:tagType,tagBodyLength:tagBodyLength,format:formatTable[soundFormat],channels:soundType+1,soundRate:soundRateTable[soundRate]});
}
flvData.position = tagStartPos + tagBodyLength + 15;
// End of Tag Body
}
tags_dg.dataProvider = tags;
}
private function readUI24(bytes:ByteArray):int{
return bytes.readUnsignedByte() << 16 | (bytes.readUnsignedByte() << 8) | bytes.readUnsignedByte();
}
]]>
</mx:Script>
<mx:Button x="10" y="10" label="Open FLV" click="openFile()" width="799"/>
<mx:DataGrid id="tags_dg" x="10" y="40" width="799" height="322" />
<mx:Button x="10" y="370" label="Save sound as Mp3" width="799" click="saveSound()"/>
</mx:WindowedApplication>
