本地音乐播放器的使用

音乐播放器的简单使用:
<1>AVAudioPlayer使用简单方便,但只能播放本地音频,不支持网络连接的播放.
<2>AVPlayer可以播放本地音频也支持网络播放以及视屏播放,但是提供接口较少,处理音频不够灵活.
使用它们都需要导入系统的AVFoundation框架
今天介绍一下AVAudioPlayer的使用

它的使用非常简单直接获取本地音乐路径
NSString *path = [[NSBundle mainBundle] pathForResource:@"本地音乐的名字" ofType:@"后缀"];
NSURL *url = [NSURL fileURLWithPath:path];
AVAudioPlayer *player = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil];
[player play];
这样就可以播放了

但是如果添加上暂停 上一曲 下一曲 歌词 功能 就不能这么简单了由于代码有点多直接上代码了 每一次播放都会创建新的player, 再把上一次的清掉, 并且, 承载音乐播放的VC也不能多次创建

先创建一个Model对象存放本地音乐的数据
Model.h

#import 
@interface ModelOfMusic : NSObject
@property (nonatomic, copy) NSString *filename;
@property (nonatomic, copy) NSString *icon;
@property (nonatomic, copy) NSString *name;
@property (nonatomic, copy) NSString *singer;
@property (nonatomic, copy) NSString *singerIcon;
@property (nonatomic, copy) NSString *lrcname;
- (instancetype)initWithDic:(NSDictionary *)dic;
+ (ModelOfMusic *)modelWithDic:(NSDictionary *)dic;
@end

Model.m

#import "ModelOfMusic.h"
@implementation ModelOfMusic
- (instancetype)initWithDic:(NSDictionary *)dic {

    self = [super init];
    if (self) {
        
        [self setValuesForKeysWithDictionary:dic];
    }
    return self;
}
+ (ModelOfMusic *)modelWithDic:(NSDictionary *)dic {

    return [[self alloc] initWithDic:dic];
}
- (void)setValue:(id)value forUndefinedKey:(NSString *)key {   
}
- (id)valueForUndefinedKey:(NSString *)key {

    return nil;
}
@end

还要创建管理音乐数据的类

#import 
@class ModelOfMusic;
@interface WHMusicTool : NSObject
/** 返回所有的歌曲 */
+ (NSArray *)arrayOfMusics;
/** 返回正在播放的歌曲 */
+ (ModelOfMusic *)playingMusic;
+ (void)setPlayingMusic:(ModelOfMusic *)playingMusic;
/** 下一首歌曲 */
+ (ModelOfMusic *)nextMusic;
/** 上一首歌曲 */
+ (ModelOfMusic *)lastMusic;
@end
#import "WHMusicTool.h"
#import "ModelOfMusic.h"
static NSArray *_arrayOfMusics;
static ModelOfMusic *_playingMusic;

@implementation WHMusicTool

#pragma mark ------------  返回所有的歌曲  -----------
+ (NSArray *)arrayOfMusics {

    if (_arrayOfMusics.count == 0) {
        NSMutableArray *mArr = [NSMutableArray array];
        
        NSString *path = [[NSBundle mainBundle] pathForResource:@"Musics" ofType:@"plist"];
        NSArray *array = [NSArray arrayWithContentsOfFile:path];
        for (NSDictionary *dic in array) {
            
            ModelOfMusic *model = [ModelOfMusic modelWithDic:dic];
            [mArr addObject:model];
        }
        _arrayOfMusics = mArr;
    }
    return _arrayOfMusics;
}
+ (void)setPlayingMusic:(ModelOfMusic *)playingMusic {

    /** 
     * 如果没有传入需要播放的歌曲, 或者是传入歌曲名不在音乐库中, 那么就直接返回
     * 如果需要播放的歌曲就是当前正在播放的歌曲, 那么就直接返回
     */
    if (!playingMusic || ![[self arrayOfMusics] containsObject:playingMusic]) {
        
        return;
    }
    if (_playingMusic == playingMusic) {
        
        return;
    }
    _playingMusic = playingMusic;
}
#pragma mark ------------  返回正在播放的歌曲  -----------
+ (ModelOfMusic *)playingMusic {

    return _playingMusic;
}
#pragma mark ------------  下一曲  -----------
+ (ModelOfMusic *)nextMusic {

    // 设定一个初值
    NSInteger nextIndex = 0;
    if (_playingMusic) {
        
        // 获取当前播放音乐的索引
        NSInteger playingIndex = [[self arrayOfMusics] indexOfObject:_playingMusic];
        // 设置下一首音乐的索引
        nextIndex = playingIndex + 1;
        if (nextIndex >= [self arrayOfMusics].count) {
            nextIndex = 0;
        }
    }
    return [self arrayOfMusics][nextIndex];
}
#pragma mark ------------  上一曲  -----------
+ (ModelOfMusic *)lastMusic {

    // 设定一个初值
    NSInteger lastIndex = 0;
    if (_playingMusic) {
        
        // 获取当前播放音乐的索引
        NSInteger playingIndex = [[self arrayOfMusics] indexOfObject:_playingMusic];
        // 设置下一曲的索引
        lastIndex = playingIndex - 1;
        if (lastIndex < 0) {
            
            lastIndex = [self arrayOfMusics].count - 1;
        }
    }
    return [self arrayOfMusics][lastIndex];
}
@end

管理音乐播放器的类

#import 
@class AVAudioPlayer;
@interface WHAudioTool : NSObject
/** 播放音乐文件 */
+ (AVAudioPlayer *)playMusic:(NSString *)fileName;
/** 暂停播放 */
+ (void)pauseMusic:(NSString *)fileName;
/** 播放音乐 */
+ (void)stopMusic:(NSString *)fileName;
/** 播放音效文件 */
+ (void)playSound:(NSString *)fileName;
/** 销毁音效 */
+ (void)disposeSound:(NSString *)fileName;
@end
#import "WHAudioTool.h"
#import 
@implementation WHAudioTool
static NSMutableDictionary *_musicPlayers;
static NSMutableDictionary *_soundIDs;
#pragma mark ------------  存放所有的音乐播放器  -----------
+ (NSMutableDictionary *)musicPalyers {

    if (_musicPlayers == nil) {
        
        _musicPlayers = [NSMutableDictionary dictionary];
    }
    return _musicPlayers;
}
#pragma mark ------------  存放所有的音效ID  -----------
+ (NSMutableDictionary *)soundIDs {

    if (_soundIDs == nil) {
        
        _soundIDs = [NSMutableDictionary dictionary];
    }
    return _soundIDs;
}
#pragma mark ------------  播放音乐  -----------
+ (AVAudioPlayer *)playMusic:(NSString *)fileName {

    // 如果没有传入文件名, 直接返回
    if (!fileName) {
        
        return nil;
    }
    // 1.取出对应的播放器
    AVAudioPlayer *player = [[self musicPalyers] objectForKey:fileName];
    // 2.如果没有播放器, 就进行初始化
    if (!player) {
        
        // 2.1 音频文件的URL
        NSURL *url = [[NSBundle mainBundle] URLForResource:fileName withExtension:nil];
        //      如果url为空, 直接返回
        if (!url) {
            return nil;
        }
        // 2.2创建播放器
        player = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil];
        // 2.3 缓冲
        //      如果缓冲失败 直接返回
        if (![player prepareToPlay]) {
            
            return nil;
        }
        // 2.4存入字典
//        [self musicPalyers][fileName] = player;
        [[self musicPalyers] setObject:player forKey:fileName];
    }
    // 3.播放
    if (![player isPlaying]) {
        
        // 如果当前没处于播放状态, 那么就播放
        [player play];
        return player;
    }
    
    // 正在播放, 那么就返回YES
    return player;
}
#pragma mark ------------  暂停  -----------
+ (void)pauseMusic:(NSString *)fileName {

    // 如果没有传入文件名, 那么就直接返回
    if (!fileName) {
        
        return;
    }    
    // 1. 取出对应的播放器
    AVAudioPlayer *player = [[self musicPalyers] objectForKey:fileName];
    
    // 2. 暂停(如果player为空, 那相当于[nil pause]不用做处理)
    [player pause];
}
#pragma mark ------------  stop  -----------
+ (void)stopMusic:(NSString *)fileName {

    // 如果没有传入文件名, 直接返回
    if (!fileName) {
        
        return;
    }
    // 1. 取出对应的播放器
    AVAudioPlayer *player = [[self musicPalyers] objectForKey:fileName];
    // 2.停止
    [player stop];
    // 3.将播放器从字典中移除
    [[self musicPalyers] removeObjectForKey:fileName];   
}
#pragma mark ------------  播放音效  -----------
+ (void)playSound:(NSString *)fileName {

    if (!fileName) {
        
        return;
    }
    // 1. 取出对应的音效
    SystemSoundID soundID = (SystemSoundID)[[self soundIDs] objectForKey:fileName];
    
    // 2. 播放音效
    // 2.1 如果音效ID不存在, 那么就创建
    if (!soundID) {
        
        // 音效文件的URL
        NSURL *url = [[NSBundle mainBundle] URLForResource:fileName withExtension:nil];
        //      如果url不存在, 直接返回
        if (!url) {
            
            return;
        }
        OSStatus status = AudioServicesCreateSystemSoundID((__bridge CFURLRef)(url), &soundID);
        [[self soundIDs] setObject:@(soundID) forKey:fileName];
    }
    // 2.2 有音效ID后, 播放音效
    AudioServicesPlaySystemSound(soundID);
}
#pragma mark ------------  销毁音效  -----------
+ (void)disposeSound:(NSString *)fileName {

    // 如果传入的文件名为空, 直接返回
    if (!fileName) {
        return;
    }
    // 1. 取出对应的音效
    SystemSoundID soundID = (SystemSoundID)[[self soundIDs] objectForKey:fileName];
    // 2. 销毁
    if (soundID) {
        AudioServicesDisposeSystemSoundID(soundID);   
        // 2.1 销毁后, 从字典中移除
        [[self soundIDs] removeObjectForKey:fileName];
    }   
}
@end

解析歌词的类

#import 
@interface LrcParser : NSObject
@property (nonatomic, retain) NSMutableArray *timerArray;
@property (nonatomic, retain) NSMutableArray *wordArray;
-(void)parserLrc:(NSString *)name type:(NSString *)type;
@end
#import "LrcParser.h"
@implementation LrcParser
- (instancetype)init{
    self = [super init];
    if (self) {
        self.timerArray = [[NSMutableArray alloc] init];
        self.wordArray = [[NSMutableArray alloc] init];
        
    }
    return self;
}
-(void)parserLrc:(NSString *)name type:(NSString *)type{
    
    NSString *path = [[NSBundle mainBundle] pathForResource:name ofType:type];
    NSURL *url = [NSURL fileURLWithPath:path];
    //转换 C 字符串
    NSString *lrc = [NSString stringWithContentsOfURL:url encoding:NSUTF8StringEncoding error:nil];
    
    if (![lrc isEqual:nil]) {
        NSArray *sepArray = [lrc componentsSeparatedByString:@"["];
        NSArray *lineArray = [[NSArray alloc] init];
        for (int i = 0; i < sepArray.count; i++) {
            if ([sepArray[i] length] > 0) {
                lineArray = [sepArray[i] componentsSeparatedByString:@"]"];
                if (![lineArray[0] isEqualToString:@"\n"]) {
                    [self.timerArray addObject:lineArray[0]];
                    [self.wordArray addObject:lineArray.count > 1 ? lineArray[1] : @""];
                }
            }
        }
    }   
}
@end

给创建View的frame写的类目(这个可以不要)

#import 
@interface UIView (Frame)
@property (nonatomic, assign) CGFloat wh_x;
@property (nonatomic, assign) CGFloat wh_y;
@property (nonatomic, assign) CGFloat wh_width;
@property (nonatomic, assign) CGFloat wh_height;

@property (nonatomic, assign) CGFloat wh_centerX;
@property (nonatomic, assign) CGFloat wh_centerY;
@end
#import "UIView+Frame.h"

@implementation UIView (Frame)

// 原点的x
// set方法
- (void)setWh_x:(CGFloat)wh_x {

    CGRect rect = self.frame;
    rect.origin.x = wh_x;
    self.frame = rect;
}
// get方法
- (CGFloat)wh_x {

    return self.frame.origin.x;
}

// 原点的y
// set方法
- (void)setWh_y:(CGFloat)wh_y {

    CGRect rect = self.frame;
    rect.origin.y = wh_y;
    self.frame = rect;
}
// get方法
- (CGFloat)wh_y {

    return self.frame.origin.y;
}
// view的width
// set方法
- (void)setWh_width:(CGFloat)wh_width {

    CGRect rect = self.frame;
    rect.size.width = wh_width;
    self.frame = rect;
}
// get方法
- (CGFloat)wh_width {

    return self.frame.size.width;
}
// view的height
// set方法
- (void)setWh_height:(CGFloat)wh_height {

    CGRect rect = self.frame;
    rect.size.height = wh_height;
    self.frame = rect;
}
// get方法
- (CGFloat)wh_height {

    return self.frame.size.height;
}

/** 中心点 */
//X
// set方法
- (void)setWh_centerX:(CGFloat)wh_centerX {

    CGPoint center = self.center;
    center.x = wh_centerX;
    
    self.center = center;
}
// get方法
- (CGFloat)wh_centerX {

    return self.center.x;
}
//Y
// set方法
- (void)setWh_centerY:(CGFloat)wh_centerY {

    CGPoint center = self.center;
    center.y = wh_centerY;
    self.center = center;
}
// get方法
- (CGFloat)wh_centerY {

    return self.center.y;
}
@end

自定义的一个View

#import 
typedef void(^Play)(UIButton *play);
typedef void(^Pause)(UIButton *pause);
typedef void(^ButtonBlock)(UIButton *btn);
@interface PlayView : UIView
//- (void)play:(void (^)(UIButton *play))play
//       pause:(void (^)(UIButton *pause))pause;
- (void)play:(ButtonBlock)play pause:(ButtonBlock)pause last:(ButtonBlock)last next:(ButtonBlock)next;
@end
#import "PlayView.h"
#import "UIView+Frame.h"

@interface PlayView ()

@property (nonatomic, strong) UIButton *buttonOfPlay;

@property (nonatomic, strong) UIButton *buttonOfLast;

@property (nonatomic, strong) UIButton *buttonOfNext;

//@property (nonatomic, copy) void (^play)(UIButton *play);
@property (nonatomic, copy) ButtonBlock play;

//@property (nonatomic, copy) void (^pause)(UIButton *pause);
@property (nonatomic, copy) ButtonBlock pause;
@property (nonatomic, copy) ButtonBlock last;
@property (nonatomic, copy) ButtonBlock next;
@end
@implementation PlayView
/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
    // Drawing code
}
*/
- (instancetype)initWithFrame:(CGRect)frame {

    self = [super initWithFrame:frame];
    if (self) {
        
        [self createSubViews];
    }
    return self;
}
- (instancetype)initWithCoder:(NSCoder *)aDecoder {

    self = [super initWithCoder:aDecoder];
    if (self) {
        
        [self createSubViews];
    }
    return self;
}

- (void)createSubViews {

    _buttonOfLast = [self buttonImageWithName:@"player_btn_pre_normal" action:@selector(last:)];
   
    
    _buttonOfPlay = [self buttonImageWithName:@"player_btn_pause_normal" action:@selector(pause:)];
   
    
    _buttonOfNext = [self buttonImageWithName:@"player_btn_next_normal" action:@selector(next:)];
   
}
#pragma mark ------------  self的属性block赋值 -----------
- (void)play:(ButtonBlock)play pause:(ButtonBlock)pause last:(ButtonBlock)last next:(ButtonBlock)next {
    
    self.play = play;
    self.pause = pause;
    self.last = last;
    self.next = next;
}
#pragma mark ------------  Last  -----------
- (void)last:(UIButton *)lastBtn {
    
    self.last(lastBtn);
    [_buttonOfPlay setImage:[UIImage imageNamed:@"player_btn_pause_normal"] forState:UIControlStateNormal];
    
}
#pragma mark ------------  Next  -----------
- (void)next:(UIButton *)nextBtn {

    self.next(nextBtn);
    [_buttonOfPlay setImage:[UIImage imageNamed:@"player_btn_pause_normal"] forState:UIControlStateNormal];
}
#pragma mark ------------  Play  -----------
- (void)play:(UIButton *)playBtn {

    [playBtn setImage:[UIImage imageNamed:@"player_btn_pause_normal"] forState:UIControlStateNormal];
    [playBtn removeTarget:self action:@selector(play:) forControlEvents:UIControlEventTouchUpInside];
    [playBtn addTarget:self action:@selector(pause:) forControlEvents:UIControlEventTouchUpInside];
    
    self.play(playBtn);
}
#pragma mark ------------  Pause  -----------
- (void)pause:(UIButton *)pauseBtn {

    [pauseBtn setImage:[UIImage imageNamed:@"player_btn_play_normal"] forState:UIControlStateNormal];
    [pauseBtn removeTarget:self action:@selector(pause:) forControlEvents:UIControlEventTouchUpInside];
    [pauseBtn addTarget:self action:@selector(play:) forControlEvents:UIControlEventTouchUpInside];
    
    self.pause(pauseBtn);
}
#pragma mark ------------  Layout布局  -----------
- (void)layoutSubviews {

    [super layoutSubviews];
    
    _buttonOfPlay.frame = CGRectMake(0, 0, CGRectGetHeight(self.bounds), CGRectGetHeight(self.bounds));
    _buttonOfPlay.center = CGPointMake(CGRectGetWidth(self.bounds) / 2, CGRectGetHeight(self.bounds) / 2);
    
    _buttonOfLast.frame = CGRectMake(0, 0, CGRectGetWidth(_buttonOfPlay.bounds) * 2 / 3, CGRectGetHeight(_buttonOfPlay.bounds) * 2 / 3);
    _buttonOfLast.wh_centerX = _buttonOfPlay.wh_centerX / 2;
    _buttonOfLast.wh_centerY = _buttonOfPlay.wh_centerY;
    
    _buttonOfNext.frame = CGRectMake(0, 0, CGRectGetWidth(_buttonOfPlay.bounds) * 2 / 3, CGRectGetHeight(_buttonOfPlay.bounds) * 2 / 3);
    _buttonOfNext.wh_centerX = _buttonOfPlay.wh_centerX * 1.5;
    _buttonOfNext.wh_centerY = _buttonOfPlay.wh_centerY;
}
#pragma mark ------------  创建Button的共同方法  -----------
- (UIButton *)buttonImageWithName:(NSString *)imageName action:(SEL)action {

    UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
    [button setImage:[UIImage imageNamed:imageName] forState:UIControlStateNormal];
    [self addSubview:button];
    
    [button addTarget:self action:action forControlEvents:UIControlEventTouchUpInside];
    return button;
}
@end

首页的VC是一个tableView存放本地音乐列表.m

#import "ViewController.h"
#import "ModelOfMusic.h"
#import "VCOfPlayer.h"
#import "WHMusicTool.h"
@interface ViewController () 
@property (nonatomic, strong) UITableView *tableView;
@property (nonatomic, strong) NSMutableArray *mArrOfMusic;
@property (nonatomic, strong) VCOfPlayer *vcOfPlayer;
@end
@implementation ViewController
-(VCOfPlayer *)vcOfPlayer {

    if (_vcOfPlayer == nil) {
        
        _vcOfPlayer = [[VCOfPlayer alloc] init];
    }
    return _vcOfPlayer;
}
- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    [self createTableView];
}
- (void)createTableView {

    self.tableView = [[UITableView alloc] initWithFrame:[UIScreen mainScreen].bounds style:UITableViewStylePlain];
    
    [self.view addSubview:_tableView];
    _tableView.delegate = self;
    _tableView.dataSource = self;
    
    [_tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"pool"];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {

    return [WHMusicTool arrayOfMusics].count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"pool"];
    
    ModelOfMusic *model = [WHMusicTool arrayOfMusics][indexPath.row];
    cell.textLabel.text = model.name;
    return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {

    return 70;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    [tableView deselectRowAtIndexPath:indexPath animated:YES];
    
    // 2.设置正在播放的歌曲
    [WHMusicTool setPlayingMusic:[WHMusicTool arrayOfMusics][indexPath.row]];
    
    // 调用show方法
    [self.vcOfPlayer show];
}
@end

显示播放页的VC.h

#import 
@interface VCOfPlayer : UIViewController
- (void)show;
@end

播放页面的.m


#import "VCOfPlayer.h"
#import 
#import "PlayView.h"
#import "ModelOfMusic.h"
#import "UIView+Frame.h"
#import "WHMusicTool.h"
#import "WHAudioTool.h"
#import "LrcParser.h"

@interface VCOfPlayer () 
// 歌手的图片
@property (nonatomic, strong) UIImageView *imageViewOfSinger;
// 歌名
@property (nonatomic, strong) UILabel *labelOfSongName;
// 歌手名
@property (nonatomic, strong) UILabel *labelOfSingerName;
// 音乐播放器
@property (nonatomic, strong) AVAudioPlayer *player;
// Model类
@property (nonatomic, strong) ModelOfMusic *playingMusic;
// 滑动指示器
@property (nonatomic, strong) UISlider *slider;
// 当前时间
@property (nonatomic, strong) UILabel *labelOfMin;
// 歌曲总时间
@property (nonatomic, strong) UILabel *labelOfMax;
// 时间
@property (nonatomic, strong) NSTimer *timer;
// 解析歌词类
@property (nonatomic, strong) LrcParser *lrcContent;
// 歌词的当前行
@property (nonatomic, assign) NSInteger currentRow;
// 显示歌词的tableView
@property (nonatomic, strong) UITableView *tableView;
@end
@implementation VCOfPlayer
- (void)show {

    // 1.禁用整个app的点击事件
    UIWindow *window = [UIApplication sharedApplication].keyWindow;
    window.userInteractionEnabled = NO;
    
    // 2.添加播放界面
    //   设置View的大小覆盖整个窗口
    self.view.frame = window.bounds;
    
    // 设置View显示
    self.view.hidden = NO;
    // 把View添加到窗口上
    [window addSubview:self.view];
    
    // 3.检测是否换了歌曲
    if (self.playingMusic != [WHMusicTool playingMusic]) {
        
        [self resetPlayMusic];
    }
    
    // 3.使用动画让View显示
    self.view.wh_y = self.view.wh_height;
    [UIView animateWithDuration:0.25 animations:^{
       
        self.view.wh_y = 0;
    } completion:^(BOOL finished) {
        
        // 设置音乐数据
        [self startPlayingMusic];
        
        _imageViewOfSinger.backgroundColor = [UIColor brownColor];
        window.userInteractionEnabled = YES;
    }];
}

- (void)back {
    
    // 1.禁用整个app的点击事件
    UIWindow *window = [UIApplication sharedApplication].keyWindow;
    
    window.userInteractionEnabled = NO;
    
    // 2.动画隐藏View
    [UIView animateWithDuration:0.25 animations:^{
        
        self.view.wh_y = window.wh_height;
    } completion:^(BOOL finished) {
        
        window.userInteractionEnabled = YES;
        
        // 设置View的隐藏能节省一些性能
        self.view.hidden = YES;
    }];
}
#pragma mark ------------  重置正在播放得到音乐  -----------

- (void)resetPlayMusic {

    // 1. 重置界面数据
//    self.imageViewOfSinger.image = [UIImage imageNamed:@"28131977_1383101943208"];
//    self.labelOfSongName = nil;
//    self.labelOfSingerName = nil;
    
    // 2. 停止播放
    [WHAudioTool stopMusic:self.playingMusic.filename];
    
    // 把播放器进行清空
    self.player = nil;
}
#pragma mark ------------  开始播放音乐数据  -----------
- (void)startPlayingMusic {

    // 1. 设置界面数据
    // 取出当前正在播放的音乐
    
    
    // 如果当前播放的音乐就是传入的音乐, 直接返回
    if (self.playingMusic == [WHMusicTool playingMusic]) {
        
        return;
    }
    //存取音乐
    self.playingMusic = [WHMusicTool playingMusic];
    self.imageViewOfSinger.image = [UIImage imageNamed:self.playingMusic.icon];
    self.labelOfSongName.text = self.playingMusic.name;
    self.labelOfSingerName.text = self.playingMusic.singer;
   
    // 2. 开始播放
    self.player = [WHAudioTool playMusic:self.playingMusic.filename];
    
    /** 设置进度条 */
    _slider.minimumValue = 0.0f;
    _slider.maximumValue = self.player.duration;
    [_slider addTarget:self action:@selector(sliderAction:) forControlEvents:UIControlEventValueChanged];
    
    
    /** 定时器(让slider随player播放移动) */
    self.timer = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(changeTime:) userInfo:nil repeats:YES];
    
    /** 进度条两边的时间 */
    NSInteger allTime = self.player.duration;
    if (allTime / 60 < 10) {
        
        _labelOfMax.text = [NSString stringWithFormat:@"0%ld:%ld", allTime / 60, allTime % 60];
    } else if (allTime / 60 > 10) {
    
        _labelOfMax.text = [NSString stringWithFormat:@"%ld:%ld", allTime / 60, allTime % 60];
    }
    
    [self createLyricTableView];
}

- (void)sliderAction:(UISlider *)slider {

    self.player.currentTime = self.slider.value;
    
}
/** 定时器 */
- (void)changeTime:(NSTimer *)timer {

    self.slider.value = self.player.currentTime;
    
    // 时间跟着走
    NSInteger currentTime = self.player.currentTime;
    if (currentTime / 60 < 10) {
        
        if (currentTime % 60 < 10) {
            
            _labelOfMin.text = [NSString stringWithFormat:@"0%ld:0%ld", currentTime / 60, currentTime % 60];
        } else if (currentTime % 60 > 10) {
        
            _labelOfMin.text = [NSString stringWithFormat:@"0%ld:%ld", currentTime / 60, currentTime % 60];
        }
    } else if (currentTime / 60 > 10) {
    
        if (currentTime % 60 < 10) {
            
            _labelOfMin.text = [NSString stringWithFormat:@"%ld:0%ld", currentTime / 60, currentTime % 60];
        } else if (currentTime % 60 > 10) {
        
            _labelOfMin.text = [NSString stringWithFormat:@"%ld:%ld", currentTime / 60, currentTime % 60];
        }
    } 
   
    for (int i = 0; i < self.lrcContent.timerArray.count; i++) {
        
        NSArray *timeArray = [self.lrcContent.timerArray[i] componentsSeparatedByString:@":"];
        float lrcTime = [timeArray[0] intValue] * 60 + [timeArray[1] floatValue];
        if (currentTime > lrcTime) {
            
            self.currentRow = i;
        }
    }
    [self.tableView reloadData];
    [self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:self.currentRow inSection:0] atScrollPosition:UITableViewScrollPositionMiddle animated:YES];
}
- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    
    [self createSubViews];
}
- (void)createSubViews {
    
    self.view.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"28131977_1383101943208"]];
    
    /** 歌手圆图 */
    self.imageViewOfSinger = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, CGRectGetWidth(self.view.bounds) * 0.75, CGRectGetWidth(self.view.bounds) * 0.75)];
    _imageViewOfSinger.wh_centerX = self.view.wh_centerX;
    _imageViewOfSinger.wh_centerY = self.view.wh_centerY * 0.8;
    [self.view addSubview:_imageViewOfSinger];
    self.imageViewOfSinger.clipsToBounds = YES;
    self.imageViewOfSinger.layer.cornerRadius = self.imageViewOfSinger.bounds.size.width / 2;
    self.imageViewOfSinger.layer.borderWidth = 2;
    
   /** 歌名 */
    self.labelOfSongName = [[UILabel alloc] initWithFrame:CGRectMake(60, 20, CGRectGetWidth(self.view.bounds) - 120, 44)];
    [self.view addSubview:_labelOfSongName];
    _labelOfSongName.textAlignment = NSTextAlignmentCenter;
    _labelOfSongName.textColor = [UIColor whiteColor];
    _labelOfSongName.font = [UIFont systemFontOfSize:20];
    
    /** 歌手 */
    self.labelOfSingerName = [[UILabel alloc] initWithFrame:CGRectMake(60, 70, CGRectGetWidth(self.view.bounds) - 120, 50)];
    [self.view addSubview:_labelOfSingerName];
    _labelOfSingerName.textAlignment = NSTextAlignmentCenter;
    _labelOfSingerName.textColor = [UIColor whiteColor];
    _labelOfSingerName.font = [UIFont systemFontOfSize:15];
    
    
    /** slider */
    self.slider = [[UISlider alloc] initWithFrame:CGRectMake(50, CGRectGetHeight(self.view.bounds) - 130, CGRectGetWidth(self.view.bounds) - 100, 30)];
    [self.view addSubview:_slider];
    [_slider setMinimumTrackImage:[UIImage imageNamed:@"player_slider_playback_left"] forState:UIControlStateNormal];
    [_slider setMaximumTrackImage:[UIImage imageNamed:@"player_slider_playback_right"] forState:UIControlStateNormal];
    [_slider setThumbImage:[UIImage imageNamed:@"player_slider_playback_thumb"] forState:UIControlStateNormal];

    /** slider两边的时间 */
    self.labelOfMin = [[UILabel alloc] initWithFrame:CGRectMake(0, CGRectGetHeight(self.view.bounds) - 130, 50, 30)];
    [self.view addSubview:_labelOfMin];
    _labelOfMin.textColor = [UIColor whiteColor];
    _labelOfMin.textAlignment = NSTextAlignmentCenter;
    _labelOfMin.text = @"00:00";
    
    self.labelOfMax = [[UILabel alloc] initWithFrame:CGRectMake(CGRectGetWidth(self.view.bounds) - 50, CGRectGetHeight(self.view.bounds) - 130, 50, 30)];
    [self.view addSubview:_labelOfMax];
    _labelOfMax.textColor = [UIColor whiteColor];
    _labelOfMax.textAlignment = NSTextAlignmentCenter;
    
    /** 自定义的playView */
    PlayView *playView = [[PlayView alloc] initWithFrame:CGRectMake(0, CGRectGetHeight(self.view.bounds) - 100, CGRectGetWidth(self.view.bounds), 100)];
    [self.view addSubview:playView];
    [playView play:^(UIButton *btn) {
        
        [self.player play];
        
    } pause:^(UIButton *btn) {
        
        [self.player pause];
    } last:^(UIButton *btn) {
        
        // 在开始播放之前, 禁用一切的app点击事件
        UIWindow *window = [[UIApplication sharedApplication].windows lastObject];
        window.userInteractionEnabled = NO;
        // 重置当前歌曲
        [self resetPlayMusic];
        
        // 获得上一曲
        [WHMusicTool setPlayingMusic:[WHMusicTool lastMusic]];
        
        // 播放上一曲
        [self startPlayingMusic];
        
        window.userInteractionEnabled = YES;
        
        // 恢复window的点击为可用
        window.userInteractionEnabled = YES;
        
    } next:^(UIButton *btn) {
        
        // 在开始播放之前, 禁用一切的app点击事件
        UIWindow *window = [[UIApplication sharedApplication].windows lastObject];
        window.userInteractionEnabled = NO;

        // 重置当前歌曲
        [self resetPlayMusic];
        
        // 获取下一曲
        [WHMusicTool setPlayingMusic:[WHMusicTool nextMusic]];
        
        // 播放下一曲
        [self startPlayingMusic];
        
        // 恢复window的点击为可用
        window.userInteractionEnabled = YES;
    }];
    /** 左上角的返回按钮 */
    UIButton *buttonOfBack = [UIButton buttonWithType:UIButtonTypeCustom];
    [buttonOfBack setTitle:@"Back" forState:UIControlStateNormal];
    [self.view addSubview:buttonOfBack];
    buttonOfBack.frame = CGRectMake(10, 20, 50, 44);
    [buttonOfBack addTarget:self action:@selector(back) forControlEvents:UIControlEventTouchUpInside];
    /** 右上角的歌词按钮 */
    UIButton *buttonOfLyric = [UIButton buttonWithType:UIButtonTypeCustom];
    [self.view addSubview:buttonOfLyric];
    [buttonOfLyric setTitle:@"歌词" forState:UIControlStateNormal];
    buttonOfLyric.frame = CGRectMake(CGRectGetWidth(self.view.bounds) - 60, 20, 50, 44);
    [buttonOfLyric addTarget:self action:@selector(lyricAction:) forControlEvents:UIControlEventTouchUpInside]; 
}
- (void)createLyricTableView {
    NSArray *array = [_playingMusic.lrcname componentsSeparatedByString:@"."];
    self.lrcContent = [[LrcParser alloc] init];
    [_lrcContent parserLrc:array.firstObject type:array.lastObject];
     
    self.tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 64, CGRectGetWidth(self.view.bounds), CGRectGetHeight(self.view.bounds) - 200) style:UITableViewStylePlain];
    [self.view addSubview:_tableView];
    _tableView.delegate = self;
    _tableView.dataSource = self;
    
    [_tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"pool"];
    _tableView.hidden = YES;
    _tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    
    return _lrcContent.wordArray.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"pool"];
    
    cell.textLabel.text =  _lrcContent.wordArray[indexPath.row];
    
    if (indexPath.row == self.currentRow) {
        
        cell.textLabel.textColor = [UIColor redColor];
        cell.textLabel.font = [UIFont systemFontOfSize:20];
    } else {
    
        cell.textLabel.textColor = [UIColor lightGrayColor];
        cell.textLabel.font = [UIFont systemFontOfSize:15];
    }
    
    cell.textLabel.textAlignment = NSTextAlignmentCenter;
    cell.backgroundColor = [UIColor clearColor];
    return cell;
}
- (void)lyricAction:(UIButton *)btn {

    if (self.tableView.hidden) {
        
        self.tableView.hidden = NO;
        btn.selected = YES;
    } else {
    
        self.tableView.hidden = YES;
        btn.selected = NO;
    }
}
@end

额 有点乱. 不过仔细屡屡就明白了!!!

你可能感兴趣的:(本地音乐播放器的使用)