AVPlayer实时流如何获得功率以进行音频电平计量 [英] AVPlayer Live stream how to get power for audio level metering
问题描述
我试图在我的应用中显示一个仪表图,该仪表图使用AVPlayer传输实时音频流.
I am trying to show a meter graph in my app which uses AVPlayer to stream live audio streams.
我知道对于AVAudioPlayer,有一种方法如下: 试图了解AVAudioPlayer和音频电平计量
I know for AVAudioPlayer there is a way as per: Trying to understand AVAudioPlayer and audio level metering
使用peakPowerForChannel
但是AVAudioPlayer不适用于音频流.
But AVAudioPlayer doesn't work for audio streams.
AVPlayer是否有类似的东西?还是有其他方法可以从AVPlayer获取功率值?
Is there something similar for AVPlayer? Or is there any other way I can get the power values from the AVPlayer?
代码:
[[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];
}
}
}
推荐答案
通常,您可以通过在播放器项目上使用MTAudioProcessingTap
来获取AVPlayer
的音频样本,但是您的资产会对此进行抵抗>
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
-
AVURLAsset
上的tracks
属性从不可用 - 当您观察并将水龙头连接到
playerItem.tracks
的assetTrack
时,请不要回电.
- the
tracks
property on yourAVURLAsset
never becoming available - not calling you back when you observe and attach the tap to your
playerItem.tracks
'sassetTrack
.
我从未见过很好的解释,为什么它不适用于远程mp3
或m3u8
流,但令人讨厌的是,它确实适用于其他远程资产类型,例如aac
.不公平地,在视频方面, AVPlayerItemVideoOutput 似乎适用于所有类型的资产(除非存在DRM问题)!
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
. Unjustly, on the video side, AVPlayerItemVideoOutput seems to work for all types of assets (barring DRM problems)!
那么这会让你离开哪里?一种方法是自己流式传输mp3数据,您可以在其中使用AudioQueue
对其进行解码和播放,然后 使用上述MTAudioProcessingTap
计算峰值功率.还想到了涉及AudioConverter
/AudioUnit
和AVAudioConverter
/AVAudioEngine
的解决方案.
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
. Solutions involving AudioConverter
/AudioUnit
and AVAudioConverter
/AVAudioEngine
come to mind too.
如果只是为了替换单个属性而听起来工作量太大,则可以查看预先烘焙的解决方案,例如 FreeStreamer ,然后计算功效.您可能会找到一个可以为您计算功率的库.如果没有,您可以使用此公式
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. You may find a library that calculates power for you. If not, you can calculate peakPowerForChannel
using this formula
这篇关于AVPlayer实时流如何获得功率以进行音频电平计量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!