音樂播放器的簡單使用:
<1>AVAudioPlayer使用簡單方便,但只能播放本地音頻,不支持網絡連接的播放.
<2>AVPlayer可以播放本地音頻也支持網絡播放以及視屏播放,但是提供接口較少,處理音頻不夠靈活.
使用它們都需要導入系統(tǒng)的AVFoundation框架
今天介紹一下AVAudioPlayer的使用
它的使用非常簡單直接獲取本地音樂路徑
NSString *path = [[NSBundle mainBundle] pathForResource:@"本地音樂的名字" ofType:@"后綴"];
NSURL *url = [NSURL fileURLWithPath:path];
AVAudioPlayer *player = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil];
[player play];
這樣就可以播放了
但是如果添加上暫停 上一曲 下一曲 歌詞 功能 就不能這么簡單了由于代碼有點多直接上代碼了 每一次播放都會創(chuàng)建新的player, 再把上一次的清掉, 并且, 承載音樂播放的VC也不能多次創(chuàng)建
先創(chuàng)建一個Model對象存放本地音樂的數據
Model.h
#import <Foundation/Foundation.h>
@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
還要創(chuàng)建管理音樂數據的類
#import <Foundation/Foundation.h>
@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 <Foundation/Foundation.h>
@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 <AVFoundation/AVFoundation.h>
@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創(chuàng)建播放器
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]) {
// 如果當前沒處于播放狀態(tài), 那么就播放
[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不存在, 那么就創(chuàng)建
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 <Foundation/Foundation.h>
@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
給創(chuàng)建View的frame寫的類目(這個可以不要)
#import <UIKit/UIKit.h>
@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 <UIKit/UIKit.h>
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 ------------ 創(chuàng)建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 () <UITableViewDelegate, UITableViewDataSource>
@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 <UIKit/UIKit.h>
@interface VCOfPlayer : UIViewController
- (void)show;
@end
播放頁面的.m
#import "VCOfPlayer.h"
#import <AVFoundation/AVFoundation.h>
#import "PlayView.h"
#import "ModelOfMusic.h"
#import "UIView+Frame.h"
#import "WHMusicTool.h"
#import "WHAudioTool.h"
#import "LrcParser.h"
@interface VCOfPlayer () <UITableViewDelegate, UITableViewDataSource>
// 歌手的圖片
@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的隱藏能節(jié)省一些性能
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
額 有點亂. 不過仔細屢屢就明白了!!!