AVPlayer HLS 直播电平表(显示 FFT 数据)

Posted

技术标签:

【中文标题】AVPlayer HLS 直播电平表(显示 FFT 数据)【英文标题】:AVPlayer HLS live stream level meter (Display FFT Data) 【发布时间】:2013-10-24 13:51:26 【问题描述】:

我将AVPlayer 用于使用 HTTP 实时流媒体的广播应用程序。现在我想为那个音频流实现一个电平表。最好的电平表显示不同的频率,但一个简单的左/右解决方案将是一个很好的起点。

我发现了几个使用AVAudioPlayer 的示例。但我找不到从AVPlayer 获取所需信息的解决方案。

有人能想出解决我问题的办法吗?

编辑我想创建这样的东西(但更好)

编辑二

一个建议是使用MTAudioProcessingTap 来获取原始音频数据。我可以使用[[[_player currentItem] asset] tracks] 数组找到的示例,在我的例子中,它是一个空数组。另一个建议是使用[[_player currentItem] audioMix],对我来说是null

编辑 III

之后,似乎仍然没有解决方案。我确实取得了进步,所以我正在分享它。

在设置过程中,我向 playerItem 添加了一个键值观察器:

[[[self player] currentItem] addObserver:self forKeyPath:@"tracks" options:kNilOptions context:NULL];

//////////////////////////////////////////////////////

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)changecontext:(void *)context
    if ([keyPath isEqualToString:@"tracks"] && [[object tracks] count] > 0) 
        for (AVPlayerItemTrack *itemTrack in [object tracks]) 
            AVAssetTrack *track = [itemTrack assetTrack];

            if ([[track mediaType] isEqualToString:AVMediaTypeAudio]) 
                [self addAudioProcessingTap:track];
                break;
            
        


- (void)addAudioProcessingTap:(AVAssetTrack *)track 
    MTAudioProcessingTapRef tap;
    MTAudioProcessingTapCallbacks callbacks;
    callbacks.version = kMTAudioProcessingTapCallbacksVersion_0;
    callbacks.clientInfo = (__bridge void *)(self);
    callbacks.init = init;
    callbacks.prepare = prepare;
    callbacks.process = process;
    callbacks.unprepare = unprepare;
    callbacks.finalize = finalise;

    // more tap setup...

    AVMutableAudioMix *audioMix = [AVMutableAudioMix audioMix];

    AVMutableAudioMixInputParameters *inputParams = [AVMutableAudioMixInputParameters audioMixInputParametersWithTrack:audioTrack];
    [inputParams setAudioTapProcessor:tap];
    [audioMix setInputParameters:@[inputParams]];

    [[[self player] currentItem] setAudioMix:audioMix];

到目前为止一切顺利。这一切都有效,我可以找到正确的轨道并设置 inputParams 和 audioMix 等。 但不幸的是,唯一被调用的回调是 init 回调。其他任何一个都不会在任何时候开火。

我尝试了不同(种类)的流源,其中一个是官方 Apple HLS 流:http://devimages.apple.com/iphone/samples/bipbop/bipbopall.m3u8

【问题讨论】:

电平表需要什么?,如果你在玩直播,@Julian 我正在开发一个无线电应用程序,我的客户设计师想要一个用于各种频率的电平表。像这样(但更好)oocities.org/henrym24/eq.gif 好的,我从事实时流媒体工作,但不是像这样的音频可视化,我已经发布了一些示例链接的答案,希望您能得到帮助。快乐编码:) @Julian 你看过***.com/questions/28109516/…吗? 其实不是,谢谢。我假设他流式传输实际的音频文件。仅在 HLS 的情况下不会调用回调。稍后我会更深入地了解并评论那里。 【参考方案1】:

遗憾的是,使用带有AVFoundation 的 HLS 流无法让您对音轨进行任何控制。我在尝试使 HLS 流静音时遇到了同样的问题,结果证明这是不可能的。

读取音频数据的唯一方法是点击AVAudiosession

编辑

您可以像这样访问 AVAudioSession:

[AVAudioSession sharedInstance]

这是AVAudioSession的文档

【讨论】:

如何访问会话? 嗯,这看起来很有希望,谢谢。然后使用此会话(或其任何属性)作为MTAudioProcessingTap 的输入吗? 问得好,但处理音频所需的任何信息都应该在其中提供。 @Simon Germain 查看我对 Julian re HLS 流的评论。确实可以将 MTAudioProcessingTap 插入通过 AVPlayer 托管的 HLS Stream。 @MDB983 只是在两年后回顾一下...您愿意向我们提供有关如何它可以完成的任何细节吗?【参考方案2】:

使用AVPlayer 测量音频似乎是一个仍在进行的问题。话虽如此,我相信可以通过结合AVPlayerAVAudioRecorder 来实现解决方案。

虽然这两个类的目的看似矛盾,但有一种解决方法允许AVAudioRecorder 访问AVPlayer 的音频输出。

播放器/录音机

如Stack Overflow Answer 中所述,如果您使用kAudioSessionProperty_AudioRouteChange 访问音频路由更改,则可以录制 AVPlayer 的音频。

请注意,必须访问音频路由更改后开始录音。使用链接堆栈答案作为参考 - 它包含更多详细信息和必要的代码。

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~

一旦您可以访问AVPlayer 的音频路径并进行录音,测量就相对简单了。

音频电平

在我的answer 中关于测量麦克风输入的堆栈问题中,我描述了访问音频电平测量所需的步骤。使用AVAudioRecorder 监控音量变化比人们想象的要复杂,因此我添加了一个 GitHub project,它充当了在录制时监控音频变化的模板。

~~~~~~~~~~~~~~~~~~~~~~~~~~ 请注意 ~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~

HLS 直播期间的这种组合不是我测试过的。这个答案是严格理论上的,因此可能需要对这两个类有充分的理解才能完全解决。

【讨论】:

哇 - 这听起来像是一个明显的解决方法,一旦有人描述它,但很难想到你自己......非常感谢!我必须看看,因为这个问题现在已经有四年多了(即使我偶尔研究过这个话题)。请给我几天的时间来解决这个问题——我会尽快重新审视这个问题。再次感谢您分享您的想法! 当然。根据提供的答案中的 cmets,在我看来,还有很多其他人正在寻找可行的解决方案。更不用说,您的问题获得的票数/星数。

以上是关于AVPlayer HLS 直播电平表(显示 FFT 数据)的主要内容,如果未能解决你的问题,请参考以下文章

AVPlayer HLS 直播 IOS

AVPlayer 不播放 HLS 流

Hls 流 url 不会在 AVPlayer 中播放

如何在原生 iOS 应用程序中显示 Vimeo 实时视频流

在 iOS SDK - AVPlayer 中手动选择视频质量的 HLS 流?

是否可以使用 AVPlayer 缓存 HLS 段?