65

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

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

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

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

漂亮的水平仪

编辑二

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

编辑三

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

在设置过程中,我向 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

4

2 回答 2

2

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

您可以读取音频数据的唯一方法是点击AVAudioSession.

编辑

您可以像这样访问 AVAudioSession:

[AVAudioSession sharedInstance]

这是AVAudioSession的文档

于 2014-06-01T18:46:07.130 回答
2

使用外观测量音频AVPlayer仍然是一个持续存在的问题。话虽如此,我相信可以通过AVPlayer结合AVAudioRecorder.

虽然这两个类的目的看似矛盾,但有一种变通方法可以AVAudioRecorder访问AVPlayer的音频输出。

播放器/录音机

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

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

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

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

音频电平

在我对有关测量麦克风输入的堆栈问题的回答中,我描述了访问音频电平测量所需的步骤。用于AVAudioRecorder监控音量变化比人们想象的要复杂,因此我包含了一个 GitHub项目,该项目用作在录制时监控音频变化的模板。

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

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

于 2017-09-04T20:46:29.803 回答