Using Media Playback
使用媒体播放
想要从设备iPod库播放歌曲、有声书、和播客,你需要使用媒体播放器――一个MPMusicPlayerController类的实例。简单的说,执行步骤如下:
1.注册一个接收音乐播放器的通知,并打开通知。
2.创建一个音乐播放器。
3.为音乐播放器设置一个播放队列。
4.配置回放选项。
5.调用回放。
本章描述如何实现这些步骤。它也提供了处理一些在使用音乐播放器的时候可能会遇到的情况的指导,例如在音乐播放的时候添加音乐到现有的回放队列。本章扩展版本的代码示例是在AddMusic 中。
Important: 一次只能有一个音乐播放器播放音频。音乐播放器只能使用应用程序的主线程。
Registering for Music Player Notifications
为音乐播放器注册通知
如果你提供音乐播放器回放控制,或者如果你显示关于当前播放项目的信息,你必须为音乐播放器注册通知,如 代码清单2-1 所示。
代码清单 2-1 注册并激活音乐播放器通知
NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
[notificationCenter
addObserver: self
selector: @selector (handle_NowPlayingItemChanged:)
name: MPMusicPlayerControllerNowPlayingItemDidChangeNotification
object: musicPlayer];
[notificationCenter
addObserver: self
selector: @selector (handle_PlaybackStateChanged:)
name: MPMusicPlayerControllerPlaybackStateDidChangeNotification
object: musicPlayer];
[musicPlayer beginGeneratingPlaybackNotifications];
你实现这些方法提供给选择器:如参数所示。实现的例子见AddMusic。
在释放音乐播放器之前,要注销通知并关闭它们,如代码清单2-2所示。
代码清单 2-2 注销和灭活音乐播放器通知
[[NSNotificationCenter defaultCenter]
removeObserver: self
name: MPMusicPlayerControllerNowPlayingItemDidChangeNotification
object: musicPlayer];
[[NSNotificationCenter defaultCenter]
removeObserver: self
name: MPMusicPlayerControllerPlaybackStateDidChangeNotification
object: musicPlayer];
[musicPlayer endGeneratingPlaybackNotifications];
Creating and Configuring a Music Player
创建和配置音乐播放器
创建应用程序的音乐播放器,要调用applicationMusicPlayer类方法如代码清单2-3第一行所示。
代码清单 2-3 创建一个应用程序音乐播放器
MPMusicPlayerController* appMusicPlayer =
[MPMusicPlayerController applicationMusicPlayer];
[appMusicPlayer setShuffleMode: MPMusicShuffleModeOff];
[appMusicPlayer setRepeatMode: MPMusicRepeatModeNone];
如代码清单所示,你也许也想配置随机和重复模式,这样它们就不会像iPod应用程序的应用程序那样被默认设置为开启。
各种随机和重复模式的详细解释见MPMusicPlayerController Class Reference.
创建iPod音乐播放器有一个额外的步骤,因为你访问的内置的iPod应用程序的状态以及可能有一个当你应用程序启动的时候就正在播放的项目。代码清单 2-4 显示了如何测试iPod应用程序正在播放从设备iPod库中的媒体项。
代码清单 2-4 创建一个iPod音乐播放器
MPMusicPlayerController* iPodMusicPlayer =
[MPMusicPlayerController iPodMusicPlayer];
if ([iPodMusicPlayer nowPlayingItem]) {
// Update the UI (artwork, song name, volume indicator, etc.)
// to reflect the iPod state
}
如代码所示,应用程序能够基于现在播放项目来更新它的用户界面。
Important: 如果iPod应用程序正在播放一个使用家庭共享的共享歌曲,这个iPod音乐播放器的nowPlayingItem属性的值为nil。然而,iPod音乐播放器的playbackState属性总是反应iPod应用程序实际的播放状态。
Setting Up a Playback Queue
设置播放队列
有两种主要途径来为音乐播放器设置队列:
使用媒体项集合。
使用媒体查询,它隐式的定义了一个集合。
通过使用数据库访问类或者调用媒体项选取器得到一个集合。两条路,都适用于集合去让音乐播放器回调一个单独方法。
[musicPlayer setQueueWithItemCollection: userMediaItemCollection];
或者,你可以用媒体查询来设置队列――它隐式定义了一个集合,如下所示:
[musicPlayer setQueueWithQuery: [MPMediaQuery songsQuery]];
当然,你可以指定一个更加复杂的查询作为setQueueWithQuery方法的参数。关于查询的更多内容,详见“Using the iPod Library.”
代码清单2-5展示了一个实际的播放队列的设置――播放状态所占的比例、是否一个新的集合会取代播放器的队列或者添加到现有队列,等等。
代码清单 2-5 在上下文中设置一个回放队列
- (void) updateQueueWithCollection: (MPMediaItemCollection *) collection {
// Add 'collection' to the music player's playback queue, but only if
// the user chose at least one song to play.
if (collection) {
// If there's no playback queue yet…
if (userMediaItemCollection == nil) {
[self setUserMediaItemCollection: collection];
[musicPlayer setQueueWithItemCollection: userMediaItemCollection];
[musicPlayer play];
// Obtain the music player's state so it can be restored after
// updating the playback queue.
}
else {
BOOL wasPlaying = NO;
if (musicPlayer.playbackState == MPMusicPlaybackStatePlaying) {
wasPlaying = YES;
}
// Save the now-playing item and its current playback time.
MPMediaItem *nowPlayingItem = musicPlayer.nowPlayingItem;
NSTimeInterval currentPlaybackTime = musicPlayer.currentPlaybackTime;
// Combine the previously-existing media item collection with
// the new one
NSMutableArray *combinedMediaItems =
[[userMediaItemCollection items] mutableCopy];
NSArray *newMediaItems = [mediaItemCollection items];
[combinedMediaItems addObjectsFromArray: newMediaItems];
[self setUserMediaItemCollection:
[MPMediaItemCollection collectionWithItems:
(NSArray *) combinedMediaItems]];
[musicPlayer setQueueWithItemCollection: userMediaItemCollection];
// Restore the now-playing item and its current playback time.
musicPlayer.nowPlayingItem = nowPlayingItem;
musicPlayer.currentPlaybackTime = currentPlaybackTime;
if (wasPlaying) {
[musicPlayer play];
}
}
}
}
这个方法分支取决于是否有一个事先存在的回放队列,且确保播放状态在添加到播放列表的时候被保留。
Controlling Playback
控制播放
音乐播放器的播放控制是简单的,详见MPMusicPlayerController Class Reference.你能够播放、暂停、停止、向前或向后、以及跳转到之前或之后。
此外,currentPlaybackTime property 属性是可读写的;你可以使用它在正在播放项目的时间轴上设置播放点。
例如,你可以让用户在媒体项时间轴上通过应用程序用户界面上的UISlider 设置播放点。在下面的例子中,这种滑块被认为和timelineSlider 实例变量是有联系的。
- (IBAction) setTimelinePosition: (id) sender {
[musicPlayer setCurrentPlaybackTime: [timelineSlider value]];
}