如何使用 AvAudioPlayer 实现 MPNowPlayingInfoCenter
How to Implementing MPNowPlayingInfoCenter using AvAudioPlayer
我正在为客户端创建一个 iOS 移动应用程序,它将播放各种音轨。
我想要实现的功能之一是在锁定屏幕和横幅上显示有关当前正在播放的音轨的信息。这是移动用户的简单便利之一,如果您的应用程序有背景音频播放,则必须具备。就个人而言,我一直在使用这个功能!
您应该首先观察 AVAudioPlayer
的 AVPlayerItem
,如下所示:
[playerItem addObserver:self forKeyPath:@"timedMetadata" options:NSKeyValueObservingOptionNew context:nil];
然后创建一些全局变量:
NSString *title;
NSString *artist;
UIImage *artwork;
然后您可能需要如下所示的功能,因此您观察关键路径 timedMetadata
并通过 updateInfoCenterWithTitle:andArtist:andCover:
.
更新信息中心
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
if ([keyPath isEqualToString:@"timedMetadata"])
{
for (int i = 0; i < [audioPlayer.currentItem.timedMetadata count]; i++)
{
AVMetadataItem *metaData = [audioPlayer.currentItem.timedMetadata objectAtIndex:i];
if ([[metaData commonKey] isEqualToString:AVMetadataCommonKeyArtist]) {
artist = (NSString *)metaData.value;
}
else if ([[metaData commonKey] isEqualToString:AVMetadataCommonKeyTitle])
{
title = (NSString *)metaData.value;
[self updateInfoCenterWithTitle:title andArtist:artist andCover:artwork];
}
else if ([[metaData commonKey] isEqualToString:AVMetadataCommonKeyArtwork])
{
if ([metaData.keySpace isEqualToString:AVMetadataKeySpaceID3])
{
NSDictionary *dictionary = [metaData.value copyWithZone:nil];
artwork = [UIImage imageWithData:[dictionary objectForKey:@"data"]]];
} else if ([metaData.keySpace isEqualToString:AVMetadataKeySpaceiTunes]) {
artwork = [UIImage imageWithData:[metaData.value copyWithZone:nil]];
}
}
else {
NSLog(@"%@ --> %@", [metaData commonKey], metaData.value);
}
}
}
}
这就是奇迹发生的地方:
- (void)updateInfoCenterWithTitle:(NSString *)title andArtist:(NSString *)artist andCover:(UIImage *)cover
{
if (cover == nil) {
cover = [UIImage imageNamed:@"defaultCover"];
}
MPNowPlayingInfoCenter *infoCenter = [MPNowPlayingInfoCenter defaultCenter];
[infoCenter setNowPlayingInfo:@{MPMediaItemPropertyTitle:title,
MPMediaItemPropertyArtist:artist,
MPMediaItemPropertyArtwork:[[MPMediaItemArtwork alloc] initWithImage:cover]}];
}
我正在为客户端创建一个 iOS 移动应用程序,它将播放各种音轨。
我想要实现的功能之一是在锁定屏幕和横幅上显示有关当前正在播放的音轨的信息。这是移动用户的简单便利之一,如果您的应用程序有背景音频播放,则必须具备。就个人而言,我一直在使用这个功能!
您应该首先观察 AVAudioPlayer
的 AVPlayerItem
,如下所示:
[playerItem addObserver:self forKeyPath:@"timedMetadata" options:NSKeyValueObservingOptionNew context:nil];
然后创建一些全局变量:
NSString *title;
NSString *artist;
UIImage *artwork;
然后您可能需要如下所示的功能,因此您观察关键路径 timedMetadata
并通过 updateInfoCenterWithTitle:andArtist:andCover:
.
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
if ([keyPath isEqualToString:@"timedMetadata"])
{
for (int i = 0; i < [audioPlayer.currentItem.timedMetadata count]; i++)
{
AVMetadataItem *metaData = [audioPlayer.currentItem.timedMetadata objectAtIndex:i];
if ([[metaData commonKey] isEqualToString:AVMetadataCommonKeyArtist]) {
artist = (NSString *)metaData.value;
}
else if ([[metaData commonKey] isEqualToString:AVMetadataCommonKeyTitle])
{
title = (NSString *)metaData.value;
[self updateInfoCenterWithTitle:title andArtist:artist andCover:artwork];
}
else if ([[metaData commonKey] isEqualToString:AVMetadataCommonKeyArtwork])
{
if ([metaData.keySpace isEqualToString:AVMetadataKeySpaceID3])
{
NSDictionary *dictionary = [metaData.value copyWithZone:nil];
artwork = [UIImage imageWithData:[dictionary objectForKey:@"data"]]];
} else if ([metaData.keySpace isEqualToString:AVMetadataKeySpaceiTunes]) {
artwork = [UIImage imageWithData:[metaData.value copyWithZone:nil]];
}
}
else {
NSLog(@"%@ --> %@", [metaData commonKey], metaData.value);
}
}
}
}
这就是奇迹发生的地方:
- (void)updateInfoCenterWithTitle:(NSString *)title andArtist:(NSString *)artist andCover:(UIImage *)cover
{
if (cover == nil) {
cover = [UIImage imageNamed:@"defaultCover"];
}
MPNowPlayingInfoCenter *infoCenter = [MPNowPlayingInfoCenter defaultCenter];
[infoCenter setNowPlayingInfo:@{MPMediaItemPropertyTitle:title,
MPMediaItemPropertyArtist:artist,
MPMediaItemPropertyArtwork:[[MPMediaItemArtwork alloc] initWithImage:cover]}];
}