I would like get access to the audio samples being played from an AAC streaming radio station and perform some signal processing function on them before sending them on to the renderer.
I was able to get access to the byte stream using the URLStream
ProgressEvent.PROGRESS
callback. Within that callback I originally called urlStream.readBytes(Bytes)
followed by netStream.appendBytes(Bytes)
. The audio would play for some number of seconds then stop with a netStatus of NetStream.Buffer.Empty
.
I put a trace in my ProgressEvent
handler to show the netStream.bufferLength
and saw that this initially got bigger then get forever smaller until the buffer was empty. I've searched for information on what might be needed to throttle the buffer but nothing I found worked.
Interestingly,
when I issue a netStream.play(url)
rather than the netStream.play(null)
, which is needed for enabling the ProgressEvent
handler, the audio plays fine but I have no visibility to the underlying audio samples.
So my question boils down to: How do I get access to the underlying audio samples and keep the buffer from becoming empty?
package
{
import flash.display.Sprite;
import flash.net.NetConnection;
import flash.net.NetStream;
import flash.net.NetStreamAppendBytesAction;
import flash.net.NetStreamPlayOptions;
import flash.net.NetStreamInfo;
import flash.events.NetStatusEvent;
import flash.events.AsyncErrorEvent;
import flash.events.ProgressEvent;
import flash.events.Event;
import flash.net.URLRequest;
import flash.net.URLStream;
import flash.utils.*;
public class Main extends Sprite
{
private var connection:NetConnection = new NetConnection();
private var netStream:NetStream = null;
private var urlStream:URLStream = null;
private var urlRequest:URLRequest = null;
private var inputSamples:ByteArray = new ByteArray();
private var outputSamples:ByteArray = new ByteArray();
private var hTimer:uint = 0;
private var nState:int = 1;
private var url:String="*** replace this text with your favorite streaming AAC radio feed ***";
// Main Constructor
public function Main() : void
{
connectToStream();
}
private function connectToStream() : void
{
connection.close();
connection = new NetConnection();
connection.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler);
connection.addEventListener(AsyncErrorEvent.ASYNC_ERROR, asyncErrorHandler);
connection.connect(null);
}
private function netStatusHandler(event:NetStatusEvent) : void
{
trace("NetStatusEvent = " + event.info.code);
switch (event.info.code)
{
case "NetConnection.Connect.Success":
requestAudio();
break;
case "NetStream.Buffer.Empty":
//hTimer = setInterval(onTimerEvent, 1000);
break;
} // End switch
}
private function asyncErrorHandler(event:AsyncErrorEvent) : void
{
trace("Stream Error Handler - error = " + event);
}
public function onMetaData(info:Object) : void
{
trace("metadata: duration=" + info.duration + " framerate=" + info.framerate);
}
private function onTimerEvent() : void
{
}
private function requestAudio() : void
{
if (netStream !== null)
{
netStream.close();
}
netStream = new NetStream(this.connection);
netStream.client = new Object();
netStream.client.onMetaData = onMetaData;
netStream.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler);
netStream.addEventListener(AsyncErrorEvent.ASYNC_ERROR, asyncErrorHandler);
netStream.checkPolicyFile = false;
//netStream.play(url);
if (urlStream !== null)
{
urlStream.close();
}
urlStream = new URLStream();
urlStream.addEventListener(ProgressEvent.PROGRESS, progressHandler);
urlRequest = new URLRequest(url);
urlStream.load(urlRequest);
netStream.play(null);
netStream.appendBytesAction(NetStreamAppendBytesAction.RESET_BEGIN);
}
// Process audio samples from file
private function progressHandler(event:ProgressEvent) : void
{
var streamByte:int;
// Position to beginning of buffer
inputSamples.position = 0;
urlStream.readBytes(inputSamples);
// *** want to do some signal processing here ***
// For now just copy the input to the output
// Position to beginning of buffer
outputSamples.position = 0;
// This output indicates that the buffer is being drained
// until I get NetStream.Buffer.Empty and the audio stops playing
trace("Buffer Length = " + netStream.bufferLength);
while (inputSamples.bytesAvailable)
{
streamByte = inputSamples.readByte();
outputSamples.writeByte(streamByte);
}
// Position to beginning of buffer
outputSamples.position = 0;
netStream.appendBytes(outputSamples);
}
}
}
NetStream.Buffer.Empty
event. Can you give me the url of the feed that you are using, if it's possible of course, to test it ? – akmozo