【问题标题】:Objective c - play mp3 stream frame by frame from memory bufferObjective c - 从内存缓冲区逐帧播放 mp3 流
【发布时间】:2016-05-23 17:30:48
【问题描述】:

我想通过一一提交音频帧来播放 mp3 音频流。 我必须从内存缓冲区提交它 - 不使用 mp3 文件 url(假设 mp3 从网络流式传输并到达内存缓冲区)。

我应该从哪里开始? 有没有做这种事情的示例代码?

【问题讨论】:

  • 你能把它做成一个 MP3 文件吗?如,你能像这样排列字节吗?我不是要求您将其写入任何地方或在任何时候都可以使用整个内容,但作为消费者,我是否可以继续向您询问下一个字节并最终接收到看起来像有效 MP3 文件的流?
  • 我不完全理解您的评论,所以如果我没有回答您的问题,请告诉我。我逐帧获取内存缓冲区(uint 数组)中的数据。原始数据来自一个真正的 mp3 文件,所以基本上我可以保存所有缓冲区并播放它,但我想尽快播放数据。所以从技术上讲,我认为你的问题的答案是肯定的 :)
  • 我正在尝试决定是否值得提倡您只编写一个NSURLProtocol 子类,为您提供一种异步方式,作为任何从 URL 读取的数据源。我不得不承认我不确定沙盒的最新情况(出于 DRM 原因,AVFoundation 不一定尊重您的NSURLProtocols),所以这可能不是一个答案。除非或直到我可以更新自己,否则将其作为一次性评论。
  • 谢谢。我最终找到了解决方案并发布了它。

标签: objective-c avfoundation core-audio apple-tv


【解决方案1】:

所以它似乎比我想象的要简单得多......

我刚刚创建:

    AVAudioPlayer* oAudioPlayer;

并用数据初始化它:

    oAudioPlayer = [[AVAudioPlayer alloc] initWithData:chunk fileTypeHint:AVFileTypeMPEGLayer3 error:&error];

虽然块是从网络到达的一些 mp3 帧。

以及最终的播放方法:

    if ([oAudioPlayer play] == false)
        NSLog(@"failed to play audio buffer");

如果想要在播放完帧时有一个回调,他可以在播放前添加一个委托:

    oAudioPlayer.delegate = oSound;

而 oSound 是一个类:

    @interface    SoundClass : NSObject <AVAudioPlayerDelegate> {}

    @property(nonatomic,retain) AVAudioPlayer *player;

    - (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag;
    - (void)audioPlayerDecodeErrorDidOccur:(AVAudioPlayer *)player error:(NSError * __nullable)error;

    @end

似乎音频播放器需要大缓冲区(我需要至少两个原始帧才能听到声音)。

目前,音频听起来不够好,但我想这是我做错了数据馈送的问题。

【讨论】:

  • 您能否发布一段完整的代码以更清晰。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-01-05
  • 1970-01-01
  • 1970-01-01
  • 2018-11-02
  • 1970-01-01
  • 2014-08-01
  • 1970-01-01
相关资源
最近更新 更多