2014-11-02 46 views
0

我希望能夠訪問AAC流式廣播電臺正在播放的音頻樣本,並在將它們發送給呈現器之前對它們執行一些信號處理功能。AS3如何使用appendBytes節制AAC流式音頻的NetStream緩衝

我能夠使用URLStreamProgressEvent.PROGRESS回調訪問字節流。在該回調中,我最初稱爲urlStream.readBytes(Bytes),然後是netStream.appendBytes(Bytes)。音頻會播放幾秒鐘,然後停止netStatus NetStream.Buffer.Empty

我在我的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);      
     } 
    } 
} 
+0

我測試你的代碼,但我沒有收到'NetStream.Buffer.Empty'事件。你可以給我你使用的飼料的網址,如果有可能的話,來測試它嗎? – akmozo 2014-11-03 01:36:36

+0

其實我們的客戶要求我們不要使用我們應該進行信號處理的流式URL。不過,如果您願意發佈該網址,我會對嘗試獲得成功的網址感興趣。另外,您是否知道在ProgressEvent處理程序中接收到的字節是否代表使用聲音提取方法時的32位浮點音頻採樣?當我嘗試使用Number數據類型讀取和寫入樣本時,我不再聽到任何音頻輸出! – BooRowan 2014-11-03 13:50:45

+0

我找到了一個可以用來測試的鏈接。 – BooRowan 2014-11-03 19:43:07

回答

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) 

} 
+0

您可以在不使用Video類的情況下使用流嗎? – 2014-12-10 09:25:48

+0

@TarmoSaluste當然可以,你可以刪除'Video'對象,它只是爲了測試。 – akmozo 2014-12-10 12:28:45

相關問題