iOS开发中适合新手学习的音乐播放器(带DLNA功能)

一、需求

了解音乐播放器相关知识,熟悉相关逻辑,完成上一首,下一首,播放/暂停等基本功能。本文按照以上需求完成了一个小型的音乐播放器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下。
全文完。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,686评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,668评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,160评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,736评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,847评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,043评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,129评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,872评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,318评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,645评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,777评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,470评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,126评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,861评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,095评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,589评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,687评论 2 351

推荐阅读更多精彩内容