如何在 ActionScript 3 中从缓冲区 (ByteArray/Stream) 播放 MP3 声音?

Posted

技术标签:

【中文标题】如何在 ActionScript 3 中从缓冲区 (ByteArray/Stream) 播放 MP3 声音?【英文标题】:How to play MP3 sound from buffer (ByteArray/Stream) in ActionScript 3? 【发布时间】:2010-12-09 20:07:30 【问题描述】:

所以.. 我有一个带有 MP3 数据的 缓冲区(如果我要保存这个缓冲区并将其命名为 buffer.mp3 它会播放,但在这种情况下我不应该将它保存到文件系统) . 我必须玩,但我不能,我该怎么办?


我尝试了下一个代码来播放该缓冲区(ByteArray\Stream)(我从服务器获取 MP3 数据,获取数据的方法工作正常(在 text int 等上测试)我调用返回的 ByteArray readResponse,因为我有一些固定方法这是它的回应)。

            protected function Play(event:MouseEvent):void
        
            var mySound:Sound = new Sound();
            mySound.addEventListener(SampleDataEvent.SAMPLE_DATA, soundFill);
            mySound.play(); 
        

        public function soundFill(event:SampleDataEvent):void
        
            event.data.writeBytes(readResponse.buffer, 0, readResponse.buffer.length);  
        

【问题讨论】:

这个帖子可能会有所帮助***.com/questions/1553563/… 【参考方案1】:

这个不起作用,因为 SampleDataEvent.data 需要未压缩的原始样本数据,而不是 MP3。请改用https://github.com/claus/as3swf/wiki/play-mp3-directly-from-bytearray。

【讨论】:

【参考方案2】:

我不认为 mp3 二进制数据有解决方案,但如果它是 wav 的,那么这应该可以:


   private function loaded(event:Event):void 
   var urlStream:URLStream = event.target as URLStream;
   bArr = new ByteArray();
   urlStream.readBytes(bArr, 0);
   /**
    * Remove wav header here
    */
   bArr.position = 0;
   sampleMP3.addEventListener(SampleDataEvent.SAMPLE_DATA, sampleDataHandler);
   soundChannel = sampleMP3.play();
  

  private function sampleDataHandler(event:SampleDataEvent):void 
   var bytesToRead:int = (bArr.bytesAvailable > 65536 ? 65536 : bArr.bytesAvailable);
   event.data.writeBytes(bArr, bArr.position, bytesToRead);
   bArr.position += bytesToRead;
  

请记住在采样数据之前删除 wav 标头。此外,它仅在采样率为 44.1kHz 时才能正常工作。对于其他采样率,您需要手动重复或删除采样以使其接近 44.1kHz。请注意单声道声音,因为您需要向 Flash 提供左右声道样本,因此需要重复样本。

很好的起点是 Popforge 的 audio.format.wav 包中的 WavDecoder 类。

【讨论】:

【参考方案3】:

以下对我有用:

package

 import flash.display.Sprite;
 import flash.events.Event;
 import flash.events.SampleDataEvent;
 import flash.media.Sound;
 import flash.media.SoundChannel;
 import flash.net.URLRequest;
 import flash.net.URLStream;
 import flash.utils.ByteArray;

 public class QuickSoundTest extends Sprite
 
  public var sampleMP3:Sound;
  private var soundChannel:SoundChannel; 
  public var bArr:ByteArray;

  public function QuickSoundTest()
  
   sampleMP3 = new Sound();

   var urlReq:URLRequest = new URLRequest("test.mp3");
   var urlStream:URLStream = new URLStream();
   urlStream.addEventListener(Event.COMPLETE, loaded);
   urlStream.load(urlReq);

  

  private function loaded(event:Event):void 
   var urlStream:URLStream = event.target as URLStream;
   bArr = new ByteArray();
   urlStream.readBytes(bArr, 0, 40960);
   sampleMP3.addEventListener(SampleDataEvent.SAMPLE_DATA, sampleDataHandler);
   soundChannel = sampleMP3.play();
  

  private function sampleDataHandler(event:SampleDataEvent):void 
   event.data.writeBytes(bArr, 0, 40960);
  
 

您可能需要检查 readResponse ByteArray 中存储的内容或在加载数据时如何读取数据。确保使用 URLLoaderDataFormat.BINARY 或仅使用 URLStream 加载 URLLoader,就像我在这里所做的那样。

【讨论】:

正如@user238621 所说,这只会给我一堆随机失真的声音

以上是关于如何在 ActionScript 3 中从缓冲区 (ByteArray/Stream) 播放 MP3 声音?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Actionscript 3 中将数据写入 XML 文件

如何在应用程序中从网站加载 Flash 游戏?

如何在scRGB色彩空间中从HDR视频中获取帧?

在 Metal 中从顶点缓冲区渲染四边形

在纯 WinAPI 中从内存缓冲区播放声音

是否可以在 opengl 中从 2 个不同的线程渲染 2 个不同的帧缓冲区对象?