音频播放AVAudioPlayer

// LrcParser.h
#import <Foundation/Foundation.h>

@interface LRCParser : NSObject

/** 保存时间的数组 */
@property (nonatomic, strong) NSMutableArray *timeArray;
/** 保存歌词的数组 */
@property (nonatomic, strong) NSMutableArray *wordArray;

/**
 *  开始解析歌词
 */
- (void)startParseWithLrc:(NSString *)lrc;

@end

// LrcParser.m
#import "LRCParser.h"

@implementation LRCParser

#pragma mark - 懒加载

- (NSMutableArray *)timeArray {
    if (_timeArray == nil) {
        _timeArray = [[NSMutableArray alloc] init];
    }
    return _timeArray;
}

- (NSMutableArray *)wordArray {
    if (_wordArray == nil) {
        _wordArray = [[NSMutableArray alloc] init];
    }
    return _wordArray;
}

- (void)startParseWithLrc:(NSString *)lrc {
    [self.wordArray removeAllObjects];
    [self.timeArray removeAllObjects];
    int start;
    if ([lrc isEqualToString:@"林俊杰-背对背拥抱.lrc"]) {
        start = 1;
    } else if ([lrc isEqualToString:@"情非得已.lrc"]) {
        start = 3;
    } else if ([lrc isEqualToString:@"梁静茹-偶阵雨.lrc"]) {
        start = 5;
    }
    // 获取歌词内容
    NSString *content = [self contentFromLrc:lrc];
    // 1. 以‘[’进行分割
    NSArray *strArray = [content componentsSeparatedByString:@"["];
    
    for (int i = start; i < strArray.count; i++) {
        NSString *itemStr = strArray[i];
        // 2. 以']'进行分割
        NSArray *itmStrArray = [itemStr componentsSeparatedByString:@"]"];
        if (itmStrArray.count == 2) {
            [self.timeArray addObject:itmStrArray[0]];
            [self.wordArray addObject:itmStrArray[1]];
        }
    }
}

/**
 *  返回文件内容 NSString
 */
- (NSString *)contentFromLrc:(NSString *)lrc {
    NSString *path = [[NSBundle mainBundle] pathForResource:lrc ofType:nil];
    return [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];
}

@end


// ViewController.m

#import "ViewController.h"
#import <AVFoundation/AVFoundation.h>
#import "LRCParser.h"

@interface ViewController () <UITableViewDataSource,UITableViewDelegate>

#pragma mark - properties

/** 播放按钮 */
@property (weak, nonatomic) IBOutlet UIButton *playBtn;
/** 歌词解析器 */
@property (nonatomic, strong) LRCParser *lrcParser;
/** 用来显示歌词的tableView */
@property (weak, nonatomic) IBOutlet UITableView *tableView;
/** 进度 */
@property (weak, nonatomic) IBOutlet UISlider *slider;
/** 播放器 */
@property (nonatomic, strong)AVAudioPlayer *player;

/** 已播放时长 */
@property (weak, nonatomic) IBOutlet UILabel *timeLabel;
/** 总时长 */
@property (weak, nonatomic) IBOutlet UILabel *allLabel;
/** 当期播放的哪首 */
@property (nonatomic, assign) NSInteger currentIndex;
/** 更新定时器 */
@property (nonatomic, strong) NSTimer *updateTimer;
/** 总时间 */
@property (nonatomic, assign) NSTimeInterval totalSeconds;
/** MP3数组 */
@property (nonatomic, copy) NSArray *musics;
/** 当前歌词显示的行 */
@property (nonatomic, assign) NSInteger tableViewRow;

#pragma mark - methods

/** 播放进度指示条 */
- (IBAction)proSlider:(UISlider *)sender;
/** 上一首 */
- (IBAction)pre:(UIButton *)sender;
/** 播放*/
- (IBAction)play:(UIButton *)sender;
/** 下一首 */
- (IBAction)next:(UIButton *)sender;

@end

@implementation ViewController

#pragma mark - 懒加载

- (NSArray *)musics {
    if (_musics == nil) {
        _musics = @[@"情非得已.mp3",@"林俊杰-背对背拥抱.mp3",@"梁静茹-偶阵雨.mp3"];
    }
    return _musics;
}

- (AVAudioPlayer *)player {
    if (_player == nil) {
        NSURL *url = [self urlWithFileName:self.musics[_currentIndex]];
        _player = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil];
        // -1 左声道 0 双声道 1右声道
        _player.pan = 0;
        // 音量 0.0~1.0
        _player.volume = 1;
        // -1 表示单曲循环
        _player.numberOfLoops = -1;
        
        // 对应的歌词文件
        NSMutableString *musicName = [self.musics[_currentIndex] mutableCopy];
        [musicName replaceCharactersInRange:NSMakeRange(musicName.length-3, 3) withString:@"lrc"];
        
        [_lrcParser startParseWithLrc:musicName];
        [self.tableView reloadData];
        // 获取当前音频的总时间
        _totalSeconds = _player.duration;
        self.allLabel.text = [NSString stringWithFormat:@"%02d:%02d", (int)_totalSeconds / 60, (int)_totalSeconds % 60];
        /*
         // 当前时间
         [_player currentTime];
         // 总时间
         [_player duration];
         // 播放
         [_player play];
         // 停止
         [_player stop];
         // 播放
         [_player pause];
         // 音量
         _player.volume;
         // 循环次数
         _player.numberOfLoops;
         */
        
    }
    return _player;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    
    _updateTimer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(updateTimeAction:) userInfo:nil repeats:YES];
    // 歌词解析
    _lrcParser = [[LRCParser alloc] init];
    
    // 注册cell
    [self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"cell"];
    self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
}

/**
 *  更新当前显示的歌词 和 时间进度
 */
- (void)updateTimeAction:(NSTimer *)timer {
    // 01 获取当前时间
    NSTimeInterval currentSecond = self.player.currentTime;
    // 02 更新当前时间 00:00
    self.timeLabel.text = [NSString stringWithFormat:@"%02d:%02d", (int)currentSecond / 60, (int)currentSecond % 60];
    // 03 更新进度
    self.slider.value = (float)currentSecond/_totalSeconds;
    // 04 根据当前时间获取当前歌词行
    _tableViewRow = [self currentIndexPathRowWithCurrentSecond:currentSecond];
    // 05 刷新tableView
    [self.tableView reloadData];
    // 06 滚动到当前行
    NSIndexPath *currentIndexPath = [NSIndexPath indexPathForRow:_tableViewRow inSection:0];
    [self.tableView scrollToRowAtIndexPath:currentIndexPath atScrollPosition:UITableViewScrollPositionMiddle animated:YES];
}

/**
 * 获取当前行
 */
- (NSInteger)currentIndexPathRowWithCurrentSecond:(NSTimeInterval)currentSecond {
    __block NSInteger row = 0;
    // 遍历时间数组
    [_lrcParser.timeArray enumerateObjectsUsingBlock:^(NSString *obj, NSUInteger idx, BOOL *stop) {
        NSArray *timeStrArray = [obj componentsSeparatedByString:@":"];
        NSInteger minute = [timeStrArray[0] integerValue];
        float second = [timeStrArray[1] floatValue];
        NSTimeInterval compareSecond = minute * 60 + second;
        
        // 如果播放器里的当前时间大于 数组中的时间 就赋值
        if (currentSecond > compareSecond) {
            row = idx;
        } else {
            *stop = YES;
        }
    }];
    return row;
}

/**
 *   根据文件名返回url
 */
- (NSURL *)urlWithFileName:(NSString *)fileName {
    return [[NSBundle mainBundle] URLForResource:fileName withExtension:nil];
}

#pragma mark - actions

/**
 *  通过控制当前时间来控制进度
 */
- (IBAction)proSlider:(UISlider *)sender {
    self.player.currentTime = _totalSeconds * sender.value;
}

/**
 *  上一首
 */
- (IBAction)pre:(UIButton *)sender {
    if (_currentIndex == 0) {
        _currentIndex = self.musics.count-1;
    } else {
        _currentIndex--;
    }
    [self stopPlayer];
    [self.player prepareToPlay];
}

/**
 *  播放和暂停
 */
- (IBAction)play:(UIButton *)sender {
    sender.selected = !sender.selected;
    if (sender.selected) { // 被点击了 显示暂停 执行播放
        [self.player play];
        // 启动定时器 如果播放就启动定时器
        [_updateTimer setFireDate:[NSDate distantPast]];
        
    } else { // 被点击了 显示播放 执行暂停
        
        [self.player pause];
        // 暂停定时器 如果暂停就关闭定时器
        [_updateTimer setFireDate:[NSDate distantFuture]];
    }
}

/**
 *  下一首
 */
- (IBAction)next:(UIButton *)sender {
    if (_currentIndex == self.musics.count-1) {
        _currentIndex = 0;
    } else {
        _currentIndex++;
    }
    [self stopPlayer];
    [self.player prepareToPlay];
}

/**
 * 如果当前播放器正在播放则停止播放
 */
- (void)stopPlayer {
    // 如果当前的播放器正在播放
    if ([self.player isPlaying]) {
        // 停止播放
        [self.player stop];
    }
    self.player = nil;
    self.playBtn.selected = NO;
}

#pragma mark - UITableView 数据源方法

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return self.lrcParser.timeArray.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];
    cell.textLabel.textAlignment = NSTextAlignmentCenter;
    cell.textLabel.font = [UIFont systemFontOfSize:15.0f];
    cell.textLabel.text = [self.lrcParser.wordArray objectAtIndex:indexPath.row];
    cell.textLabel.textColor = [UIColor blackColor];
    
    if (indexPath.row == _tableViewRow) {
        cell.textLabel.textColor = [UIColor redColor];
    }
    cell.selectionStyle = UITableViewCellSelectionStyleNone;
    
    return cell;
}

@end

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值