简单实现基于IOS的音乐播放器,并且带有歌词,随播放自动滚动,实现效果如下:
技术分享
首先,需要建立一个解析歌词的类ZMPlrc,解析歌词主要就是把时间和对应的歌词分离出来,然后存储到数组中。
ZMPlrc.h
#import <Foundation/Foundation.h>
@interface ZMPlrc : NSObject
/**
时间
*/
@property (nonatomic,strong)NSMutableArray *timeArray;
/**
歌词
*/
@property (nonatomic,strong)NSMutableArray *wordArray;
/**
解析歌词
*/
- (void)parselrc;
@end
ZMPlrc.m
#import "ZMPlrc.h"
@implementation ZMPlrc
- (instancetype)init
{
self = [super init];
if (self) {
_timeArray = [NSMutableArray array];
_wordArray = [NSMutableArray array];
}
return self;
}
/**
歌词路径
*/
- (NSString *)getLrcPath{
return [[NSBundle mainBundle] pathForResource:@"梁静茹-偶阵雨" ofType:@"lrc"];
}
/**
解析歌词
*/
- (void)parselrc{
NSString *content = [NSString stringWithContentsOfFile:[self getLrcPath] encoding:NSUTF8StringEncoding error:nil];
NSArray *sepArray = [content componentsSeparatedByString:@"["];
for (int i = 5; i < sepArray.count; i ++) {
//有两个元素,一个是时间,一个是歌词
NSArray *arr = [sepArray[i] componentsSeparatedByString:@"]"];
//NSLog(@"%@",sepArray[i]);
[_timeArray addObject:arr[0]];
[_wordArray addObject:arr[1]];
}
//NSLog(@"%@",content);
}
@end
接着,在storyboard中添加必要的控件。
技术分享
最后,就可以在控制器中实现了ZMPViewController,在实现过程中,主要就是监听音频播放player的播放时间,跟之前解析好的每句歌词对应的时间进行处理。
ZMPViewController.h
#import <UIKit/UIKit.h>
@interface ZMPViewController : UIViewController
@property (weak, nonatomic) IBOutlet UITableView *lrcTableView;
@property (weak, nonatomic) IBOutlet UISlider *timeSlider;
@property (weak, nonatomic) IBOutlet UILabel *currentTimeLabel;
@property (weak, nonatomic) IBOutlet UILabel *totalTimeLabel;
@property (weak, nonatomic) IBOutlet UIButton *lastMusicBtnClick;
- (IBAction)playBtnClick:(UIButton *)sender;
- (IBAction)preMusicBtnClick:(id)sender;
- (IBAction)valueChange:(UISlider *)sender;
- (IBAction)nextMusicBtnClick:(id)sender;
@end
ZMPViewController.m
#import "ZMPViewController.h"
#import <AVFoundation/AVFoundation.h>
#import "ZMPlrc.h"
@interface ZMPViewController ()<UITableViewDataSource,UITableViewDelegate>{
//音乐播放器
AVAudioPlayer *player;
ZMPlrc *lrc;
NSInteger currentRow;
}
@end
@implementation ZMPViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[self initPlayer];
//侦听当前时间
[NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(updateTime) userInfo:nil repeats:YES];
lrc = [[ZMPlrc alloc] init];
[lrc parselrc];
[self.lrcTableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"CELL"];
[self.lrcTableView reloadData];
}
- (void)updateTime{
CGFloat currentTime = player.currentTime;
//
self.currentTimeLabel.text = [NSString stringWithFormat:@"%02d:%02d",(int)currentTime / 60, (int)currentTime % 60];
self.timeSlider.value = currentTime / player.duration;
for (int i = 0; i < lrc.timeArray.count; i ++) {
NSArray *arr = [lrc.timeArray[i] componentsSeparatedByString:@":"];
CGFloat compTime = [arr[0] integerValue]*60 + [arr[1] floatValue];
if (player.currentTime > compTime)
{
currentRow = i;
}
else
{
break;
}
}
[self.lrcTableView reloadData];
[self.lrcTableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:currentRow inSection:0] atScrollPosition:UITableViewScrollPositionMiddle animated:YES];
}
/**
初始化音乐播放器
*/
- (void)initPlayer{
//后台播放音频设置
AVAudioSession *session = [AVAudioSession sharedInstance];
[session setActive:YES error:nil];
[session setCategory:AVAudioSessionCategoryPlayback error:nil];
//让app支持接受远程控制事件
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
NSString *path = [[NSBundle mainBundle] pathForResource:@"梁静茹-偶阵雨" ofType:@"mp3"];
NSURL *url = [NSURL fileURLWithPath:path];
player = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil];
//声道 -1------左声道,1-----右声道
player.pan = 0;
//音量:0~1
player.volume = 1;
//单曲循环(负数表示单曲循环)
player.numberOfLoops = -1;
//速率(默认为1)
//player.enableRate = YES;
//player.rate = 1.0;
//总时间
CGFloat totalSeconds = player.duration;
self.totalTimeLabel.text = [NSString stringWithFormat:@"%02d:%02d",(int)totalSeconds / 60, (int)totalSeconds % 60];
//当前时间
player.currentTime;
#if 0
//播放
[player play];
//停止
[player stop];
//暂停
[player pause];
#endif
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)playBtnClick:(UIButton *)sender {
sender.selected = !sender.selected;
if (sender.selected) {
[player prepareToPlay];
[player play];
}else{
[player pause];
}
}
- (IBAction)preMusicBtnClick:(id)sender {
[self initPlayer];
}
- (IBAction)valueChange:(UISlider *)sender {
player.currentTime = player.duration * sender.value;
}
- (IBAction)nextMusicBtnClick:(id)sender {
[self initPlayer];
}
#pragma mark - TableViewDelegate
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return lrc.wordArray.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"CELL"];
if (indexPath.row == currentRow)
{
cell.textLabel.textColor = [UIColor redColor];
}
else
{
cell.textLabel.textColor = [UIColor blackColor];
}
cell.textLabel.textAlignment = NSTextAlignmentCenter;
cell.textLabel.font = [UIFont systemFontOfSize:15];
cell.textLabel.text = lrc.wordArray[indexPath.row];
return cell;
}
@end
需要音乐在程序进入后台后同样能够播放,那么在plist文件中,增加Required background modes设置item 0的value为App plays audio or streams audio/video using AirPlay
技术分享
并在控制器中,添加后台播放音频的设置
//后台播放音频设置
AVAudioSession *session = [AVAudioSession sharedInstance];
[session setActive:YES error:nil];
[session setCategory:AVAudioSessionCategoryPlayback error:nil];
//让app支持接受远程控制事件
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];