《iOS组件与框架——iOS SDK高级特性剖析》——第6章,第6.2节打造播放引擎

6.2 打造播放引擎
iOS组件与框架——iOS SDK高级特性剖析
如果对播放控制没有深刻认识,获取音频数据将毫无意义。要在应用中播放音乐,需要创建一个MPMusicPlayerController实例。在头文件ICFViewController.h中,声明了一个名为player的MPMusicPlayerController变量,在整个示例应用中,都将使用它来控制播放以及获取当前播放的曲目的信息。

在方法viewDidLoad中,初始化了MPMusicPlayerController变量player,这是使用MPMusicPlayerController的一个类方法完成的。创建MPMusicPlayerController实例的方式有两种:一是使用applicationMusicPlayer,这将在应用内播放音乐,不影响iPod的状态,并在应用退出后停止播放;二是使用iPodMusicPlayer,这将控制应用iPod,从iPod播放头的位置开始继续播放,应用进入后台后也不会停止播放。本章的示例应用使用的是applicationMusicPlayer;但可轻松地转而使用iPodMusicPlayer,而无需对其他代码做任何修改。

6.2.1 注册播放通知
要有效地播放音乐,必须知道音乐播放器的状态。处理音乐播放器时,需要监视3种通知:当前播放的乐曲变了、音量变了,以及播放状态发生了变化。要监视这些状态,可使用NSNotificationCenter来订阅前述事件。为确保代码整洁易懂,示例应用使用了辅助方法registerMediaPlayerNotifications。将观察者加入NSNotificationCenter后,需要对对象player调用beginGeneratingPlaybackNotifications。

注册通知后,确保在清理内存和视图期间将它们注销,这很重要,否则将导致应用崩溃以及其他意外行为。另外,在方法viewWillDisapper中还调用了endGeneratingPlayback Notifications。

除注册音乐播放器回调方法外,还将创建一个NSTimer,用于更新播放进度和播放头时间标签。在示例应用中,这个NSTimer名为playbackTimer。对于通知回调方法和NSTimer,暂时就介绍这些,后面的6.2.3节将详细讨论它们。

6.2.2 播放控制
示例应用提供了多个让用户能够与音乐播放器交互的按钮,如播放、暂停、下一曲、前一曲以及前进和后退30秒。首先需要实现的是播放和暂停方法。这是一个简单的切换按钮:如果正在播放,就暂停;如果已暂停或停止,就继续播放。至于将按钮文本在Play和Pause之间切换的代码,将在6.2.3节讨论状态变化通知回调方法时进行讨论。

用户欣赏音乐时,还应能够跳到下一曲或前一曲。这是通过对对象player调用另外两个方法实现的。

6.2.3 响应状态变化
前面给3个通知注册了回调方法。这些通知让应用能够获悉MPMusicPlayerController的当前状态和行为。当前播放的曲目变了时,将调用第一个方法。这个方法包含两部分,第一部分更新专辑封面,第二部分更新显示艺术家、曲目名和专辑的标签。

MPMusicPlayerController当前播放的音频或视频由一个MPMediaItem对象表示,要获取这个对象,可对MPMusicPlayerController实例调用方法nowPlayingItem。

创建了一个用于表示专辑封面的UIImage,并将其初始化为一个占位符,在MPMediaItem没有专辑封面时将显示该占位符。MPMediaItem使用键值属性来表示存储的数据,表6.1列出了所有的键值属性。创建了一个MPMediaItemArtwork,并将其设置为专辑封面数据。Apple文档指出,如果没有专辑封面,获取属性MPMediaItemPropertyArtwork时将返回nil,但实际情况并非如此。为解决这个问题,将专辑封面加载到一个UIImage中,并检查结果。如果结果为nil,就认为没有专辑封面,进而加载前面指定的占位符。即便MPMediaItemPropertyArtwork在没有专辑封面时返回nil,示例应用也能正常运行。

方法nowPlayingItemChanged:的第二部分更新歌曲名、艺术家信息和专辑名,如图6.1所示。如果获取这些属性时返回nil,就使用占位符字符串。表6.1列出了MPMediaItem的所有可访问属性。请注意,媒体项为播客时,则除表6.1所示的属性外,还有其他一些属性,详情请参阅Apple的MPMediaItem文档。在这个表中,还指出了以编程方式查找媒体项时,属性键是否可用于谓词搜索。

[

监视音乐播放器的状态很重要,在状态可能受应用无法控制的外部输入的影响时尤其如此。如果状态发生变化,将调用方法playbackStateChanged:。在这个方法中,创建了变量playbackState,用于存储播放器的当前状态。这个方法执行了多项重要任务,其中第一项任务是更新按钮play/pause的文本,以反映当前状态。另外,创建和拆除了6.2.1节提到的NSTimer。如果应用正在播放音频,就将该定时器设置为每隔0.3秒触发一次,以便更新播放时间标签以及指出播放头位置的UIProgressIndicator。这个定时器触发的方法updateCurrentPlaybackTimer将在下一小节讨论。

除这个示例应用演示的状态外,还有其他3种状态。第一种状态是MPMusicPlaybackState Interrupted,表示音频播放中断,如来电导致中断。其他两种状态是MPMusicPlaybackState SeekingForward和MPMusicPlaybackStateSeekingBackward,表示音乐播放器正为查找指定播放位置而前进或后退。

如果音量发生变化,也必须通过应用的音量滑块反映出来。这是由通知回调方法volume Changed:完成的。在这个方法中,获取了播放器的当前音量,并相应地设置volumeSlider。

6.2.4 时长和定时器
在大多数情况下,用户都想获悉当前播放的歌曲的信息,如已播放多长时间以及还有多长时间。示例应用包含两个显示这些数据的方法。第一个是updateSongDuration,在当前播放的歌曲变了或应用启动时被调用。它创建一个指向当前播放歌曲的引用,再使用属性键playbackDuration获取该歌曲的时长(单位为秒)。然后,将这项数据转换为小时、分钟和秒数,并将结果显示在UIProgressIndicator旁边的标签上。

第二个方法是updateCurrentPlaybackTime,由NSTimer每隔0.3秒调用一次,而这个NSTimer由6.2.3节讨论的方法playbackStateChanged:控制。与方法updateSongDuration一样,将已播放的时间转换为小时、分钟和秒数;另外,还根据前面确定的歌曲时长计算percentagePlayed,并使用它来更新playbackProgressIndicator。由于currentPlaybackTime只能精确到秒,因此没有必要过于频繁地调用这个方法。然而,调用这个方法的频率越高,显示的结果就越精确。

6.2.5 随机播放和重复播放
除前面提到的属性和控制外,还可指定MPMusicPlayerController的属性repeatMode和shuffleMode。虽然示例应用没有实现设置这两个属性的功能,但实现起来非常容易。

重复播放模式包括MPMusicRepeatModeDefault(用户的预定义首选模式)、MPMusicRepeat ModeNone、MPMusicRepeatModeOne和MPMusicRepeatModeAll。

随机播放模式包括MPMusicShuffleModeDefault(用户的预定义首选模式)、MPMusicShuffle ModeOff、MPMusicShuffleModeSongs和MPMusicShuffleModeAlbums,其中MPMusicShuffle ModeDefault表示用户的预定义首选模式。

时间: 2024-10-28 11:06:14

《iOS组件与框架——iOS SDK高级特性剖析》——第6章,第6.2节打造播放引擎的相关文章

《iOS组件与框架——iOS SDK高级特性剖析》——第2章,第2.4节地图注释和覆盖层

2.4 地图注释和覆盖层 iOS组件与框架--iOS SDK高级特性剖析 地图视图(MKMapView)是一种可滚动的视图,行为独特:以标准方式在其中添加子视图时,子视图不会随地图视图滚动,而是静止的,其相对于地图视图框架的位置始终不变.对悬停按钮或标签来说,这种特点也许不错,但在地图上标出点和细节至关重要.要标出地图视图中感兴趣的点或区域,可使用地图注释和覆盖层.地图滚动或缩放时,注释和覆盖层在地图上的位置保持不变.地图注释是使用地图上的单个坐标点定义的,而地图覆盖层可以是线段.多边形或复杂形

《iOS组件与框架——iOS SDK高级特性剖析》——第8章,第8.6节键值存储同步

8.6 键值存储同步 iOS组件与框架--iOS SDK高级特性剖析 iCloud还支持键值存储同步.这类似于在NSMutableDictionary或NSUserDefaults中存储信息,将一个与对象值相关联的键用于存储和检索:iCloud键值存储的不同之处在于,将自动在设备之间同步键和值.本书编写期间,iCloud为每个应用提供1MB的键值存储空间,最多可存储1024个键值对,因此键值存储机制只适合用于存储少量信息. 本章的示例应用利用iCloud键值存储来跟踪最后修改的备忘录.详细视图控

《iOS组件与框架——iOS SDK高级特性剖析》——导读

目 录前言 第1章 UIKit Dynamics第2章 Core Location.MapKit和地理围栏 2.1 示例应用2.2 获取用户的位置 2.3 显示地图 2.4 地图注释和覆盖层2.5 地理编码和反向地理编码 2.6 地理围栏2.7 获取线路 2.8 小结 2.9 练习 第3章 排行榜第4章 成就第5章 地址簿第6章 使用音乐库 6.1 示例应用简介 6.2 打造播放引擎 6.3 媒体选择器6.4 以编程方式选择媒体 6.5 小结6.6 练习 第7章 使用和分析JSON第8章 iCl

常用iOS的第三方框架

图像:1.图片浏览控件MWPhotoBrowser       实现了一个照片浏览器类似 iOS 自带的相册应用,可显示来自手机的图片或者是网络图片,可自动从网络下载图片并进行缓存.可对图片进行缩放等操作.      下载:https://github.com/mwaterfall/MWPhotoBrowser 目前比较活跃的社区仍旧是Github,除此以外也有一些不错的库散落在Google Code.SourceForge等地方.由于Github社区太过主流,这里主要介绍一下Github里面流

iOS组件化方案(二)

概述 这是iOS组件化方案-总结的第二篇,在本文中我实现了Target-Action方案的Demo,并与第一篇介绍的protocol方案做出对比. 如果没有看过我第一篇protocol组件化方案的同学,可以先去下载我那篇文章中提供的Demo,方便理解我本文的详述以及了解我Demo中实现的业务场景,传送门iOS组件化方案-总结的第一篇 Target-Action方案 国际惯例先上Demo(下载主工程就好了哈,如果不能理解可以把所有业务模块都下载下来,Casa也提供了官方Demo,我第一篇文章中提供

iOS开发新框架ReactiveCocoa简介

ReactiveCocoa(其简称为RAC)是由Github 开源的一个应用于iOS和OS X开发的新框架.RAC具有函 数式编程和响应式编程的特性.它主要吸取了.Net的 Reactive Extensions的设计和实现.本文将详细 介绍该框架试图解决什么问题,以及其用法与特点. ReactiveCocoa试图解决什么问题 经过一段时间的研究,我认为ReactiveCocoa试图解决以下3个问题: 传统iOS开发过程中,状态以及状态之间依赖过多的问题 传统MVC架构的问题:Controlle

我的女神——简洁实用的iOS代码调试框架

我的女神--简洁实用的iOS代码调试框架 一.引言         这篇博客的起源是接手了公司的一个已经完成的项目,来做代码优化,项目工程很大,并且引入了很多公司内部的SDK,要搞清楚公司内部的这套框架,的确不是件容易的事,并且由于这个项目是多人开发的,在调试阶段会打印出巨量的调试信息,使得浏览有用信息变的十分困难,更加恐怖的是,很多信息是SDK中的调试打印,将这些都进行注销是非常费劲甚至不可能的事,于是便有了这样一些需求:首先,我需要清楚了解各个controller之间的跳转关系,需要快速的弄

Kiwi,BDD行为测试框架–iOS攻城狮进阶必备技能

Kiwi,BDD行为测试框架–iOS攻城狮进阶必备技能 http://www.ios122.com/ 简介 Kiwi 是一个适用于iOS开发的行为驱动测试框架,旨在提供一个足够简单易用的BDD库. 项目主页: https://github.com/kiwi-bdd/Kiwi 示例下载: https://github.com/ios122/ios122 使用Cocopods 安装 1 2 3 4 target :AmazingAppTests, :exclusive => true do   po

使用iOS原生sqlite3框架对sqlite数据库进行操作

使用iOS原生sqlite3框架对sqlite数据库进行操作 一.引言       sqlite数据库是一种小型数据库,由于其小巧与简洁,在移动开发领域应用深广,sqlite数据库有一套完备的sqlite语句进行管理操作,一些常用的语句和可视化的开发工具在上篇博客中有介绍,地址如下: sqlite数据库常用语句及可视化工具介绍:http://my.oschina.net/u/2340880/blog/600820.       在iOS的原生开发框架中可以对sqlite数据库进行很好的支持,这个