AVAudioPlayer实现音乐播放+歌词与播放进度同步

说明:.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]];
    }
}

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值