美文网首页iOS开发牛叉的demo
iOS开发中适合新手学习的音乐播放器(带DLNA功能)

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

作者: 百里玄卿 | 来源:发表于2016-10-27 09:57 被阅读365次

一、需求

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

相关文章

网友评论

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

    本文链接:https://www.haomeiwen.com/subject/cjzduttx.html