简体   繁体   English

AVPlayer Live 流如何获得用于音频电平计量的电源

[英]AVPlayer Live stream how to get power for audio level metering

I am trying to show a meter graph in my app which uses AVPlayer to stream live audio streams.我试图在我的应用程序中显示一个仪表图,它使用 AVPlayer 来流式传输实时音频流。

I know for AVAudioPlayer there is a way as per: Trying to understand AVAudioPlayer and audio level metering我知道 AVAudioPlayer 有一种方法: 尝试了解 AVAudioPlayer 和音频电平表

which uses peakPowerForChannel它使用peakPowerForChannel

But AVAudioPlayer doesn't work for audio streams.但是 AVAudioPlayer 不适用于音频流。

Is there something similar for AVPlayer? AVPlayer 有类似的东西吗? Or is there any other way I can get the power values from the AVPlayer?或者有没有其他方法可以从 AVPlayer 获取功率值?

Code:代码:

[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];
    if (self.avplayer) {
        [self.avplayer replaceCurrentItemWithPlayerItem:nil];
    }
    AVURLAsset *avAsset = [[AVURLAsset alloc] initWithURL:[NSURL URLWithString:@"http://broadcast.infomaniak.net/radionova-high.mp3"] options:nil];
    NSArray *keys = @[@"playable"];
    [avAsset loadValuesAsynchronouslyForKeys:keys completionHandler:^{
        dispatch_async(dispatch_get_main_queue(), ^{
            AVPlayerItem *newItem = [[AVPlayerItem alloc] initWithAsset:avAsset];
            if (!self.avplayer) {
                self.avplayer = [[AVPlayer alloc] initWithPlayerItem:newItem];
            } else {
                [self.avplayer replaceCurrentItemWithPlayerItem:newItem];
            }
            [self.avplayer addObserver:self forKeyPath:@"status" options:(NSKeyValueObservingOptionNew | NSKeyValueObservingOptionInitial) context:nil];
            [self.avplayer addObserver:self forKeyPath:@"rate" options:(NSKeyValueObservingOptionNew | NSKeyValueObservingOptionInitial) context:nil];
        });
    }];

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object
                        change:(NSDictionary *)change context:(void *)context {
    NSLog(@"%@ called",keyPath);
    if ( [keyPath isEqualToString:@"status"]) {
        [self.avplayer play];
    } else if ( [keyPath isEqualToString:@"rate"]) {
        if (self.avplayer.rate) {
            NSLog(@"Playing...");
            [[NSNotificationCenter defaultCenter] postNotificationName:@"currentPlayingChangedToPlay" object:nil];

        } else {
            NSLog(@"Not playing...");
            [[NSNotificationCenter defaultCenter] postNotificationName:@"currentPlayingChangedToPause" object:nil];
        }
    }

}

Ordinarily, you can get at the audio samples of an AVPlayer by using an MTAudioProcessingTap on the player item, however your asset resists this through通常,您可以通过在播放器项目上使用MTAudioProcessingTap来获取AVPlayer的音频样本,但是您的资产通过

  1. the tracks property on your AVURLAsset never becoming availabletracks上你的财产AVURLAsset从来没有变得可用
  2. not calling you back when you observe and attach the tap to your playerItem.tracks 's assetTrack .当您观察并将点击附加到您的playerItem.tracksassetTrack时,不会给您assetTrack

I've never seen a good explanation for why this doesn't work for remote mp3 s or m3u8 streams, and annoyingly, it does work for other remote asset types, like aac .对于为什么这对远程mp3 s 或m3u8流不起作用,我从未见过很好的解释,而且令人讨厌的是,它确实适用于其他远程资产类型,例如aac Unjustly, on the video side, AVPlayerItemVideoOutput seems to work for all types of assets (barring DRM problems)!不公平的是,在视频方面, AVPlayerItemVideoOutput似乎适用于所有类型的资产(除非 DRM 问题)!

So where does this leave you?那么这会让你在哪里呢? One way is to stream the mp3 data yourself from where you can decode and play it using an AudioQueue , and also calculate the peak power using the aforementioned MTAudioProcessingTap .一种方法是自己从那里你可以解码和使用播放流的MP3数据AudioQueue ,并且计算使用上述峰值功率MTAudioProcessingTap Solutions involving AudioConverter / AudioUnit and AVAudioConverter / AVAudioEngine come to mind too.涉及解决方案AudioConverter / AudioUnitAVAudioConverter / AVAudioEngine脑海里浮现了。

If that sounds like too much work just to replace a single property, you could look at pre-baked solutions, like StreamingKit or FreeStreamer and then calculate power.如果仅仅替换单个属性听起来工作量太大,您可以查看预烘焙的解决方案,例如StreamingKitFreeStreamer ,然后计算功率。 You may find a library that calculates power for you.您可能会找到一个可以为您计算功率的库。 If not, you can calculate peakPowerForChannel using this formula如果没有,您可以使用此公式计算peakPowerForChannel

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM