MusicHandle.h
// #import <Foundation/Foundation.h> // #import "MusicModel.h" / @interface MusicHandle : NSObject // 单例类 /+ (MusicHandle *)defaultHandle; // 添加一个 model对象 /- (void)addObjectWithModel:(MusicModel *)model; // 查询出有多少个 model /- (NSInteger)musicCount; // 根据 index找出 model /- (MusicModel *)modelWithIndex:(NSInteger)index; @end
MusicHandle.m
/#import "MusicHandle.h" @interface MusicHandle () @property (nonatomic, strong) NSMutableArray *dataArray; @end @implementation MusicHandle // 单例类 /+ (MusicHandle *)defaultHandle { static MusicHandle *musicHandel = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ if (musicHandel == nil) { musicHandel = [[MusicHandle alloc] init]; musicHandel.dataArray = [NSMutableArray array]; } }); return musicHandel; } // 添加一个 model对象 /- (void)addObjectWithModel:(MusicModel *)model { [self.dataArray addObject:model]; } // 查询出有多少个 model /- (NSInteger)musicCount { return self.dataArray.count; } // 根据 index 找出 model /- (MusicModel *)modelWithIndex:(NSInteger)index { return self.dataArray[index]; } @end
MusicModel.h
#import <Foundation/Foundation.h> @interface MusicModel : NSObject @property (nonatomic, copy) NSString *musicName; @property (nonatomic, copy) NSString *musicType; @end
MusicListViewController.h
//#import <UIKit/UIKit.h> @interface MusicPlayerViewController : UIViewController @property (nonatomic, assign) NSInteger musicIndex; @end
MusicListViewController.m
`
//#import "MusicListViewController.h"
//#import "MusicPlayerViewController.h"
//#import "LabelTableViewCell.h"
//#import "MusicModel.h"
//#import "MusicHandle.h"
//#define kColor arc4random() % 256 / 255.0
@interface MusicListViewController ()<UITableViewDataSource, UITableViewDelegate>
@property (nonatomic, strong) UITableView *tableView;
@end
@implementation MusicListViewController
//- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
self.tableView = [[UITableView alloc] initWithFrame:[UIScreen mainScreen].bounds style:(UITableViewStylePlain)];
self.tableView.dataSource = self;
self.tableView.delegate = self;
self.tableView.separatorColor = [UIColor redColor];
[self.tableView registerClass:[LabelTableViewCell class] forCellReuseIdentifier:@"cell_id"];
[self.view addSubview:self.tableView];
// 添加3首歌曲
MusicModel *model = [[MusicModel alloc] init];
model.musicName = @"情非得已";
model.musicType = @"mp3";
MusicModel *model1 = [[MusicModel alloc] init];
model1.musicName = @"林俊杰-背对背拥抱";
model1.musicType = @"mp3";
MusicModel *model2 = [[MusicModel alloc] init];
model2.musicName = @"梁静茹-偶阵雨";
model2.musicType = @"mp3";
[[MusicHandle defaultHandle] addObjectWithModel:model];
[[MusicHandle defaultHandle] addObjectWithModel:model1];
[[MusicHandle defaultHandle] addObjectWithModel:model2];
self.navigationItem.title = @"The Song List";
[self.navigationController.navigationBar setTitleTextAttributes:@{NSFontAttributeName:[UIFont systemFontOfSize:26], NSForegroundColorAttributeName:[UIColor whiteColor]}];
self.navigationController.navigationBar.barStyle = UIBarStyleBlackTranslucent;
}
//- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// Auto adjusting tableView's number of rows
return [[MusicHandle defaultHandle] musicCount];
}
//- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
LabelTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell_id" forIndexPath:indexPath];
cell.songLabel.font = [UIFont systemFontOfSize:21];
MusicModel *model = [[MusicHandle defaultHandle] modelWithIndex:indexPath.row];
cell.songLabel.text = model.musicName;
cell.backgroundColor = [UIColor colorWithRed:kColor green:kColor blue:kColor alpha:0.5];
return cell;
}
//- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
MusicPlayerViewController *musicPlayVC = [[UIStoryboard storyboardWithName:@"Main" bundle:[NSBundle mainBundle]] instantiateViewControllerWithIdentifier:@"musicPlayVC"];
musicPlayVC.musicIndex = indexPath.row;
[self.navigationController pushViewController:musicPlayVC animated:YES];
}
//- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
`
LabelTableViewCell.h
//#import <UIKit/UIKit.h> @interface LabelTableViewCell : UITableViewCell @property (nonatomic, strong) UILabel *songLabel; @end
LabelTableViewCell.m
//#import "LabelTableViewCell.h" @implementation LabelTableViewCell //- (void)awakeFromNib { // Initialization code } //- (void)setSelected:(BOOL)selected animated:(BOOL)animated { [super setSelected:selected animated:animated]; // Configure the view for the selected state } //- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) { self.songLabel = [[UILabel alloc] initWithFrame:CGRectZero]; self.songLabel.textAlignment = NSTextAlignmentCenter; [self.contentView addSubview:self.songLabel]; } return self; } //- (void)layoutSubviews { self.songLabel.frame = CGRectMake(0, 0, self.frame.size.width, self.frame.size.height); } @end
MusicPlayerViewController.h
//#import <UIKit/UIKit.h> @interface MusicPlayerViewController : UIViewController @property (nonatomic, assign) NSInteger musicIndex; @end
MusicPlayerViewController.m
`
//#import "MusicPlayerViewController.h"
//#import "MusicHandle.h"
//#import "MusicModel.h"
//#import <AVFoundation/AVFoundation.h>
@interface MusicPlayerViewController ()<UITableViewDataSource, UITableViewDelegate>
@property (weak, nonatomic) IBOutlet UITableView *tableView;
@property (weak, nonatomic) IBOutlet UISlider *volumnSlider;
@property (weak, nonatomic) IBOutlet UISlider *timeSlider;
@property (weak, nonatomic) IBOutlet UILabel *currentTiemLabel;
@property (weak, nonatomic) IBOutlet UILabel *timeLabel;
// 记录播放状态
@property (nonatomic, assign) BOOL isPlay;
// 音频播放器
@property (nonatomic, strong) AVAudioPlayer *audioPlayer;
// 定时器
@property (nonatomic, strong) NSTimer *timer;
@end
@implementation MusicPlayerViewController
//- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
// 导航栏标题
self.navigationItem.title = @"MusicPlayerViewController";
// 获取到一个需要播放的 model
MusicModel *model = [[MusicHandle defaultHandle] modelWithIndex:self.musicIndex];
// 获取音频的地址
NSString *pathString = [[NSBundle mainBundle] pathForResource:model.musicName ofType:model.musicType];
// 音频的 data
NSData *data = [NSData dataWithContentsOfFile:pathString];
// 根据音频的 data 创建一个 AVAudioPlayer对象
self.audioPlayer = [[AVAudioPlayer alloc] initWithData:data error:nil];
// 记录播放初始状态
self.isPlay = NO;
// 注册tableViewCell
[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"cell_id"];
// 让滑动条的值和音乐播放器的音量关联, 默认值为1(最大)
self.volumnSlider.value = self.audioPlayer.volume;
// 获取歌曲的持续时间
CGFloat time = self.audioPlayer.duration;
NSInteger minutes = (NSInteger)time / 60;
NSInteger seconds = (NSInteger)time % 60;
// 让右边label 的值置为歌曲的总时长
self.timeLabel.text = [NSString stringWithFormat:@"%02ld:%02ld", minutes, seconds];
// 设置控制音量的滑动条的渲染颜色
self.volumnSlider.minimumTrackTintColor = [UIColor blueColor];
self.volumnSlider.maximumTrackTintColor = [UIColor blueColor];
// 设置控制时间进度的滑动条的值为歌曲的时长
self.timeSlider.maximumValue = self.audioPlayer.duration;
// 设置控制时间的滑动条的渲染颜色
self.timeSlider.maximumTrackTintColor = [UIColor redColor];
// 让滑动条的进度与音乐的播放进度一致
self.timeSlider.value = self.audioPlayer.currentTime;
// 导航栏按钮
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Return" style:(UIBarButtonItemStyleDone) target:self action:@selector(barButtonItemClicked)];
}
// 点击按钮切回歌曲清单列表, 并暂停播放
//- (void)barButtonItemClicked {
[self.audioPlayer stop];
[self.navigationController popViewControllerAnimated:YES];
}
//- (void)timeChange {
// 显示时间进度
self.currentTiemLabel.text = [NSString stringWithFormat:@"%02ld:%02ld", (NSInteger)self.audioPlayer.currentTime / 60, (NSInteger)self.audioPlayer.currentTime % 60];
// 计算剩余时长
NSInteger surplus = self.audioPlayer.duration - self.audioPlayer.currentTime;
// 显示剩余时间
self.timeLabel.text = [NSString stringWithFormat:@"%02ld:%02ld", (NSInteger)surplus / 60, (NSInteger)surplus % 60];
// 让滑动条和音乐的播放进度关联
self.timeSlider.value = self.audioPlayer.currentTime;
// 如果 slider的 value和 audioPlayer 的 duration 相等则直接进入下一首歌
if (self.timeSlider.value >= self.audioPlayer.duration) {
[self nextMusic];
}
}
// 切到下一首
//- (void)nextMusic {
// 如果当前播放的音乐是播放列表中的最后一首
if (self.musicIndex == [[MusicHandle defaultHandle] musicCount] - 1) {
// 则切回第一首
self.musicIndex = 0;
} else {
// 否则播放下一首
self.musicIndex += 1;
}
// 获取到一个需要播放的 model
MusicModel *model = [[MusicHandle defaultHandle] modelWithIndex:self.musicIndex];
// 音频的地址
NSString *pathString = [[NSBundle mainBundle] pathForResource:model.musicName ofType:model.musicType];
// 音频的 data
NSData *data = [NSData dataWithContentsOfFile:pathString];
// 根据音频的 data 创建一个 AVAudioPlayer对象
self.audioPlayer = [[AVAudioPlayer alloc] initWithData:data error:nil];
// 播放
[self.audioPlayer play];
}
// 切到上一首
//- (void)lastMusic {
// 如果当前播放的音乐是第一首
if (self.musicIndex == 0) {
// 则播放音乐列表中的最后一首
self.musicIndex = [[MusicHandle defaultHandle] musicCount] - 1;
} else {
// 否则播放当前音乐的前一曲
self.musicIndex -= 1;
}
// 获取到一个需要播放的 model
MusicModel *model = [[MusicHandle defaultHandle] modelWithIndex:self.musicIndex];
// 音频的地址
NSString *pathString = [[NSBundle mainBundle] pathForResource:model.musicName ofType:model.musicType];
// 音频的 URL
// NSURL *url = [NSURL URLWithString:pathString];
// 音频的 data
NSData *data = [NSData dataWithContentsOfFile:pathString];
// 根据音频的 data 创建一个 AVAudioPlayer对象
self.audioPlayer = [[AVAudioPlayer alloc] initWithData:data error:nil];
// 播放
[self.audioPlayer play];
}
//- (IBAction)lastButtonClicked:(id)sender {
[self lastMusic];
}
//- (IBAction)playButtonClicked:(UIButton *)sender {
if (!_isPlay) {
// 让播放器播放音乐
[self.audioPlayer play];
// 记录播放状态
self.isPlay = YES;
// 改变 button 上的图片
[sender setImage:[UIImage imageNamed:@"pause"] forState:(UIControlStateNormal)];
// 播放的时候才创建 NSTimer
// NSTimer
// 第一个参数 : timer执行的时间
// 第二个参数 : target
// 第三个参数 : 方法选择
// 第四个参数 : 传递的值
// 第五个参数 : 是否重复
self.timer = [NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:@selector(timeChange) userInfo:nil repeats:YES];
// 启动计时器
[self.timer fire];
} else {
// 让音乐暂停
[self.audioPlayer pause];
// 改变播放状态
self.isPlay = NO;
// 改变 button 的图片
[sender setImage:[UIImage imageNamed:@"play"] forState:(UIControlStateNormal)];
// 移除 timer
[self.timer invalidate];
self.timer = nil;
}
}
//- (IBAction)nextButtonClicked:(id)sender {
[self nextMusic];
}
//- (IBAction)volumnSliderChange:(id)sender {
UISlider *slider = (UISlider *)sender;
// 用滑动条来控制当前播放器的音量
self.audioPlayer.volume = slider.value;
}
//- (IBAction)timeSliderChange:(UISlider *)sender {
UISlider *slider = (UISlider *)sender;
// 用滑动条来控制播放的进度
self.audioPlayer.currentTime = slider.value;
}
//- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 100;
}
//- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell_id" forIndexPath:indexPath];
return cell;
}
//- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
`