package {
import com.greensock.TweenLite;
import com.greensock.easing.*;
import com.greensock.plugins.TweenPlugin;
import com.greensock.plugins.VolumePlugin;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.IOErrorEvent;
import flash.media.Sound;
import flash.media.SoundChannel;
import flash.media.SoundLoaderContext;
import flash.media.SoundTransform;
import flash.net.URLRequest;
import flash.system.System;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
public class debug_radio extends Sprite
{
private var txtOutput:TextField;
private var txtMessages:TextField;
// start time
private var startTime:Date;
// last stream load
private var lastLoad:Date;
private var button:Sprite;
// initial memory usage on load
private var initialMemory:Number;
private static const streamUrl:String = "http://radio.hiof.no/nrk-mpetre-128";
// used for loading sounds
private var soundRequest:URLRequest;
private var soundLoaderContext:SoundLoaderContext;
// first sound + channel
private var activeSound:Sound;
private var activeSoundChannel:SoundChannel;
// second sound + channel
private var idleSound:Sound;
private var idleSoundChannel:SoundChannel;
// counter for channel swaps
private var reloadCount:int = 0;
// buffer size in KB
private var bufferSize:int = 400;
// size of current buffer
private var currentBuffer:int = 0;
public function debug_radio()
{
TweenPlugin.activate([VolumePlugin]);
startTime = new Date();
graphics.beginFill(0xFFFFFF,1);
graphics.drawRect(0,0,800,410);
graphics.endFill();
txtOutput = new TextField();
txtOutput.x = 100;
txtOutput.y = 100;
txtOutput.autoSize = TextFieldAutoSize.LEFT;
txtMessages = new TextField();
txtMessages.x = 100;
txtMessages.y = 100;
txtMessages.autoSize = TextFieldAutoSize.LEFT;
addChild(txtOutput);
addChild(txtMessages);
addEventListener(Event.ENTER_FRAME,updateMemoryUsage);
// set up request and loader context
soundRequest = new URLRequest(streamUrl);
soundLoaderContext = new SoundLoaderContext(3000, false);
soundLoaderContext.bufferTime = 1;
// set up initial stream
activeSoundChannel= new SoundChannel();
activeSoundChannel.soundTransform = new SoundTransform(1,0);
activeSound = new Sound();
lastLoad = new Date();
initialMemory = System.totalMemory/1024;
// load and play initial stream
activeSound.load(soundRequest,soundLoaderContext);
activeSoundChannel = activeSound.play(0,0,activeSoundChannel.soundTransform);
}
private function onIoError(e:IOErrorEvent):void
{
trace(e.text);
}
private function swapStreams():void
{
// set up secondary sound channel
idleSoundChannel = new SoundChannel();
idleSoundChannel.soundTransform = new SoundTransform(0,0);
// set up secondary sound object, initiate load
idleSound = new Sound();
idleSound.load(soundRequest,soundLoaderContext);
idleSound.addEventListener(IOErrorEvent.IO_ERROR,onIoError);
idleSoundChannel = idleSound.play(0,0,idleSoundChannel.soundTransform);
reloadCount++;
lastLoad = null;
lastLoad = new Date();
/**
* 1. start loading idleStream
*/
// initiate tweening of volume on both channels
TweenLite.to(idleSoundChannel, 4, {volume:1,onComplete:onCrossFadeComplete});
TweenLite.to(activeSoundChannel, 4, {volume:0,onComplete:onCrossFadeComplete});
}
private function onCrossFadeComplete():void
{
// we have reached complete cross-fade, swap channels, clear memory for old objects
if (activeSoundChannel.soundTransform.volume <= 0 && idleSoundChannel.soundTransform.volume >= 1)
{
activeSoundChannel.stop();
activeSound.close();
activeSoundChannel = null;
activeSound = null;
activeSoundChannel = idleSoundChannel;
activeSound = idleSound;
idleSound = null;
idleSoundChannel = null;
}
}
private function updateMemoryUsage(e:Event):void
{
var deltaMemory:Number = (Number(System.totalMemory/1024) - initialMemory);
if (currentBuffer > bufferSize && idleSoundChannel == null)
{
// buffer has reached limit, and we do not have an instance in idleSoundChannel, start the swapping
swapStreams();
}
// some usage info
var now:Date = new Date();
var deltaStart:Date = new Date(now.time - startTime.time);
var deltaLoad:Date = new Date(now.time - lastLoad.time);
var str:String = "";
str += "General Info\n";
str += "Elapsed time : " + deltaStart.hoursUTC + ":" + deltaStart.minutes + ":" + deltaStart.seconds + "\n";
str += "Stream Size : " + Number(activeSound.bytesTotal/1024).toFixed(2) + "kb\n";
str += "Total memory : " + Number(System.totalMemory/1024).toFixed(2) + "kb\n";
str += "Delta memory: " + deltaMemory.toFixed(2) + "kb\n";
var streamRate:Number = Number((activeSound.bytesLoaded/1024) / (deltaLoad.time/1000));
str += "\n\n\nStreaming info\n";
str += "Age : " + deltaLoad.minutes + ":" + deltaLoad.seconds + "\n";
str += "Bytes loaded : " + Number(activeSound.bytesLoaded/1024).toFixed(2) + "kb\n";
str += "Rate : " + streamRate.toFixed(2) + "kb/sec / " + Number(streamRate*60).toFixed(2) + "kb/min \n";
str += "Remaning buffer: " + Number(bufferSize - currentBuffer).toFixed(2) + "kb\n";
str += "Expected buffer life duration : " + Number(bufferSize/streamRate).toFixed(2) + "sec / " + Number(bufferSize/streamRate/60).toFixed(2) + "min\n" ;
str += "Buffer life remaining : " + Number((bufferSize/streamRate) - (deltaLoad.time/1000)).toFixed(2) + "\n";
currentBuffer = activeSound.bytesLoaded/1024;
str += "\n\nReload count : " + reloadCount + "\n";
txtOutput.text = str;
deltaMemory = 0;
deltaStart = null
deltaLoad = null
streamRate = 0;
now = null;
str = null;
}
}
}