AS3如何使用appendBytes限制AAC流音频的NetStream缓冲

时间:2014-11-02 18:59:06

标签: actionscript-3 audio aac

我希望能够访问从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);                       
        }
    }
}

1 个答案:

答案 0 :(得分:0)

试试这个:

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)

}
相关问题