我想访问从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/

10-10 11:07