AVAudioPlayer简单的本地音乐播放器

作者: SongLazy | 来源:发表于2016-07-19 02:51 被阅读716次

    这只是一个非常简单的音乐播放器的小demo,实现一些小功能. 大神自动略过.

    功能概览

    1.播放/暂停/停止

    2.上一曲/下一曲/点击列表中的歌曲名称播放对应歌曲

    3.显示播放列表/显示正在播放的歌曲名称

    4.循环播放/随机播放

    5.音量/进度条/可拖动进度条控制播放进度/进度时间显示

    6.白天模式/夜间模式

    界面效果

    界面.png 夜间.png 播放中.png

    功能介绍

    1.播放/暂停/停止:

    当点击播放按钮,按钮变为选中状态,文字为"暂停播放",再次点击会暂停. 当点击下一曲/上一曲或者选择歌曲列表中的歌名的时候,会自动播放,播放按钮状态变为选中状态.当点击停止按钮,歌曲进度变为00:00.

    2.上一曲/下一曲/点击列表中的歌曲名称播放对应歌曲:

    点击上一曲/下一曲会播放列表中对应的上一曲/下一曲,歌名会对应显示,点击列表中的歌曲名称播放对应歌曲.

    3.显示播放列表/显示正在播放的歌曲名称

    4.循环播放/随机播放:

    当选择循环播放,歌曲播放完毕会自动播放列表中对应的下一曲,点击上一曲/下一曲会播放列表中对应的上一曲/下一曲;当选择随机播放,歌曲播放完毕之后或者点击上一曲/下一曲会随机播放列表中的一首歌曲.

    5.音量/进度条/可拖动进度条控制播放进度/进度时间显示

    6.白天模式/夜间模式


    源代码

    storyboard - 随便拖的,没做自动布局 模拟器6s


    storyboard.png
    #import "ViewController.h"
    #import <AVFoundation/AVFoundation.h>
    
    @interface ViewController ()<AVAudioPlayerDelegate,UITableViewDelegate,UITableViewDataSource,AVAudioPlayerDelegate>
    
    //播放器
    @property (nonatomic, strong) AVAudioPlayer *player;
    //表示进度的slider
    @property (weak, nonatomic) IBOutlet UISlider *progressSlider;
    //计时器
    @property (nonatomic, strong) NSTimer *timer;
    //显示时间进度的label
    @property (weak, nonatomic) IBOutlet UILabel *progressLabel;
    //音乐名称
    @property (weak, nonatomic) IBOutlet UILabel *musicNameLabel;
    //存储音乐url的数组
    @property (nonatomic, strong) NSArray *musicArray;
    //音乐的下标
    @property (nonatomic, assign) NSInteger index;
    //音乐列表的tableView
    @property (nonatomic, strong) UITableView *tableView;
    //开始按钮
    @property (weak, nonatomic) IBOutlet UIButton *startButton;
    //循环模式的segControl
    @property (weak, nonatomic) IBOutlet UISegmentedControl *repeatModelSegControl;
    //夜间模式的segControl
    @property (weak, nonatomic) IBOutlet UISegmentedControl *tintModelControl;
    
    @end
    
    
    
    @implementation ViewController
    
    //懒加载音乐url数组
    - (NSArray *)musicArray {
        if (_musicArray == nil) {
    //        _musicArray = [NSArray array];
            NSURL *url0 = [[NSBundle mainBundle] URLForResource:@"好妹妹乐队-你曾是少年.mp3" withExtension:nil];
            NSURL *url1 = [[NSBundle mainBundle] URLForResource:@"陈小春 - 扑火.mp3" withExtension:nil];
            NSURL *url2 = [[NSBundle mainBundle] URLForResource:@"赵雷-画.mp3" withExtension:nil];
            NSURL *url3 = [[NSBundle mainBundle] URLForResource:@"赵雷-家乡.mp3" withExtension:nil];
            NSURL *url4 = [[NSBundle mainBundle] URLForResource:@"林峯 - 爱在记忆中找你.mp3" withExtension:nil];
            NSURL *url5 = [[NSBundle mainBundle] URLForResource:@"宁夏 - 午餐.mp3" withExtension:nil];
            NSURL *url6 = [[NSBundle mainBundle] URLForResource:@"张敬轩-愿望树上.mp3" withExtension:nil];
            _musicArray = @[url0,url1,url2,url3,url4,url5,url6];
        }
        return _musicArray;
    }
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        
        self.index = 0;
        
        //创建音乐列表的tableView
        UITableView *tableView = [[UITableView alloc] initWithFrame:CGRectMake(20, 350, 340, 250) style:UITableViewStylePlain];
        
        self.tableView = tableView;
        //设置代理和数据源
        self.tableView.delegate = self;
        self.tableView.dataSource = self;
        //添加
        [self.view addSubview:tableView];
        
        [self loadMusic];
        
        //设置子控件们的tintColor
        NSArray *array = [self.view subviews];
        [array enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
            [obj setTintColor:[UIColor grayColor]];
        }];
        
    }
    
    - (void)loadMusic {
        //创建一个错误对象,用来接收错误信息
        NSError *error;
        //创建播放器对象 传入本地url
        self.player = [[AVAudioPlayer alloc] initWithContentsOfURL:self.musicArray[self.index] error:&error];
        //设置代理
        self.player.delegate = self;
        //打印错误信息
        if (error) {
            NSLog(@"%@",error);
        }
        //创建一个计时器,用于记录播放进度--在计时器方法里把currentTime赋值给slider的value
        self.timer = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(sliderDisplay) userInfo:nil repeats:YES];
        //设置slider的最大值
        self.progressSlider.maximumValue = self.player.duration;
        //音乐名称
        NSURL *url = self.self.musicArray[self.index];
        self.musicNameLabel.text = url.lastPathComponent;
    
        
    }
    
    //控制音量的slider
    - (IBAction)volumeSlider:(UISlider *)sender {
        self.player.volume = sender.value;
    }
    //开始播放按钮
    - (IBAction)startClick:(UIButton *)sender {
        
        
        
        if (!sender.selected) {
            //如果player是空的 就读取音乐 否则就是已经在播放 再次点击的时候不能重新读取音乐
            if (self.player == nil) {
                [self loadMusic];
            }
            //准备播放, 可不写 为了规范要写.
            [self.player prepareToPlay];
            //播放
            [self.player play];
            sender.selected = YES;
        } else {
            [self.player pause];
            sender.selected = NO;
        }
       
    }
    //暂停  暂停按钮已删除  合并到播放按钮
    //- (IBAction)pauseClick:(id)sender {
    //    [self.player pause];
    //}
    //停止
    - (IBAction)stopClick:(id)sender {
        [self.player pause];
        self.player.currentTime = 0;
        self.startButton.selected = NO;
    }
    /** 计时器调用的显示slider的方法 */
    - (void)sliderDisplay {
        //赋值
        self.progressSlider.value = self.player.currentTime;
        //转换时间格式
        NSString *curren = [self timeFormatted:self.player.currentTime];
        NSString *all = [self timeFormatted:self.player.duration];
        //把时间拼接赋值给显示时间的label
        self.progressLabel.text = [NSString stringWithFormat:@"%@/%@",curren,all];
    }
    /** 拖动进度条 */
    - (IBAction)slideProgress:(UISlider *)sender {
        //将当前的播放时间设置为slider的value
        self.player.currentTime = sender.value;
    }
    /** 将秒数转换为分秒格式的时间字符串 */
    - (NSString *)timeFormatted:(int)totalSeconds
    {
        //将秒数转换为时间
        NSDate  *date = [NSDate dateWithTimeIntervalSince1970:totalSeconds];
        NSTimeZone *zone = [NSTimeZone systemTimeZone];
        NSInteger interval = [zone secondsFromGMTForDate: date];
        NSDate *localeDate = [date  dateByAddingTimeInterval: interval];
        //设置时间格式
        NSDateFormatter *dateformmatter = [[NSDateFormatter alloc] init];
        dateformmatter.dateFormat = @"mm:ss";
        NSString *time = [dateformmatter stringFromDate:localeDate];
        
        return time;
    }
    //上一曲
    - (IBAction)lastMusicClick:(id)sender {
        
        self.startButton.selected = YES;
        
        if (self.repeatModelSegControl.selectedSegmentIndex == 0) { //顺序播放
            if (self.index <= 0) {
                self.index = self.musicArray.count - 1;
            } else {
                self.index--;
            }
        } else { //随机播放
            NSInteger index = arc4random() % self.musicArray.count;
            self.index = index;
        }
        [self loadMusic];
        [self.player play];
    }
    //下一曲
    - (IBAction)nextMusicClick:(id)sender {
    
        self.startButton.selected = YES;
        
        if (self.repeatModelSegControl.selectedSegmentIndex == 0) { //顺序播放
            if (self.index >= self.musicArray.count - 1) {
                self.index = 0;
            } else {
                self.index++;
            }
        } else { //随机播放
            NSInteger index = arc4random() % self.musicArray.count;
            self.index = index;
        }
        [self loadMusic];
        [self.player play];
    }
    #pragma mark - 播放结束调用的方法
    - (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag {
        
        if (self.repeatModelSegControl.selectedSegmentIndex == 0) { //顺序播放
            [self nextMusicClick:nil];
        } else { //随机播放
            NSInteger index = arc4random() % self.musicArray.count;
            self.index = index;
            [self loadMusic];
            [self.player play];
        }
        
        
        // 音频播放完成时,调用该方法。
        // 参数flag:如果音频播放无法解码时,该参数为NO。
        //当音频被终端时,该方法不被调用。而会调用audioPlayerBeginInterruption方法
        // 和audioPlayerEndInterruption方法
        
    }
    
    //数据源
    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
        return self.musicArray.count;
    }
    
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
        UITableViewCell *cell = [[UITableViewCell alloc] init];
        NSURL *url = self.musicArray[indexPath.row];
        cell.textLabel.text = url.lastPathComponent;
        cell.textColor = [UIColor grayColor];
        if (self.tintModelControl.selectedSegmentIndex == 0) { //白天模式的颜色
            cell.contentView.backgroundColor = [UIColor whiteColor];
        } else { //夜间模式的颜色
            cell.contentView.backgroundColor = [UIColor darkGrayColor];
        }
        
        return cell;
    }
    //选中cell
    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
        self.startButton.selected = YES;
        self.index = indexPath.row;
        //读取音乐 播放音乐
        [self loadMusic];
        [self.player play];
    }
    //夜间模式选择按钮
    - (IBAction)tintModelClick:(UISegmentedControl *)sender {
        if (sender.selectedSegmentIndex == 0) { //白天模式
            self.view.backgroundColor = [UIColor whiteColor];
            //在cell方法里设置了cell的相关颜色,所以需要重新加载数据
            [self.tableView reloadData];
        } else { //夜间模式
            self.view.backgroundColor = [UIColor darkGrayColor];
            [self.tableView reloadData];
        }
    }
    
    @end
    
    

    相关文章

      网友评论

      • eb7040b8e817:不错
        SongLazy:@_XZ 都是简单的东西。。谢谢哈
      • f6d14557eec6:这些代码怎么用
        SongLazy:@fafalalaLi 整个拷贝到viewController里就行了 再拖几个音乐到项目里,加载音乐的时候把名字改成你自己拖的
      • MdWhat:叼....媳妇跟上!!! :unamused:
        SongLazy:@某人超过 :heart_eyes:有你就够了

      本文标题:AVAudioPlayer简单的本地音乐播放器

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