那么现在给同学补齐一个还算比较完整功能的音乐播放器,还有待完善!废话不多说,直接上代码!先看示例:

 

 

 

iOS开发后台音频播放 ios音乐播放器开发_iOS视频播放

 

 

//
//  AppDelegate.h
//  05-音乐播放器
//
//  Created by 周昭 on 2017/3/20.
//  Copyright © 2017年 ZZ. All rights reserved.
//
 
#import <UIKit/UIKit.h>
 
typedef void (^remoteBlock)(UIEvent
@interface AppDelegate : UIResponder <UIApplicationDelegate>
 
@property (strong, nonatomic) UIWindow *window;
 
/**
 *  一个回调远程事件的block
 */
@property (nonatomic, copy) remoteBlock removteBlock;
 
@end
 
//
//  AppDelegate.m
//  05-音乐播放器
//
//  Created by 周昭 on 2017/3/20.
//  Copyright © 2017年 ZZ. All rights reserved.
//
 
#import "AppDelegate.h"
#import <AVFoundation/AVFoundation.h>
 
@interface  AppDelegate ()
 
@end
 
@implementation AppDelegate
 
 
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary
 
    
    AVAudioSession *session = [AVAudioSession sharedInstance];
    [session setCategory:AVAudioSessionCategoryPlayback error:nil];
setActive:YES error:nil];
    
    // 接收远程事件
    [application beginReceivingRemoteControlEvents];
    
    return YES;
}
 
/**
 *  锁屏按钮的远程通知
 */
- (void)remoteControlReceivedWithEvent:(UIEvent
{
    if (event.type == UIEventTypeRemoteControl) {
if (self.removteBlock) {
self.removteBlock(event);
        }
    }
}
 
- (void)applicationDidEnterBackground:(UIApplication
    // 开启后台任务
    [application beginBackgroundTaskWithExpirationHandler:nil];
}
 
@end
 
 
//
//  ZZMusic.h
//  05-音乐播放器
//
//  Created by 周昭 on 2017/3/20.
//  Copyright © 2017年 ZZ. All rights reserved.
//
 
#import <Foundation/Foundation.h>
 
@interface ZZMusic : NSObject
@property (copy, nonatomic) NSString *name;
@property (copy, nonatomic) NSString *filename;
@property (copy, nonatomic) NSString *singer;
@property (copy, nonatomic) NSString *singerIcon;
@property (copy, nonatomic) NSString *icon;
 
@property (nonatomic, assign, getter = isPlaying) BOOL playing;
@end
 
//
//  ZZMusic.m
//  05-音乐播放器
//
//  Created by 周昭 on 2017/3/20.
//  Copyright © 2017年 ZZ. All rights reserved.
//
 
#import "ZZMusic.h"
 
@implementation ZZMusic
 
@end
 
//
//  UIImage+ZZ.h
//  05-音乐播放器
//
//  Created by 周昭 on 2017/3/20.
//  Copyright © 2017年 ZZ. All rights reserved.
//
 
#import <UIKit/UIKit.h>
 
@interface
+ (instancetype)circleImageWithName:(NSString *)name borderWidth:(CGFloat)borderWidth borderColor:(UIColor
@end
 
//
//  UIImage+ZZ.m
//  05-音乐播放器
//
//  Created by 周昭 on 2017/3/20.
//  Copyright © 2017年 ZZ. All rights reserved.
//
 
#import "UIImage+ZZ.h"
 
@implementation UIImage (ZZ)
+ (instancetype)circleImageWithName:(NSString *)name borderWidth:(CGFloat)borderWidth borderColor:(UIColor
{
    // 1.加载原图
UIImage *oldImage = [UIImage imageNamed:name];
    
    // 2.开启上下文
CGFloat imageW = oldImage.size.width + 2
CGFloat imageH = oldImage.size.height + 2
CGSize imageSize = CGSizeMake(imageW, imageH);
    UIGraphicsBeginImageContextWithOptions(imageSize, NO,  0.0);
    
    // 3.取得当前的上下文
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    
    // 4.画边框(大圆)
set];
CGFloat bigRadius = imageW * 0.5; // 大圆半径
CGFloat centerX = bigRadius; // 圆心
CGFloat
CGContextAddArc(ctx, centerX, centerY, bigRadius, 0, M_PI * 2, 0);
    CGContextFillPath(ctx); // 画圆
    
    // 5.小圆
CGFloat
CGContextAddArc(ctx, centerX, centerY, smallRadius, 0, M_PI * 2, 0);
    
    CGContextClip(ctx);
    
    // 6.画图
drawInRect:CGRectMake(borderWidth, borderWidth, oldImage.size.width, oldImage.size.height)];
    
    // 7.取图
    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
    
    // 8.结束上下文
    UIGraphicsEndImageContext();
    
return
}
 
@end
 
 
 
 
//
//  NSString+ZZ.h
//  05-音乐播放器
//
//  Created by 周昭 on 2017/3/21.
//  Copyright © 2017年 ZZ. All rights reserved.
//
 
#import <Foundation/Foundation.h>
 
@interface
/**
 *  返回分与秒的字符串 如:01:60
 */
+ (NSString *)getMinuteSecondWithSecond:(NSTimeInterval)time;
@end
 
 
 
 
//
//  NSString+ZZ.m
//  05-音乐播放器
//
//  Created by 周昭 on 2017/3/21.
//  Copyright © 2017年 ZZ. All rights reserved.
//
 
#import "NSString+ZZ.h"
 
@implementation NSString (ZZ)
 
+ (NSString *)getMinuteSecondWithSecond:(NSTimeInterval)time {
    
int minute = (int)time / 60;
int second = (int)time % 60;
    
if (second > 9) { //2:10
return [NSString stringWithFormat:@"%d:%d",minute,second];
    }
    
    //2:09
return [NSString stringWithFormat:@"%d:0%d",minute,second];
}
@end
 
//
//  ZZAudioTool.h
//  05-音乐播放器
//
//  Created by 周昭 on 2017/3/20.
//  Copyright © 2017年 ZZ. All rights reserved.
//
 
#import <Foundation/Foundation.h>
#import <AVFoundation/AVFoundation.h>
@class ZZMusic;
@interface ZZAudioTool : NSObject
/**
 *  播放器
 */
@property(nonatomic, strong) AVAudioPlayer *player;
 
/*
 * 音乐播放前的准备工作
 */
- (void)prepareToPlayWithMusic:(ZZMusic
 
/*
 * 播放
 */
- (void)play;
/*
 * 暂停
 */
- (void)pause;
 
/**
 *  创建单例
 */
+ (instancetype)shareInstance;
/**
 *  播放音效
 *
 *  @param filename 音效文件名
 */
+ (void)playSound:(NSString
 
/**
 *  销毁音效
 *
 *  @param filename 音效文件名
 */
+ (void)disposeSound:(NSString
 
/**
 *  播放音乐
 *
 *  @param filename 音乐文件名
 */
+ (AVAudioPlayer *)playMusic:(NSString
 
/**
 *  暂停音乐
 *
 *  @param filename 音乐文件名
 */
+ (void)pauseMusic:(NSString
 
/**
 *  停止音乐
 *
 *  @param filename 音乐文件名
 */
+ (void)stopMusic:(NSString
 
/**
 *  返回当前正在播放的音乐播放器
 */
+ (AVAudioPlayer
 
@end
 
 
//
//  ZZAudioTool.m
//  05-音乐播放器
//
//  Created by 周昭 on 2017/3/20.
//  Copyright © 2017年 ZZ. All rights reserved.
//
 
#import "ZZAudioTool.h"
#import "ZZMusic.h"
#import <MediaPlayer/MediaPlayer.h>
 
@implementation ZZAudioTool
/**
 *  存放所有的音频ID
 *  字典: filename作为key, soundID作为value
 */
static NSMutableDictionary *_soundIDDict;
 
/**
 *  存放所有的音乐播放器
 *  字典: filename作为key, audioPlayer作为value
 */
static NSMutableDictionary
 
/**
 *  返回请求单例对象
 */
+ (instancetype)shareInstance
{
static ZZAudioTool
static dispatch_once_t
dispatch_once(&onceToken, ^{
if (audioTool == nil) {
ZZAudioTool alloc] init];
        }
    });
return
}
 
- (void)prepareToPlayWithMusic:(ZZMusic
{
if (!music.filename) return;
    
    // 创建播放器
    NSURL *musicURL = [[NSBundle mainBundle] URLForResource:music.filename withExtension:nil];
    self.player = [[AVAudioPlayer alloc] initWithContentsOfURL:musicURL error:nil];
    
    // 准备
    [self.player prepareToPlay];
 
    
    [self setUpLockInfoWithMP3Info:music];
}
 
- (void)setUpLockInfoWithMP3Info:(ZZMusic
{
NSLog(@"%s",__func__);
    //锁屏信息设置
    NSMutableDictionary *playingInfo = [NSMutableDictionary dictionary];
    
    //1.专辑名称
    playingInfo[MPMediaItemPropertyAlbumTitle] = @"中文十大金曲";
    
    //2.歌曲
MPMediaItemPropertyTitle] = music.name;
    
    //3.歌手名称
MPMediaItemPropertyTitle] = music.singer;
    
    //4.专辑图片
if(music.icon){
UIImage *artWorkImage = [UIImage imageNamed:music.icon];
MPMediaItemArtwork *artwork = [[MPMediaItemArtwork alloc] initWithImage:artWorkImage];
MPMediaItemPropertyArtwork] = artwork;
    }
    
    //5.锁屏音乐总时间
    playingInfo[MPMediaItemPropertyPlaybackDuration] = @(self.player.duration);
    
    
    [MPNowPlayingInfoCenter defaultCenter].nowPlayingInfo = playingInfo;
}
 
/*
 * 播放
 */
- (void)play
{
self.player play];
}
 
/*
 * 暂停
 */
- (void)pause
{
self.player pause];
}
 
/**
 *  初始化
 */
+ (void)initialize
{
    _soundIDDict = [NSMutableDictionary dictionary];
    _audioPlayerDict = [NSMutableDictionary dictionary];
}
 
/**
 *  播放音效
 *
 *  @param filename 音效文件名
 */
+ (void)playSound:(NSString
{
if (!filename) return;
    
    // 1.从字典中取出soundID
SystemSoundID soundID = [_soundIDDict[filename] unsignedLongValue];
if (!soundID) { // 创建
        // 加载音效文件
        NSURL *url = [[NSBundle mainBundle] URLForResource:filename withExtension:nil];
        
if (!url) return;
        
        // 创建音效ID
        AudioServicesCreateSystemSoundID((__bridge CFURLRef)url, &soundID);
        
// 放入字典
_soundIDDict[filename] = @(soundID);
    }
    
    // 2.播放
    AudioServicesPlaySystemSound(soundID);
}
 
/**
 *  销毁音效
 *
 *  @param filename 音效文件名
 */
+ (void)disposeSound:(NSString
{
if (!filename) return;
    
SystemSoundID soundID = [_soundIDDict[filename] unsignedLongValue];
if
        // 销毁音效ID
        AudioServicesDisposeSystemSoundID(soundID);
        
        // 从字典中移除
_soundIDDict removeObjectForKey:filename];
    }
}
 
/**
 *  播放音乐
 *
 *  @param filename 音乐文件名
 */
+ (AVAudioPlayer *)playMusic:(NSString
{
if (!filename) return nil;
    
    // 1.从字典中取出audioPlayer
AVAudioPlayer *audioPlayer = _audioPlayerDict[filename];
if (!audioPlayer) { // 创建
        // 加载音乐文件
        NSURL *url = [[NSBundle mainBundle] URLForResource:filename withExtension:nil];
        
if (!url) return nil;
        
        // 创建audioPlayer
AVAudioPlayer alloc] initWithContentsOfURL:url error:nil];
        
// 缓冲
prepareToPlay];
        
        //        audioPlayer.enableRate = YES;
        //        audioPlayer.rate = 10.0;
        
// 放入字典
_audioPlayerDict[filename] = audioPlayer;
    }
    
    // 2.播放
if (!audioPlayer.isPlaying) {
play];
    }
    
return
}
 
/**
 *  暂停音乐
 *
 *  @param filename 音乐文件名
 */
+ (void)pauseMusic:(NSString
{
if (!filename) return;
    
    // 1.从字典中取出audioPlayer
AVAudioPlayer *audioPlayer = _audioPlayerDict[filename];
    
    // 2.暂停
if (audioPlayer.isPlaying) {
pause];
    }
}
 
/**
 *  停止音乐
 *
 *  @param filename 音乐文件名
 */
+ (void)stopMusic:(NSString
{
if (!filename) return;
    
    // 1.从字典中取出audioPlayer
AVAudioPlayer *audioPlayer = _audioPlayerDict[filename];
    
    // 2.暂停
if (audioPlayer.isPlaying) {
stop];
        
// 直接销毁
_audioPlayerDict removeObjectForKey:filename];
    }
}
 
/**
 *  返回当前正在播放的音乐播放器
 */
+ (AVAudioPlayer
{
for (NSString *filename in _audioPlayerDict) {
AVAudioPlayer *audioPlayer = _audioPlayerDict[filename];
        
if (audioPlayer.isPlaying) {
return
        }
    }
    
    return nil;
}
 
@end
 
 
//
//  ZZMusicCell.h
//  05-音乐播放器
//
//  Created by 周昭 on 2017/3/20.
//  Copyright © 2017年 ZZ. All rights reserved.
//
 
#import <UIKit/UIKit.h>
@class ZZMusic;
@interface ZZMusicCell : UITableViewCell
+ (instancetype)cellWithTableView:(UITableView
 
@property (nonatomic, strong) ZZMusic *music;
 
 
@end
 
//
//  ZZMusicCell.m
//  05-音乐播放器
//
//  Created by 周昭 on 2017/3/20.
//  Copyright © 2017年 ZZ. All rights reserved.
//
 
#import "ZZMusicCell.h"
#import "ZZMusic.h"
 
@interface  ZZMusicCell()
 
@end
 
@implementation ZZMusicCell
 
+ (instancetype)cellWithTableView:(UITableView
{
static NSString *ID = @"music";
    ZZMusicCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
if (cell == nil) {
        cell = [[ZZMusicCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:ID];
    }
return
}
 
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString
{
if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {
        self.backgroundColor = [UIColor clearColor];
        self.selectedBackgroundView = [[UIImageView alloc]  initWithImage:[UIImage imageNamed:@"backgroundImage"]];
    }
    
    return self;
}
 
- (void)setMusic:(ZZMusic
{
_music
    
self.textLabel.text = music.name;
    self.detailTextLabel.text = music.singer;
    self.imageView.image = [UIImage imageNamed:music.singerIcon];
}
 
@end
 
 
//
//  ZZPlayerToolBar.h
//  05-音乐播放器
//
//  Created by 周昭 on 2017/3/20.
//  Copyright © 2017年 ZZ. All rights reserved.
//
 
#import <UIKit/UIKit.h>
 
typedef enum
    ZZPlayerToolBarPreviousButtonType,
    ZZPlayerToolBarNextButtonType,
    ZZPlayerToolBarPlayButtonType,
    ZZPlayerToolBarPauseButtonType,
    ZZPlayerToolBarTypeButtonType
} ZZPlayerToolBarButtonType;
 
@class ZZMusic,ZZPlayerToolBar;
 
@protocol ZZPlayerToolBarDelegate <NSObject>
@optional
 
- (void)playerToolBar:(ZZPlayerToolBar *)playerToolBar didClickBtnWithType:(ZZPlayerToolBarButtonType)type;
 
@end
 
@interface ZZPlayerToolBar : UIView
 
@property (nonatomic, strong) ZZMusic *music;
 
@property (nonatomic, assign)  ZZPlayerToolBarButtonType type;
 
@property (nonatomic, weak) id <ZZPlayerToolBarDelegate> delegate;
 
+ (instancetype)playerToolBar;
 
@end
 
 
//
//  ZZPlayerToolBar.m
//  05-音乐播放器
//
//  Created by 周昭 on 2017/3/20.
//  Copyright © 2017年 ZZ. All rights reserved.
//
 
#import "ZZPlayerToolBar.h"
#import "ZZMusic.h"
#import "ZZAudioTool.h"
#import "NSString+ZZ.h"
#import "UIImage+ZZ.h"
#import "Colours.h"
 
@interface  ZZPlayerToolBar()
@property (weak, nonatomic) UIImageView *bgImg;//背景图片
@property (weak, nonatomic) UIImageView *singerIcon;//歌手图片
@property (weak, nonatomic) UIButton *previousBtn;//上一首
@property (weak, nonatomic) UIButton *playBtn;//播放\暂停
@property (weak, nonatomic) UIButton *nextBtn;//下一首
@property (weak, nonatomic) UIButton *typeBtn;//播放模式
@property (weak, nonatomic) UISlider *timeSlider;//滚动条
@property (weak, nonatomic) UILabel *totalTimeLabel;//总时间
@property (weak, nonatomic) UILabel *currentTimeLabel;//当前播放的时间
@property (strong, nonatomic) CADisplayLink *link;//定时器
@property (assign, nonatomic, getter = isDragging) BOOL dragging;//是否正在拖拽
 
@end
 
@implementation
 
- (CADisplayLink *)link {
if (!_link) {
        _link = [CADisplayLink displayLinkWithTarget:self selector:@selector(update)];
    }
return _link;
}
 
+ (instancetype)playerToolBar
{
return [[self alloc] init];
}
 
- (instancetype)initWithFrame:(CGRect)frame
{
if (self = [super initWithFrame:frame]) {
        [self setUpSubViews];
        
        [self.link addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
 
    }
    
    return self;
}
 
- (instancetype)initWithCoder:(NSCoder
{
if (self = [super initWithCoder:decoder]) {
        [self setUpSubViews];
        
        [self.link addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
    }
    
    return self;
}
 
#pragma mark - setUp 初始化
- (void)setUpSubViews
{
    UIImageView *bgImg = [[UIImageView alloc]  init];
image = [UIImage imageNamed:@"play_bar_bg2"];
self addSubview:bgImg];
self.bgImg
    
UISlider *timeSlider = [[UISlider alloc] init];
    [timeSlider setThumbImage:[UIImage imageNamed:@"playbar_slider_thumb"] forState:UIControlStateNormal];
    [timeSlider addTarget:self action:@selector(timeSliderChange:) forControlEvents:UIControlEventValueChanged];
self addSubview:timeSlider];
self.timeSlider
    
UILabel *currentTimeLabel = [[UILabel alloc] init];
font = [UIFont systemFontOfSize:14.0f];
textColor = [UIColor whiteColor];
textAlignment = NSTextAlignmentRight;
text = NSLocalizedString(@"00:00", nil);
self addSubview:currentTimeLabel];
self.currentTimeLabel
    
UILabel *totalTimeLabel = [[UILabel alloc] init];
font = [UIFont systemFontOfSize:14.0f];
textColor = [UIColor lightGrayColor];
textAlignment = NSTextAlignmentLeft;
text = NSLocalizedString(@"00:00", nil);
self addSubview:totalTimeLabel];
self.totalTimeLabel
    
UIImageView *singerIcon = [[UIImageView alloc] init];
image = [UIImage imageNamed:@"zxy_icon.jpg"];
self addSubview:singerIcon];
self.singerIcon
    
UIButton *previousBtn = [[UIButton alloc] init];
    [previousBtn setImage:[UIImage imageNamed:@"playbar_prebtn_nomal"] forState:UIControlStateNormal];
    [previousBtn setImage:[UIImage imageNamed:@"playbar_prebtn_click"] forState:UIControlStateHighlighted];
    [previousBtn addTarget:self action:@selector(buttonClick:) forControlEvents:UIControlEventTouchUpInside];
    previousBtn.tag = ZZPlayerToolBarPreviousButtonType;
self addSubview:previousBtn];
self.previousBtn
    
UIButton *playBtn = [[UIButton alloc] init];
    [playBtn setImage:[UIImage imageNamed:@"playbar_playbtn_nomal"] forState:UIControlStateNormal];
    [playBtn setImage:[UIImage imageNamed:@"playbar_playbtn_click"] forState:UIControlStateHighlighted];
    [playBtn addTarget:self action:@selector(buttonClick:) forControlEvents:UIControlEventTouchUpInside];
    playBtn.tag = ZZPlayerToolBarPlayButtonType;
self addSubview:playBtn];
self.playBtn
    
UIButton *nextBtn = [[UIButton alloc] init];
    [nextBtn setImage:[UIImage imageNamed:@"playbar_nextbtn_nomal"] forState:UIControlStateNormal];
    [nextBtn setImage:[UIImage imageNamed:@"playbar_nextbtn_click"] forState:UIControlStateHighlighted];
    [nextBtn addTarget:self action:@selector(buttonClick:) forControlEvents:UIControlEventTouchUpInside];
    nextBtn.tag = ZZPlayerToolBarNextButtonType;
self addSubview:nextBtn];
self.nextBtn
    
UIButton *typeBtn = [[UIButton alloc] init];
layer.borderWidth = 1;
    typeBtn.layer.borderColor = [UIColor blueColor].CGColor;
    [typeBtn addTarget:self action:@selector(buttonClick:) forControlEvents:UIControlEventTouchUpInside];
    typeBtn.tag = ZZPlayerToolBarTypeButtonType;
#warning - 没图先隐藏
hidden = YES;
self addSubview:typeBtn];
self.typeBtn
}
 
- (void)update
{
    // 1.更新进度条
double currentTime = [ZZAudioTool shareInstance].player.currentTime;
self.timeSlider.value
    
    // 2.更新时间
self.currentTimeLabel.text = [NSString getMinuteSecondWithSecond:currentTime];
}
 
/**
 *  时间滑动变化
 */
- (void)timeSliderChange:(UISlider
{
    // 1.播放器进度
ZZAudioTool shareInstance].player.currentTime = slider.value;
    
    // 2.工具条的当前时间
    self.currentTimeLabel.text = [NSString getMinuteSecondWithSecond:slider.value];
}
 
/**
 *  点击按钮
 *
 *  @param button 根据按钮类型来判断
 */
- (void)buttonClick:(UIButton
{
if ([self.delegate respondsToSelector:@selector(playerToolBar:didClickBtnWithType:)]) {
        if (button.tag == ZZPlayerToolBarPlayButtonType) {
if (self.music.playing) { // 播放
self.music.playing = NO;
                [button setImage:[UIImage imageNamed:@"playbar_pausebtn_nomal"] forState:UIControlStateNormal];
                [button setImage:[UIImage imageNamed:@"playbar_pausebtn_click"] forState:UIControlStateHighlighted];
                button.tag = ZZPlayerToolBarPauseButtonType;
                [self.delegate playerToolBar:self didClickBtnWithType:button.tag];
 
            }
        } else if (button.tag == ZZPlayerToolBarPauseButtonType) { // 暂停
self.music.playing = YES;
            [button setImage:[UIImage imageNamed:@"playbar_playbtn_nomal"] forState:UIControlStateNormal];
            [button setImage:[UIImage imageNamed:@"playbar_playbtn_click"] forState:UIControlStateHighlighted];
            button.tag = ZZPlayerToolBarPlayButtonType;
            [self.delegate playerToolBar:self didClickBtnWithType:button.tag];
            
        } else if (button.tag == ZZPlayerToolBarNextButtonType | button.tag == ZZPlayerToolBarPreviousButtonType) {
            [self.playBtn setImage:[UIImage imageNamed:@"playbar_playbtn_nomal"] forState:UIControlStateNormal];
            [self.playBtn setImage:[UIImage imageNamed:@"playbar_playbtn_click"] forState:UIControlStateHighlighted];
            [self.delegate playerToolBar:self didClickBtnWithType:button.tag];
 
else
            [self.delegate playerToolBar:self didClickBtnWithType:button.tag];
        }
    }
}
 
/**
 *  拿到真实的尺寸进行子控件的布局
 */
- (void)layoutSubviews
{
#warning - 一定要调用super的方法
    [super layoutSubviews];
    
CGFloat margin = 5;
    
self.bgImg.frame = self.frame;
    
CGFloat currentTimeLabelX = 10;
CGFloat currentTimeLabelY = 5;
CGFloat currentTimeLabelW = 40;
CGFloat currentTimeLabelH = 30;
self.currentTimeLabel.frame = CGRectMake(currentTimeLabelX, currentTimeLabelY, currentTimeLabelW, currentTimeLabelH);
    
CGFloat timeSliderX = CGRectGetMaxX(self.currentTimeLabel.frame) + margin;
CGFloat
CGFloat timeSliderW = self.frame.size.width - 2
CGFloat
self.timeSlider.frame = CGRectMake(timeSliderX, timeSliderY, timeSliderW, timeSliderH);
    
CGFloat totalTimeLabelX = self.frame.size.width
CGFloat
CGFloat
CGFloat
self.totalTimeLabel.frame = CGRectMake(totalTimeLabelX, totalTimeLabelY, totalTimeLabelW, totalTimeLabelH);
    
CGFloat
CGFloat singerIconY = CGRectGetMaxY(self.timeSlider.frame) + margin;
CGFloat singerIconW = 50;
CGFloat
self.singerIcon.frame = CGRectMake(singerIconX, singerIconY, singerIconW, singerIconH);
    
CGFloat previousBtnX = CGRectGetMaxX(self.singerIcon.frame) + 25;
CGFloat
CGFloat previousBtnW = 50;
CGFloat
self.previousBtn.frame = CGRectMake(previousBtnX, previousBtnY, previousBtnW, previousBtnH);
    
CGFloat playBtnX = CGRectGetMaxX(self.previousBtn.frame) + 25;
CGFloat playBtnY = singerIconY - 5;
CGFloat playBtnW = 60;
CGFloat
self.playBtn.frame = CGRectMake(playBtnX, playBtnY, playBtnW, playBtnH);
    
CGFloat nextBtnX = CGRectGetMaxX(self.playBtn.frame) + 25;
CGFloat
CGFloat
CGFloat
self.nextBtn.frame = CGRectMake(nextBtnX, nextBtnY, nextBtnW, nextBtnH);
    
CGFloat typeBtnX = CGRectGetMaxX(self.nextBtn.frame) + 20;
CGFloat
CGFloat
CGFloat
self.typeBtn.frame = CGRectMake(typeBtnX, typeBtnY, typeBtnW, typeBtnH);
}
 
#pragma mark - setter 赋值&mvc思想
- (void)setMusic:(ZZMusic
{
_music
    
    
    [self setUpSingerIconData];
    
    
    [self setUpSliderData];
}
 
/**
 *  设置歌手图片数据
 */
- (void)setUpSingerIconData
{
    // 0.设置圆角
    self.singerIcon.image = [UIImage circleImageWithName:self.music.singerIcon borderWidth:2 borderColor:[UIColor skyBlueColor]];
    
#warning - 后期再补图片旋转
//    // 1.单位矩阵
//    self.singerIcon.transform = CGAffineTransformIdentity;
}
 
/**
 *  设置滑动条的数据
 */
- (void)setUpSliderData
{
    
double duration = [ZZAudioTool shareInstance].player.duration;
    
    
    self.totalTimeLabel.text = [NSString getMinuteSecondWithSecond:duration];
    
    // 2.设置slider的最大值
self.timeSlider.maximumValue
    
    // 3.重置slider的播放时间
self.timeSlider.value = 0;
}
 
- (void)dealloc
{
    //移除定时器
    [self.link removeFromRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
}
 
@end
 
 
//
//  ZZMusicsController.h
//  05-音乐播放器
//
//  Created by 周昭 on 2017/3/20.
//  Copyright © 2017年 ZZ. All rights reserved.
//
 
#import <UIKit/UIKit.h>
 
@interface ZZMusicsController : UIViewController
 
@end
 
 
//
//  ZZMusicsController.m
//  05-音乐播放器
//
//  Created by 周昭 on 2017/3/20.
//  Copyright © 2017年 ZZ. All rights reserved.
//
 
#import "ZZMusicsController.h"
#import "ZZMusic.h"
#import "ZZMusicCell.h"
#import "ZZAudioTool.h"
#import "MJExtension.h"
#import "ZZPlayerToolBar.h"
#import "NSString+ZZ.h"
#import "AppDelegate.h"
#import <AVFoundation/AVFoundation.h>
 
@interface  ZZMusicsController ()<UITableViewDelegate,UITableViewDataSource,AVAudioPlayerDelegate,ZZPlayerToolBarDelegate>
@property (nonatomic, strong) NSArray *musics;
@property (nonatomic, strong) AVAudioPlayer
@property (nonatomic, weak) UITableView *tableView;
@property (nonatomic, weak) UIImageView *imgView;
@property (nonatomic, weak) ZZPlayerToolBar *playToolBar;
/**
 *  当前播放的索引
 */
@property (nonatomic, assign) NSInteger musicIndex;
@end
 
@implementation
 
#pragma mark - 懒加载
- (NSArray
{
if (!_musics) {
        self.musics = [ZZMusic objectArrayWithFilename:@"Musics.plist"];
    }
    return _musics;
}
 
- (void)viewDidLoad {
    [super viewDidLoad];
    
    // 0.设置标题&背景
    [self setUpTitle];
    
    // 1.初始化tableView
    [self setUpTableView];
    
    // 2.初始化playerToolBar
    [self setUpPlayerToolBar];
    
    // 3.随机播放
    [self selectIndexPathWithRow:self.musicIndex];
    
    // 4.接收远程事件
    [self setUpRemovteEvent];
}
 
#pragma mark - setUp 初始化
- (void)setUpRemovteEvent
{
AppDelegate *)[UIApplication sharedApplication].delegate).removteBlock = ^(UIEvent
switch (event.subtype) {
            case UIEventSubtypeRemoteControlNextTrack:
self playNextMusic];
break;
            case UIEventSubtypeRemoteControlPreviousTrack:
self playPreviousMusic];
break;
            case UIEventSubtypeRemoteControlPause:
self pauseCurrentMusic];
break;
            case UIEventSubtypeRemoteControlPlay:
self playCurrentMusic];
break;
        }
    };
}
 
- (void)setUpPlayerToolBar
{
    ZZPlayerToolBar *playToolBar = [ZZPlayerToolBar playerToolBar];
    playToolBar.frame = CGRectMake(0, self.view.frame.size.height - 95,  self.view.frame.size.width, 95);
delegate = self;
self.view addSubview:playToolBar];
self.playToolBar
}
 
- (void)setUpTableView
{
    // 0.创建tableView
UITableView *tableView = [[UITableView alloc] init];
delegate = self;
dataSource = self;
tableFooterView = [[UIView alloc] init];
    
    // 1.设置背景
UIImageView *imgView = [[UIImageView alloc] init];
frame = self.view.frame;
image = [UIImage imageNamed:@"backgroundImage"];
backgroundView
    
    tableView.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height);
self.view addSubview:tableView];
self.tableView
}
 
- (void)setUpTitle
{
    // 0.设置标题
    self.title = NSLocalizedString(@"音乐播放器", nil);
}
 
#pragma mark - ZZPlayerToolBarDelegate
- (void)playerToolBar:(ZZPlayerToolBar *)playerToolBar didClickBtnWithType:(ZZPlayerToolBarButtonType)type
{
switch
        case ZZPlayerToolBarPreviousButtonType:
            [self playPreviousMusic];
break;
            
        case ZZPlayerToolBarNextButtonType:
self playNextMusic];
break;
            
        case ZZPlayerToolBarPlayButtonType:
self playCurrentMusic];
break;
            
        case ZZPlayerToolBarPauseButtonType:
            [self pauseCurrentMusic];
break;
            
        case ZZPlayerToolBarTypeButtonType:
self playStyleMusic];
break;
            
default:
break;
    }
}
 
/**
 *  播放上一首
 */
- (void)playPreviousMusic
{
if (self.musicIndex == 0) { // 第一首则回到最后一首
self.musicIndex = self.musics.count - 1;
else
self.musicIndex--;
    }
    
    [self selectIndexPathWithRow:self.musicIndex];
}
 
/**
 *  播放下一首
 */
- (void)playNextMusic
{
if (self.musicIndex == self.musics.count - 1) { // 最后一首
self.musicIndex = 0;
else
self.musicIndex++;
    }
    
    [self selectIndexPathWithRow:self.musicIndex];
}
 
/**
 *  播放
 */
- (void)playCurrentMusic
{
    [[ZZAudioTool shareInstance] play];
}
 
/**
 *  暂停
 */
- (void)pauseCurrentMusic
{
    [[ZZAudioTool shareInstance] pause];
}
 
/**
 *  更换播放模式
 */
- (void)playStyleMusic
{
    
}
 
- (void)selectIndexPathWithRow:(NSInteger)row
{
    // 0.取得当前选中
NSIndexPath *selectedPath = [self.tableView indexPathForSelectedRow];
 
    // 1.主动选中下一行
NSIndexPath *currentPath = [NSIndexPath indexPathForRow:row inSection:selectedPath.section];
    [self.tableView selectRowAtIndexPath:currentPath animated:YES scrollPosition:UITableViewScrollPositionTop];
    [self tableView:self.tableView didSelectRowAtIndexPath:currentPath];
    
    // 2.播放音乐
    [self playMusic];
}
 
/**
 *  播放音乐
 */
- (void)playMusic
{
    // 0.取出播放的歌曲
    ZZMusic *music = self.musics[self.musicIndex];
playing = YES;
 
    // 1.初始化播放器
    [[ZZAudioTool shareInstance] prepareToPlayWithMusic:music];
    
    // 2.设置代理
    [ZZAudioTool shareInstance].player.delegate = self;
    
    // 3.更改播放工具条数据
    self.playToolBar.music = self.musics[self.musicIndex];
    
    // 4.播放
    [[ZZAudioTool shareInstance] play];
}
 
#pragma mark - Table view data source
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return self.musics.count;
}
 
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath
{
    // 1.创建cell
ZZMusicCell *cell = [ZZMusicCell cellWithTableView:tableView];
    
    // 2.设置cell的数据
music = self.musics[indexPath.row];
    
return
}
 
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath
{
return 70;
}
 
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath
{
    // 0.取出要播放的音乐
ZZMusic *music = self.musics[indexPath.row];
if (music.playing == YES) return;
playing = YES;
    
    // 1.取得索引值
self.musicIndex = indexPath.row;
    
    // 2.播放音乐
    [self playMusic];
}
 
- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath
{
    // 0.停止音乐直接释放
ZZMusic *music = self.musics[indexPath.row];
playing = NO;
    [ZZAudioTool stopMusic:music.filename];
}
 
#pragma mark - AVAudioPlayerDelegate
- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag
{
if (!flag == YES) return;
    
    [self playNextMusic];
}
 
@end