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

发布于 2024-08-09 01:00:46 字数 695 浏览 2 评论 0原文

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


我尝试了下一个代码来播放该缓冲区(ByteArray \ Stream)(我从服务器获取MP3数据获取数据的方法有效很好(在文本 int 等上进行了测试)我调用返回的 ByteArray readResponse 因为我有一些seading方法并且它是它的响应)。

            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);  
        }

So.. I have a buffer with MP3 data (If I would save this buffer and call it buffer.mp3 it would play, but in this situation I should not save it to file system). I have to play it, but I can not, what shall I do?


I tried the next code to play that buffrer(ByteArray\Stream) (I get MP3 data from server the method of getting data works fine (tested on text int's etc) I call the returned ByteArray readResponse because I have some seading method and It is it's response).

            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);  
        }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

蓝礼 2024-08-16 01:00:46

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

This one doesn't work since SampleDataEvent.data expects uncompressed raw sample data, not MP3. Use https://github.com/claus/as3swf/wiki/play-mp3-directly-from-bytearray instead.

鱼窥荷 2024-08-16 01:00:46

我不认为 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 类。

I don't think there is a solution to mp3 binary data, but if it's a wav one, then this should work:


   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;
  }

Remember to remove wav header before sampling data though. Also, it only works well when sample rate is 44.1kHz. For other sample rates, you need to manually repeat or remove samples to make it 44.1kHz-like. Do pay attention to mono sounds, as you need to supply both left & right channel samples to Flash, thus need to repeat samples.

Good starting point is WavDecoder class inside Popforge's audio.format.wav package.

不疑不惑不回忆 2024-08-16 01:00:46

以下对我有用:

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,就像我在这里所做的那样。

The following works for me:

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);
  }
 }
}

You might need to check what is stored in your readResponse ByteArray or how the data is getting read in when you're loading it. Making sure that it's loaded the URLLoader using URLLoaderDataFormat.BINARY or just by using a URLStream as I've done here.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文