美文网首页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