说明:.lrc 歌词文件 + .mp3 音频文件
Demo
实现功能:
1.音乐播放/暂停
2.歌曲选择
3.播放进度,声音控制
4.歌词和播放进度同步
ViewController
import AVFoundation/AVFoundation.h
import “TQParserLrc.h”
@interface ViewController () UITableViewDataSource,UITableViewDelegate
- (IBAction)volumeChange:(id)sender;
- (IBAction)songChange:(id)sender;
- (IBAction)start:(id)sender;
@property (weak, nonatomic) IBOutlet UISlider *songSlider;
- (IBAction)preSong:(id)sender;
- (IBAction)nextSong:(id)sender;
@property (nonatomic,strong) NSTimer *timer;
@property (nonatomic,strong) AVAudioPlayer *audioPlayer;
@property (nonatomic,strong) NSArray *mp3PathArray;
@property (nonatomic,strong) NSArray *lrcPathArray;
@property (nonatomic) NSInteger currentMp3; //0
@property (nonatomic) NSInteger currentRow;
@property (nonatomic,strong) TQParserLrc *lrcObj;
@property (weak, nonatomic) IBOutlet UITableView *tableView;
@end
@implementation ViewController
-(void)initMp3:(NSString )mp3Path lrcPath:(NSString )lrcPath
{
self.audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:mp3Path] error:nil];
//准备播放
[self.audioPlayer prepareToPlay];
self.audioPlayer.volume = 0.5;
[self.lrcObj parserLrc:lrcPath];
//设置最大播放时间
self.songSlider.maximumValue = self.audioPlayer.duration;
// self.audioPlayer.enableRate = YES;
// //速率
// self.audioPlayer.rate = 2.0;
self.timer = [NSTimer scheduledTimerWithTimeInterval:0.1f target:self selector:@selector(timeChange:) userInfo:nil repeats:YES];
}
(void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@”cell”];
self.mp3PathArray = @[[[NSBundle mainBundle] pathForResource:@”梁静茹-偶阵雨” ofType:@”mp3”],[[NSBundle mainBundle] pathForResource:@”林俊杰-背对背拥抱” ofType:@”mp3”],[[NSBundle mainBundle] pathForResource:@”情非得已” ofType:@”mp3”]];
self.lrcPathArray = @[[[NSBundle mainBundle] pathForResource:@”梁静茹-偶阵雨” ofType:@”lrc”],[[NSBundle mainBundle] pathForResource:@”林俊杰-背对背拥抱” ofType:@”lrc”],[[NSBundle mainBundle] pathForResource:@”情非得已” ofType:@”lrc”]];
self.lrcObj = [[TQParserLrc alloc] init];
[self initMp3:self.mp3PathArray[self.currentMp3] lrcPath:self.lrcPathArray[self.currentMp3]];
}
(void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}(IBAction)volumeChange:(UISlider *)sender {
self.audioPlayer.volume = sender.value;
}(IBAction)songChange:(UISlider *)sender {
//
self.audioPlayer.currentTime = sender.value;
}
//self.audioPlayer.currentTime 30
-(void)timeChange:(NSTimer *)t
{
self.songSlider.value = self.audioPlayer.currentTime;
for ( NSInteger i = 0; i < self.lrcObj.timeArray.count; i++ ) {
NSString *timeString = self.lrcObj.timeArray[i];
NSArray *sepTime = [timeString componentsSeparatedByString:@":"];
CGFloat seconds = [sepTime[0] integerValue] * 60 + [sepTime[1] floatValue];
if( seconds <= self.audioPlayer.currentTime )
{
//保存前一个元素的下表
self.currentRow = i;
}
else
{
break;
}
}
[self.tableView reloadData];
[self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:self.currentRow inSection:0] atScrollPosition:UITableViewScrollPositionMiddle animated:YES];
}
(IBAction)start:(id)sender {
if(!self.audioPlayer.isPlaying)
{
[self.audioPlayer play];}
else
{
[self.audioPlayer pause];
//[self.timer invalidate];
}
}(IBAction)preSong:(id)sender {
[self.audioPlayer stop];
[self.timer invalidate];self.currentMp3–;
if (self.currentMp3 == -1) {
self.currentMp3 = self.mp3PathArray.count - 1;
}[self initMp3:self.mp3PathArray[self.currentMp3] lrcPath:self.lrcPathArray[self.currentMp3]];
[self.audioPlayer play];
}(IBAction)nextSong:(id)sender {
//
[self.audioPlayer stop];
[self.timer invalidate];self.currentMp3++;
if (self.currentMp3 == self.mp3PathArray.count) {
self.currentMp3 = 0;
}[self initMp3:self.mp3PathArray[self.currentMp3] lrcPath:self.lrcPathArray[self.currentMp3]];
[self.audioPlayer play];
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return self.lrcObj.lrcArray.count;
}
-(UITableViewCell )tableView:(UITableView )tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@”cell”];
cell.textLabel.text = self.lrcObj.lrcArray[indexPath.row];
cell.textLabel.textAlignment = NSTextAlignmentCenter;
if(self.currentRow == indexPath.row)
{
cell.textLabel.textColor = [UIColor purpleColor];
}
else
{
cell.textLabel.textColor = [UIColor blackColor];
}
return cell;
}
TQParserLrc
.h
@interface TQParserLrc : NSObject
@property (nonatomic,strong) NSMutableArray *timeArray;
@property (nonatomic,strong) NSMutableArray *lrcArray;
-(void)parserLrc:(NSString *)lrcPath;
@end
.m
@implementation TQParserLrc
(instancetype)init
{
self = [super init];
if (self) {
self.timeArray = [[NSMutableArray alloc] init];self.lrcArray = [[NSMutableArray alloc] init];
}
return self;
}
-(void)parserLrc:(NSString *)lrcPath
{
[self.lrcArray removeAllObjects];
[self.timeArray removeAllObjects];
NSString *lrcContent = [NSString stringWithContentsOfFile:lrcPath encoding:NSUTF8StringEncoding error:nil];
//@""
//time lrc
NSArray *sepArray = [lrcContent componentsSeparatedByString:@"["];
//00:02.07]偶阵雨 - 梁静茹 ---> sepString
for (NSString *sepString in sepArray) {
NSArray *array = [sepString componentsSeparatedByString:@"]"];
if(!([array[0] isEqualToString:@""] || [array[1] isEqualToString:@"\n"] || [array[1] isEqualToString:@"\r\n"]))
{
[self.timeArray addObject:array[0]];
[self.lrcArray addObject:array[1]];
}
}
}