我想访问从AAC流广播电台播放的音频样本,并对它们执行一些信号处理功能,然后再将其发送到渲染器。
我能够使用URLStream
ProgressEvent.PROGRESS
回调访问字节流。在该回调中,我最初叫urlStream.readBytes(Bytes)
,然后叫netStream.appendBytes(Bytes)
。音频将播放几秒钟,然后以NetStream.Buffer.Empty
的netStatus停止。
我在ProgressEvent
处理程序中放置了一条轨迹以显示netStream.bufferLength
,并看到它最初变大,然后永远变小,直到缓冲区为空。我已经搜索了一些有关限制缓冲区的信息,但我发现没有任何效果。
有趣的是
当我发出netStream.play(url)
而不是netStream.play(null)
来启用ProgressEvent
处理程序时,音频可以正常播放,但是我看不到基础音频样本。
因此,我的问题可以归结为:如何访问底层音频样本,并防止缓冲区变空?
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);
}
}
}
最佳答案
试试这个 :
import flash.media.Video
var stream = 'http://2583.live.streamtheworld.com/KFMXFMAAC'
var http_stream:URLStream = null
var video:Video = new Video() // the video is used only to ensure that stream is playing
addChild(video)
var nc:NetConnection = new NetConnection()
nc.connect(null)
var ns:NetStream = new NetStream(nc)
ns.client = new Object()
ns.client.onMetaData = function(e){}
ns.play(null)
video.attachNetStream(ns)
http_stream = new URLStream();
http_stream.addEventListener(ProgressEvent.PROGRESS, on_Progress)
http_stream.load(new URLRequest(stream))
function on_Progress(e:ProgressEvent):void {
var b:ByteArray = new ByteArray()
http_stream.readBytes(b, 0, http_stream.bytesAvailable)
ns.appendBytes(b)
trace(ns.bufferLength)
}
关于actionscript-3 - AS3如何使用appendBytes限制AAC流音频的NetStream缓冲,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/26703104/