一、需求
了解音樂播放器相關知識,熟悉相關邏輯,完成上一首,下一首,播放/暫停等基本功能。本文按照以上需求完成了一個小型的音樂播放器Demo,適合新手學習,大神可以繞道。
二、開發
1.開發第一步
這一步,我們先需要知道,完成一個音樂播放器要做哪些準備。
1.1 首先,我們要播放音樂,要一個播放的類,這個類是整個工程都只有一個,所以我們要設計成單例類。
1.2 其次,我們需要解決音樂源的問題,包括本地音樂與網絡音樂。怎么解決,請自己想辦法。
</br>
2.開發第二步
2.1 本地音樂
本文中的本地音樂是基于plist文件來實現的,通過讀取plist文件中的數據獲取,然后轉換成模型。
plist.png
-(NSMutableArray *)dataArray
{
if (!_dataArray) {
_dataArray = [[NSMutableArray alloc] initWithArray:[ZM_MusicModel mj_objectArrayWithFile:PlistPath]];
}
return _dataArray;
}
現在獲取到數據源了,tableview顯示就OK了。
本地列表
點擊cell進入播放頁面。
播放頁面
這是本地音樂的界面,搭建完成了。
2.2 網絡音樂
網絡音樂肯定就是從網上請求數據了,本文用的第三方庫有AFNetWorking(數據請求)、MJExtension(模型轉換)、MJRefresh(網絡數據刷新)和SDWebImage(網絡圖片加載)。
分類列表
網絡音樂列表.png
現在數據源有了,同樣是點擊cell跳轉到播放頁。現在可以去設計音樂播放器管理單例類了。
開發第三步
現在要設計單例類,單例類要做的事情有,播放/暫停音樂,上一首,下一首。暫時設計這三個主要功能,如果有其它的需求,自行添加。
3.1 單例類初始化
//初始化單例類
+(ZM_MusicManager *)shareMusicManager
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
instance = [[self alloc] init];
});
return instance;
}
-(instancetype)init
{
self = [super init];
if (self) {
session = [AVAudioSession sharedInstance];
//激活會話對象
[session setActive:YES error:nil];
//設置后臺播放
[session setCategory:AVAudioSessionCategoryPlayback error:nil];
_playList = [[NSMutableArray alloc] init];
}
return self;
}
3.2 播放與暫停
/**
播放音樂
@param playURL 音樂源地址
@param index 播放列表下標
*/
-(void)playMusicWithURL:(NSURL *)playURL andIndex:(NSInteger)index
{
NSError * error;
NSData * data = [NSData dataWithContentsOfURL:playURL];
//此處建議使用initWithData方法,不建議下面的initWithContentsOfURL方法
self.audioPlayer = [[AVAudioPlayer alloc] initWithData:data error:&error];
//self.audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error];
if(error){
NSLog(@"data初始化方式出現錯誤,錯誤詳情:%@,進入URL初始化!",error);
self.audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:playURL error:nil];
}
self.audioPlayer.delegate = self;
if ([self.audioPlayer prepareToPlay]) {
[self.audioPlayer play];
}
}
/**
暫停播放
*/
-(void)pausePlayMusic
{
if ([self.audioPlayer isPlaying]) {
[self.audioPlayer pause];
}else{
[self.audioPlayer play];
}
}
3.3 上一首
其實上一首與下一首的思路很簡單,前面我們獲取到了音樂源,這是一個數組,這就是一個播放列表,然后數組是有下標的,我們通過下標遍歷數組就可以了。
/**
上一首
*/
-(void)previousMusic
{
_index --;
NSURL * nextURL;
if (_index < 0) {
_index = self.playList.count - 1;
}
NSString * string = [NSString stringWithFormat:@"%@",[self.playList[_index] url]];
NSArray * array = [string componentsSeparatedByString:@":"];
if ([array[0] isEqualToString:@"http"]) {
//網絡音樂
nextURL = [NSURL URLWithString:[NSString stringWithFormat:@"%@&ua=Iphone_Sst&version=4.239&netType=1&toneFlag=1",[self.playList[_index] url]]];
}else{
nextURL = [[NSBundle mainBundle] URLForResource:[NSString stringWithFormat:@"%@",[_playList[_index] url]] withExtension:nil];
}
[self playMusicWithURL:nextURL andIndex:_index];
}
3.4 下一首
/**
下一首
*/
-(void)nextMusic
{
_index ++;
NSURL * nextURL;
if (_index > self.playList.count - 1) {
_index = 0;
}
NSString * string = [NSString stringWithFormat:@"%@",[self.playList[_index] url]];
NSArray * array = [string componentsSeparatedByString:@":"];
if ([array[0] isEqualToString:@"http"]) {
//網絡音樂
nextURL = [NSURL URLWithString:[NSString stringWithFormat:@"%@&ua=Iphone_Sst&version=4.239&netType=1&toneFlag=1",[self.playList[_index] url]]];
}else{
nextURL = [[NSBundle mainBundle] URLForResource:[NSString stringWithFormat:@"%@",[_playList[_index] url]] withExtension:nil];
}
[self playMusicWithURL:nextURL andIndex:_index];
}
3.5 播放完一首歌后自動切換下一首歌
AVAudioPlayer有一個代理方法,可以在這個里面直接切換下一首。我們這里采用的是發通知告訴控制器,更改相應界面參數。
#pragma mark -AVAudioPlayerDelegate
-(void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag
{
//發送通知,告訴控制器音樂播放完了,切換下一首播放,也可以直接在這里播放下一首
NSNotification * notification = [NSNotification notificationWithName:@"PLAYEND" object:nil];
[[NSNotificationCenter defaultCenter] postNotification:notification];
}
//接收通知,該通知由ZM_MusicManager發送,當前歌曲播放完畢,進行下一首播放
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(nextBtnHandle:) name:@"PLAYEND" object:nil];
3.6 后臺播放
音樂播放器肯定是要后臺能夠播放最好,需要做下面的設置。
3.6.1 plist文件設置
plist設置.png
此處注意,方框里的設置為固定設置,不要改動。
3.6.2 添加代碼
見3.1節代碼
然后我們的音樂播放器基本上就設計完了,附上Demo地址:ZM_MusicPlayer
DEMO完成了DLNA功能的設計,在common/model/upnp core下。
全文完。