iOS开发系列--扩展--播放音乐库中的音乐
众所周知音乐是iOS的重要组成播放,无论是iPod、iTouch、iPhone还是iPad都可以在iTunes购买音乐或添加本地音乐到音乐 库中同步到你的iOS设备。在MediaPlayer.frameowork中有一个MPMusicPlayerController用于播放音乐库中的 音乐。
下面先来看一下MPMusicPlayerController的常用属性和方法:
| 属性 | 说明 |
| @property (nonatomic, readonly) MPMusicPlaybackState playbackState | 播放器状态,枚举类型: MPMusicPlaybackStateStopped:停止播放 MPMusicPlaybackStatePlaying:正在播放 MPMusicPlaybackStatePaused:暂停播放 MPMusicPlaybackStateInterrupted:播放中断 MPMusicPlaybackStateSeekingForward:向前查找 MPMusicPlaybackStateSeekingBackward:向后查找 |
| @property (nonatomic) MPMusicRepeatMode repeatMode | 重复模式,枚举类型: MPMusicRepeatModeDefault:默认模式,使用用户的首选项(系统音乐程序设置) MPMusicRepeatModeNone:不重复 MPMusicRepeatModeOne:单曲循环 MPMusicRepeatModeAll:在当前列表内循环 |
| @property (nonatomic) MPMusicShuffleMode shuffleMode | 随机播放模式,枚举类型: MPMusicShuffleModeDefault:默认模式,使用用户首选项(系统音乐程序设置) MPMusicShuffleModeOff:不随机播放 MPMusicShuffleModeSongs:按歌曲随机播放 MPMusicShuffleModeAlbums:按专辑随机播放 |
| @property (nonatomic, copy) MPMediaItem *nowPlayingItem | 正在播放的音乐项 |
| @property (nonatomic, readonly) NSUInteger indexOfNowPlayingItem | 当前正在播放的音乐在播放队列中的索引 |
| @property(nonatomic, readonly) BOOL isPreparedToPlay | 是否准好播放准备 |
| @property(nonatomic) NSTimeInterval currentPlaybackTime | 当前已播放时间,单位:秒 |
| @property(nonatomic) float currentPlaybackRate | 当前播放速度,是一个播放速度倍率,0表示暂停播放,1代表正常速度 |
| 类方法 | 说明 |
| + (MPMusicPlayerController *)applicationMusicPlayer; | 获取应用播放器,注意此类播放器无法在后台播放 |
| + (MPMusicPlayerController *)systemMusicPlayer | 获取系统播放器,支持后台播放 |
| 对象方法 | 说明 |
| - (void)setQueueWithQuery:(MPMediaQuery *)query | 使用媒体队列设置播放源媒体队列 |
| - (void)setQueueWithItemCollection:(MPMediaItemCollection *)itemCollection | 使用媒体项集合设置播放源媒体队列 |
| - (void)skipToNextItem | 下一曲 |
| - (void)skipToBeginning | 从起始位置播放 |
| - (void)skipToPreviousItem | 上一曲 |
| - (void)beginGeneratingPlaybackNotifications | 开启播放通知,注意不同于其他播放器,MPMusicPlayerController要想获得通知必须首先开启,默认情况无法获得通知 |
| - (void)endGeneratingPlaybackNotifications | 关闭播放通知 |
| - (void)prepareToPlay | 做好播放准备(加载音频到缓冲区),在使用play方法播放时如果没有做好准备回自动调用该方法 |
| - (void)play | 开始播放 |
| - (void)pause | 暂停播放 |
| - (void)stop | 停止播放 |
| - (void)beginSeekingForward | 开始向前查找(快进) |
| - (void)beginSeekingBackward | 开始向后查找(快退) |
| - (void)endSeeking | 结束查找 |
| 通知 | 说明 (注意:要想获得MPMusicPlayerController通知必须首先调用beginGeneratingPlaybackNotifications开启通知) |
| MPMusicPlayerControllerPlaybackStateDidChangeNotification | 播放状态改变 |
| MPMusicPlayerControllerNowPlayingItemDidChangeNotification | 当前播放音频改变 |
| MPMusicPlayerControllerVolumeDidChangeNotification | 声音大小改变 |
| MPMediaPlaybackIsPreparedToPlayDidChangeNotification | 准备好播放 |
- MPMusicPlayerController有两种播放器:applicationMusicPlayer和systemMusicPlayer,前者在应用退出后音乐播放会自动停止,后者在应用停止后不会退出播放状态。
- MPMusicPlayerController加载音乐不同于前面的AVAudioPlayer是通过一个文件路径来加载,而是需要一个播放队列。在MPMusicPlayerController中提供了两个方法来加载播放队列:- (void)setQueueWithQuery:(MPMediaQuery *)query和- (void)setQueueWithItemCollection:(MPMediaItemCollection *)itemCollection,正是由于它的播放音频来源是一个队列,因此MPMusicPlayerController支持上一曲、下一曲等操作。
那么接下来的问题就是如何获取MPMediaQueue或者MPMediaItemCollection?MPMediaQueue对象有一系列的类方法来获得媒体队列:
+ (MPMediaQuery *)albumsQuery;
+ (MPMediaQuery *)artistsQuery;
+ (MPMediaQuery *)songsQuery;
+ (MPMediaQuery *)playlistsQuery;
+ (MPMediaQuery *)podcastsQuery;
+ (MPMediaQuery *)audiobooksQuery;
+ (MPMediaQuery *)compilationsQuery;
+ (MPMediaQuery *)composersQuery;
+ (MPMediaQuery *)genresQuery;
有了这些方法,就可以很容易获到歌曲、播放列表、专辑媒体等媒体队列了,这样就可以通过:- (void)setQueueWithQuery:(MPMediaQuery *)query方法设置音乐来源了。又或者得到MPMediaQueue之后创建MPMediaItemCollection,使用- (void)setQueueWithItemCollection:(MPMediaItemCollection *)itemCollection设置音乐来源。
有时候可能希望用户自己来选择要播放的音乐,这时可以使用MPMediaPickerController,它是一个视图控制器,类似于
UIImagePickerController,选择完播放来源后可以在其代理方法中获得MPMediaItemCollection对象。
无论是通过哪种方式获得MPMusicPlayerController的媒体源,可能都希望将每个媒体的信息显示出来,这时候可以通过
MPMediaItem对象获得。一个MPMediaItem代表一个媒体文件,通过它可以访问媒体标题、专辑名称、专辑封面、音乐时长等等。无论是
MPMediaQueue还是MPMediaItemCollection都有一个items属性,它是MPMediaItem数组,通过这个属性可以获
得MPMediaItem对象。
1 首先加入MediaPlayer.frameowork,#import <MediaPlayer/MediaPlayer.h>头文件添加,<MPMediaPickerControllerDelegate>协议
代码示例:
#import "DetailViewController.h"
#import <MediaPlayer/MediaPlayer.h>
@interface DetailViewController ()<MPMediaPickerControllerDelegate>
{
MPMediaPickerController *_mediaPicker; // 媒体选择控制器
MPMusicPlayerController *_musicPlayer; //音乐播放器
UIButton *_slectBtn;//选择
UIButton *_playBtn; //播放
UIButton *_pauseBtn;// 暂停
UIButton *_nextBtn; // 下一曲
UIButton *_previousBtn; // 上一曲
UIButton *_stopBtn;
}
@end
@implementation DetailViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.view.backgroundColor = [UIColor whiteColor];
[self setUpConfigs];
}
-(void)setUpConfigs{
_slectBtn = [UIButton buttonWithType:UIButtonTypeCustom];
_slectBtn.frame = CGRectMake(self.view.frame.size.width/3, 100, 50, 50);
_slectBtn.backgroundColor = [UIColor blueColor];
[_slectBtn addTarget:self action:@selector(selectClick:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:_slectBtn];
_playBtn = [UIButton buttonWithType:UIButtonTypeCustom];
_playBtn.frame = CGRectMake(self.view.frame.size.width/3, 150, 50, 50);
_playBtn.backgroundColor = [UIColor blackColor];
[_playBtn addTarget:self action:@selector(playClick:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:_playBtn];
_pauseBtn = [UIButton buttonWithType:UIButtonTypeCustom];
_pauseBtn.frame = CGRectMake(self.view.frame.size.width/3, 200, 50, 50);
_pauseBtn.backgroundColor = [UIColor redColor];
[_pauseBtn addTarget:self action:@selector(puaseClick:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:_pauseBtn];
_stopBtn = [UIButton buttonWithType:UIButtonTypeCustom];
_stopBtn.frame = CGRectMake(self.view.frame.size.width/3, 250, 50, 50);
_stopBtn.backgroundColor = [UIColor redColor];
[_stopBtn addTarget:self action:@selector(stopClick:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:_stopBtn];
_nextBtn = [UIButton buttonWithType:UIButtonTypeCustom];
_nextBtn.frame = CGRectMake(self.view.frame.size.width/3, 300, 50, 50);
_nextBtn.backgroundColor = [UIColor orangeColor];
[_nextBtn addTarget:self action:@selector(nextClick:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:_nextBtn];
_previousBtn = [UIButton buttonWithType:UIButtonTypeCustom];
_previousBtn.frame = CGRectMake(self.view.frame.size.width/3, 350, 50, 50);
_previousBtn.backgroundColor = [UIColor orangeColor];
[_previousBtn addTarget:self action:@selector(prevClick:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:_previousBtn];
[self musicPlayer];
[self mediaPicker];
[self getLocalMediaQuery];
[self getLocalMediaItemCollection];
}
-(void)dealloc{
[_musicPlayer endGeneratingPlaybackNotifications]; //销毁MPMusicPlayerController 的通知
}
/**
* 获得音乐播放器
*
* @return 音乐播放器
*/
-(MPMusicPlayerController *)musicPlayer{
if (!_musicPlayer) {
_musicPlayer = [MPMusicPlayerController systemMusicPlayer];
[_musicPlayer beginGeneratingPlaybackNotifications]; //开启通知,否则监控不到MPMusicPlayerController 的通知
[self addNotification];
//如果不使用MPMediaPickerController可以使用如下方法获得音乐库媒体队列
//[_musicPlayer setQueueWithItemCollection:[self getLocalMediaItemCollection]];
}
return _musicPlayer;
}
/**
* 创建媒体选择器
*
* @return 媒体选择器
*/
-(MPMediaPickerController *)mediaPicker{
if (!_mediaPicker) {
//初始化媒体选择器,这里设置媒体类型为音乐,其实这里也可以选择视频、广播等
_mediaPicker = [[MPMediaPickerController alloc]initWithMediaTypes:MPMediaTypeAny];
_mediaPicker.allowsPickingMultipleItems=YES;//允许多选
// _mediaPicker.showsCloudItems=YES;//显示icloud选项
_mediaPicker.prompt=@"请选择要播放的音乐";
_mediaPicker.delegate=self;//设置选择器代理
}
return _mediaPicker;
}
/**
* 取得媒体队列
*
* @return 媒体队列
*/
-(MPMediaQuery *)getLocalMediaQuery{
MPMediaQuery *mediaQueue=[MPMediaQuery songsQuery];
for (MPMediaItem *item in mediaQueue.items) {
NSLog(@"标题:%@,%@",item.title,item.albumTitle);
}
return mediaQueue;
}
/**
* 取得媒体集合
*
* @return 媒体集合
*/
-(MPMediaItemCollection *)getLocalMediaItemCollection{
MPMediaQuery *mediaQueue=[MPMediaQuery songsQuery];
NSMutableArray *array=[NSMutableArray array];
for (MPMediaItem *item in mediaQueue.items) {
[array addObject:item];
NSLog(@"标题:%@,%@",item.title,item.albumTitle);
}
MPMediaItemCollection *mediaItemCollection=[[MPMediaItemCollection alloc]initWithItems:[array copy]];
return mediaItemCollection;
}
#pragma mark - MPMediaPickerController代理方法
//选择完成
-(void)mediaPicker:(MPMediaPickerController *)mediaPicker didPickMediaItems:(MPMediaItemCollection *)mediaItemCollection{
MPMediaItem *mediaItem=[mediaItemCollection.items firstObject];//第一个播放音乐
//注意很多音乐信息如标题、专辑、表演者、封面、时长等信息都可以通过MPMediaItem的valueForKey:方法得到,但是从iOS7开始都有对应的属性可以直接访问
// NSString *title= [mediaItem valueForKey:MPMediaItemPropertyAlbumTitle];
// NSString *artist= [mediaItem valueForKey:MPMediaItemPropertyAlbumArtist];
// MPMediaItemArtwork *artwork= [mediaItem valueForKey:MPMediaItemPropertyArtwork];
//UIImage *image=[artwork imageWithSize:CGSizeMake(100, 100)];//专辑图片
NSLog(@"标题:%@,表演者:%@,专辑:%@",mediaItem.title ,mediaItem.artist,mediaItem.albumTitle);
[self.musicPlayer setQueueWithItemCollection:mediaItemCollection];
[self dismissViewControllerAnimated:YES completion:nil];
}
//取消选择
-(void)mediaPickerDidCancel:(MPMediaPickerController *)mediaPicker{
[self dismissViewControllerAnimated:YES completion:nil];
}
#pragma mark - 通知
/**
* 添加通知
*/
-(void)addNotification{
NSNotificationCenter *notificationCenter=[NSNotificationCenter defaultCenter];
[notificationCenter addObserver:self selector:@selector(playbackStateChange:) name:MPMusicPlayerControllerPlaybackStateDidChangeNotification object:_musicPlayer];
}
/**
* 播放状态改变通知
*
* @param notification 通知对象
*/
-(void)playbackStateChange:(NSNotification *)notification{
switch (_musicPlayer.playbackState) {
case MPMusicPlaybackStatePlaying:
NSLog(@"正在播放...");
break;
case MPMusicPlaybackStatePaused:
NSLog(@"播放暂停.");
break;
case MPMusicPlaybackStateStopped:
NSLog(@"播放停止.");
break;
default:
break;
}
}
#pragma mark - UI事件
- (void)selectClick:(UIButton *)sender {
[self presentViewController:_mediaPicker animated:YES completion:nil];
}
- (void)playClick:(UIButton *)sender {
[_musicPlayer play];
}
- (void)puaseClick:(UIButton *)sender {
[_musicPlayer pause];
}
- (void)stopClick:(UIButton *)sender {
[_musicPlayer stop];
}
- (void)nextClick:(UIButton *)sender {
[_musicPlayer skipToNextItem];
}
- (void)prevClick:(UIButton *)sender {
[_musicPlayer skipToPreviousItem];
}
iOS开发系列--扩展--播放音乐库中的音乐的更多相关文章
- iOS开发系列--音频播放、录音、视频播放、拍照、视频录制
--iOS多媒体 概览 随着移动互联网的发展,如今的手机早已不是打电话.发短信那么简单了,播放音乐.视频.录音.拍照等都是很常用的功能.在iOS中对于多媒体的支持是非常强大的,无论是音视频播放.录制, ...
- iOS开发系列--音频播放、录音、
音频 在iOS中音频播放从形式上可以分为音效播放和音乐播放.前者主要指的是一些短音频播放,通常作为点缀音频,对于这类音频不需要进行进度.循环等控制.后者指的是一些较长的音频,通常是主音频,对于这些音频 ...
- iOS开发系列--音频播放(音效和音乐)播放本地的
音频 在iOS中音频播放从形式上可以分为音效播放和音乐播放.前者主要指的是一些短音频播放,通常作为 点缀音频,对于这类音频不需要进行进度.循环等控制.后者指的是一些较长的音频,通常是主音频,对于这些音 ...
- iOS开发系列--网络开发
概览 大部分应用程序都或多或少会牵扯到网络开发,例如说新浪微博.微信等,这些应用本身可能采用iOS开发,但是所有的数据支撑都是基于后台网络服务器的.如今,网络编程越来越普遍,孤立的应用通常是没有生命力 ...
- iOS开发系列文章(持续更新……)
iOS开发系列的文章,内容循序渐进,包含C语言.ObjC.iOS开发以及日后要写的游戏开发和Swift编程几部分内容.文章会持续更新,希望大家多多关注,如果文章对你有帮助请点赞支持,多谢! 为了方便大 ...
- ios学习:AVAudioPlayer播放音乐文件及读取ipod库中的音乐文件
首先要导入AVFoundation框架及 #import <AVFoundation/AVFoundation.h>头文件 注意:要在真机上调试 下面是ipad上的调试效果 下面是代码,代 ...
- iOS开发系列--App扩展开发
概述 从iOS 8 开始Apple引入了扩展(Extension)用于增强系统应用服务和应用之间的交互.它的出现让自定义键盘.系统分享集成等这些依靠系统服务的开发变成了可能.WWDC 2016上众多更 ...
- iOS:iOS开发非常全的三方库、插件等等
iOS开发非常全的三方库.插件等等 github排名:https://github.com/trending, github搜索:https://github.com/search. 此文章转自git ...
- iOS开发系列--Swift进阶
概述 上一篇文章<iOS开发系列--Swift语言>中对Swift的语法特点以及它和C.ObjC等其他语言的用法区别进行了介绍.当然,这只是Swift的入门基础,但是仅仅了解这些对于使用S ...
随机推荐
- android intent 5.1
1.intent 6 items action, data(uri &type),Component name,Extras,flags 2.data---uri & type 不管使 ...
- Windows环境下JDK安装与环境变量配置详细的图文教程
原文作者:souvc博文出处:http://www.cnblogs.com/liuhongfeng/p/4177568.html 本节内容:JDK安装与环境变量配置 以下是详细步骤 一.准备工具: 1 ...
- [转]Oracle分页之三:利用PagerView来实现无刷新GridView
本文转自:http://www.cnblogs.com/scy251147/archive/2011/04/16/2018355.html 接上面一节,上面还存在问题就是分页控件使用的仍然是服务器端控 ...
- 边工作边刷题:70天一遍leetcode: day 81
Encode and Decode Strings 要点:题的特点:不是压缩,而是encode为字节流.所以需要找delimiter来分割每个word,但是delimiter可能是字符本身,所以可以用 ...
- Python天猫淘宝评论爬虫
说明 由于Github 打包的exe某些文件上传被.gitignore了,所以不提供windows二进制包 https://github.com/hunterhug/taobaocomment 一个抓 ...
- HDU 4819 Mosaic --二维线段树(树套树)
题意: 给一个矩阵,每次查询一个子矩阵内的最大最小值,然后更新子矩阵中心点为(Max+Min)/2. 解法: 由于是矩阵,且要求区间最大最小和更新单点,很容易想到二维的线段树,可是因为之前没写过二维的 ...
- UVALive 6255 Kingdoms --状态搜索
题意:n个国家,给出国家间相互的债务关系,每个国家如果债务>收入就要破产,破产后该国的所有债务关系全部清除,第一个破产的国家不同有可能造成最后的没破产的国家的不同,问哪些国家有可能成为独自存活的 ...
- UVA 11766 Racing Car Computer --DP
题意:电脑记录了某一时刻每个赛车的前面和后面个有多少辆车(多个车并排时在别的车那只算一辆),问最少有多少个不合理的数据. 分析:看到n<=1000时,就尽量往DP上想吧. 每输入一组数据a,b, ...
- 线性代数与MATLAB2
已知矩阵 求它们的特征值和特征向量,并绘制特征向量图,分析其几何意义 运行Meigvector.m A1=[-1 3;2 5]; A2=[1 -2;-1 5]; A3=[1 2;2 4]; A4=[2 ...
- 保存带有emoji的文本报错解决方案
今天偶然遇到一个错误,就是保存文本的时候带有了emoji表情,报错了 java.sql.SQLException: Incorrect string value: '\xF0\x9F\x98\x8A\ ...