【问题标题】:get the raw data of mp3 file which is downloading with the `Sound` object获取使用“声音”对象下载的 mp3 文件的原始数据
【发布时间】:2016-07-05 07:47:09
【问题描述】:

我已经动态创建了Sound对象

var     files:Object={};
files["file1"]={};
files["file1"]["snd"]=new Sound();
...... //url etc
files["file1"]["snd"].addEventListener(ProgressEvent.PROGRESS, onLoadProgress); 

function onLoadProgress(event:ProgressEvent):void 
//// somehow I need to get the raw data (first 48 bytes to be exact) of the mp3 file which is downloading now
}

我在那个函数中尝试了URLRequest

var myByteArray:ByteArray = URLLoader(event.target).data as ByteArray;

但没有成功

文件数据这么简单的东西竟然这么难弄,真是搞笑

【问题讨论】:

  • (从我的头顶):在进度事件中,通过事件的.bytesLoaded 属性测试您是否至少有 48 个字节,如果有,通过声音 @987654326 @ 方法,将 48 个字节提取到一个字节数组中。如果您正在尝试解码 mp3 帧数据/id3v2/等...您可能会更好地使用 URLStream,进行原始字节处理,而不是将该字节数组转换为您的 Sound 对象。
  • @SushiHangove 哦,Sound .extract 提取处理后的数据(帧),这是我最大的遗憾。它与原始 mp3 文件数据无关
  • 比使用URLStream,从那里读取和转换
  • @SushiHangover 似乎需要重写太多代码
  • @elDude 您在寻找 ID3 信息吗?如果是,您可以在您的Sound 对象上使用Event.ID3 事件侦听器来获取...

标签: actionscript-3 object flash-cs5


【解决方案1】:

flash.media.Sound 是一个高级类,允许您在一行中播放声音文件:new Sound(new URLRequest('your url')).play();,但不提供对正在加载的数据的公共访问

该课程将为您处理流式传输(更准确地说,渐进式下载)

如果需要访问 id3 数据,只需监听 Event.ID3 事件即可:

var sound:Sound = new Sound("http://archive.org/download/testmp3testfile/mpthreetest.mp3");
sound.addEventListener(Event.ID3, onId3);
sound.play();
function onId3(e:Event):void {
    var id3:ID3Info = (e.target as Sound).id3;
    trace(id3.album, id3.artist, id3.comment, id3.genre,
        id3.songName, id3.track, id3.year);
}

如果您确实需要获取原始的前 48 个字节并自己处理它们,但请记住,您将不得不处理各种 mp3 格式 id3/no id3,并直接处理二进制数据,而不是让 actionscript 做为你工作。 假设您不想两次下载 mp3 文件,您可以:

  • 使用 URLLoader 将 mp3 文件加载为 ByteArray,手动读取 48 个字节,然后从内存中加载 Sound 实例,从而失去任何渐进式下载能力。 :

    var l:URLLoader = new URLLoader;
    l.dataFormat = URLLoaderDataFormat.BINARY;
    l.addEventListener(Event.COMPLETE, onComplete);
    l.load(new URLRequest("http://archive.org/download/testmp3testfile/mpthreetest.mp3"));
    function onComplete(e:Event):void {
        //do whatever you need to do with the binary data (l.data)
        // ...
        // load sound from memory
        new Sound().loadCompressedDataFromByteArray(l.data, l.data.length);
    
  • 您还可以使用经典方式加载 Sound 类(以允许渐进式下载),并使用 URLStream 独立加载前 48 个字节,并尽快关闭流(仅网络开销的一个数据包,另外您可能会得到无论如何它都来自缓存):

    var s:URLStream = new URLStream;
    s.addEventListener(ProgressEvent.PROGRESS, onStreamProgress);
    s.load(new URLRequest("http://archive.org/download/testmp3testfile/mpthreetest.mp3"));
    function onStreamProgress(e:ProgressEvent):void {
        if (s.bytesAvailable >= 48) {
            // whatever you need to do with the binary data: s.readByte()...
            s.close();
        }
    }
    

我仍然很想知道您为什么需要这 48 个字节?

编辑:由于应该将 48 个字节提供给 MP3InfoUtil,因此您不需要做任何特别的事情,只需让 lib 完成工作即可:

MP3InfoUtil.addEventListener(MP3InfoEvent.COMPLETE, yourHandler);
MP3InfoUtil.getInfo(yourMp3Url);

【讨论】:

  • 我没想过缓存。在我的情况下,在 oncomplete 事件之后再次(从缓存)下载它真的很简单。当然这不是我问题的答案(我在Object 中想到了类似 URLStream 的东西),但我认为除了你给出的方法之外别无他法
  • ps 48 字节 - 用于MP3InfoUtil。有人告诉我它比 as3 的 Sound 的原生 id 更好
  • 我查看了 MP3InfoUtil,它已经在使用 URLStream 来获取前 48 个字节,所以我更新了答案
  • 我重写了MP3InfoUtil 的一些代码以仅解析ByteArray 数据,但我也确信从Sound 对象获取原始数据没有问题))
  • 你已经有 MP3InfoUtil.analyze(bytes:ByteArray) 可以从内存中处理,并且 MP3InfoUtil.getInfo(url:String,...) 可以在远程 url 上工作,我认为你不需要更多
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-27
  • 1970-01-01
  • 1970-01-01
  • 2012-04-28
  • 2012-05-18
  • 2022-11-11
相关资源
最近更新 更多