iOS之音频

来源:互联网 发布:软件前端和后端 编辑:程序博客网 时间:2024/06/03 02:57

iOS中一共有四种专门实现播放音频的方式

1、System Sound Services (系统声音服务)

2、OpenAL (跨平台的开源的音频处理接口)

3、Audio Queue Services (播放和录制音频服务)

4、AVAudioPlayer (高级音频播放器)

System Sound Services 

System Sound Services 是最底层也是最简单的声音播放服务,通过调用AudioServicesPlaySystemSound 这个函数就可以播放一些简单的音频文件

使用场景:播放一些很小的提示或警告音

局限性:1、声音的长度要小于30秒

               2、格式:IMA4

              3、不能控制播放的进度

              4、调用方法后立即播放声音

              5、没有循环播放和立体声音播放

OpenAL

OpenAL是一套跨平台的开源的音频处理接口

最适合开发游戏的视频

OpenAL包含三个实体:Listener(听者) Source(音源)Buffer(缓存)

开发步骤:

1、获取device

2、将context关联到device

3、将数据放在buffer

4、将buffer链接到一个source

5、播放source

Audio Queue Services

Audio Queue Services 主要用来实现录制音频,为了简化音频文件的处理,通常还需要使用到AudioFileServices  
AVAudioPlayer

支持的音频格式:AAC、AMR、ALAC、iLBC、IMA4、LinearPCM、MP3

优势:1、支持更多的格式 2、可以播放任意长度的音频文件 3、支持循环播放 4、可以同步播放多个音频文件 5、控制播放进度以及从音频的任意一点开始播放

使用AVAudioPlayer的第一步就是引入系统类库

#import <AVFoundation/AVFoundation.h>
第二步:初始化AVAudioPlayer对象

第三步:设置属性

第四步:设置预播放、播放、暂停、停止等方法

第五步:代理方法

- (void)viewDidLoad {    [super viewDidLoad];    // Do any additional setup after loading the view from its nib.//    初始化    self.timeArray = [NSMutableArray new];    self.lyricsDictionary = [NSMutableDictionary new];    //    经分析:具体播放哪首歌曲,需要上个界面传过来//    获取当前音乐的model类    MusicModel *model = [MusicDataManager shareInstence].musicArray[self.playIndex];    //    初始化音乐播放器对象    NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:model.musicName ofType:model.musicType]];        audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil];    //    设置音量【最小值,最大值】    self.volumnSlider.minimumValue = 0;    self.volumnSlider.maximumValue = 1;    //    设置播放器默认的音量    audioPlayer.volume = 0;    self.volumnSlider.value = audioPlayer.volume;//    [self.volumnSlider addTarget:self action:@selector(sliderAction:) forControlEvents:UIControlEventTouchUpInside];        //    设置音量按钮的图片    [self.volumnSlider setThumbImage:[UIImage imageNamed:@"soundSlider"] forState:UIControlStateNormal];    //    高亮状态    [self.volumnSlider setThumbImage:[UIImage imageNamed:@"soundSlider"] forState:UIControlStateHighlighted];    //    设置进度按钮的图片    self.progressSlider.value = 0;    [self.progressSlider setThumbImage:[UIImage imageNamed:@"sliderThumb_small"] forState:UIControlStateNormal];    [self.progressSlider setThumbImage:[UIImage imageNamed:@"sliderThumb_small"] forState:UIControlStateHighlighted];    //    获取歌词    [self getLyrics];    //    设置代理    self.showLyricsTableView.delegate = self;    self.showLyricsTableView.dataSource = self;    //    设置定时器,0.1秒之后刷新,播放时间的刷新,如果本首歌曲播放完毕,是否进去下一首    [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(showTime) userInfo:nil repeats:YES];    }#pragma mark - 定时刷新所有的数据- (void)showTime {//    刷新进度条的数据    if ((int)audioPlayer.currentTime % 60 < 10) {        self.startTimeLabel.text = [NSString stringWithFormat:@"%d:0%d", (int)audioPlayer.currentTime / 60, (int)audioPlayer.currentTime % 60];    } else {        self.startTimeLabel.text = [NSString stringWithFormat:@"%d:%d", (int)audioPlayer.currentTime / 60, (int)audioPlayer.currentTime % 60];    }        if ((int)audioPlayer.duration % 60 < 10) {        self.endTimeLabel.text = [NSString stringWithFormat:@"%d:0%d", (int)audioPlayer.duration / 60, (int)audioPlayer.duration % 60];    } else {        self.endTimeLabel.text = [NSString stringWithFormat:@"%d:%d",(int)audioPlayer.duration / 60, (int)audioPlayer.duration % 60];    }    //    设置slider的Value值    self.progressSlider.value = audioPlayer.currentTime / audioPlayer.duration;    //    动态显示歌词    [self displaySoundWord:audioPlayer.currentTime];    //    在播放完毕之后,自动播放下一首    if (self.progressSlider.value > 0.99) {//        自动播放        [self autoPlay];    }}#pragma mark - 自动播放- (void)autoPlay {//    判断    if (self.playIndex == [MusicDataManager shareInstence].musicArray.count - 1) {        self.playIndex = -1;    }    self.playIndex++;    [self updatePlayerSetting];}#pragma mark - 动态显示歌词- (void)displaySoundWord:(NSUInteger)time {    for (int i = 0; i < _timeArray.count; i++) {        NSArray *array = [self.timeArray[i] componentsSeparatedByString:@":"];//        把数组中存在的时间,转换成秒        NSUInteger currentTime = [array[0] intValue] * 60 + [array[1] intValue];        if (i == self.timeArray.count - 1) {//            求出最后一句歌词的时间点            NSArray *array1 = [self.timeArray[self.timeArray.count - 1] componentsSeparatedByString:@":"];            NSUInteger currentTime1 = [array1[0] intValue] * 60 + [array1[1] intValue];            if (time > currentTime1) {//                刷新歌词界面                [self updateLyricsTableView:i];                break;            }        } else {            //求出第一句的时间点,在第一句显示前的时间内一直加载第一句            NSArray *array2 = [self.timeArray[0] componentsSeparatedByString:@":"];            NSUInteger currentTime2 = [array2[0] intValue] * 60 + [array2[1] intValue];            if (time < currentTime2) {                [self updateLyricsTableView:0];                //NSLog(@"马上到第一句");                break;            }            //求出下一步的歌词时间点,然后计算区间            NSArray *array3 = [self.timeArray[i+1] componentsSeparatedByString:@":"];            NSUInteger currentTime3 = [array3[0] intValue] * 60 + [array3[1] intValue];            if (time >= currentTime && time <= currentTime3) {                //动态更新歌词表中的歌词                [self updateLyricsTableView:i];                break;            }        }    }}#pragma mark - 动态更新歌词- (void)updateLyricsTableView:(NSInteger)index {//    重载tableView的    [self.showLyricsTableView reloadData];//    如果被选中某一行,移动到相关的位置    NSIndexPath *indexPath = [NSIndexPath indexPathForRow:index inSection:0];    [self.showLyricsTableView selectRowAtIndexPath:indexPath animated:YES scrollPosition:UITableViewScrollPositionMiddle];}#pragma mark - 控制音量//- (void)sliderAction:(UISlider *)sender {//    audioPlayer.volume = self.volumnSlider.value;//}- (IBAction)volumnChange:(UISlider *)sender {    audioPlayer.volume = self.volumnSlider.value;}#pragma mark - 改变进度的- (IBAction)progressChange:(UISlider *)sender {    audioPlayer.currentTime = self.progressSlider.value * audioPlayer.duration;}#pragma mark - 获取歌词- (void)getLyrics {//   获取音乐model    MusicModel *model = [MusicDataManager shareInstence].musicArray[self.playIndex];    NSString *lyricsPath = [[NSBundle mainBundle] pathForResource:model.musicName ofType:@"lrc"];//    编码    NSString *lyricsUTF8 = [NSString stringWithContentsOfFile:lyricsPath encoding:NSUTF8StringEncoding error:nil];//    以/n分割,最后使用数组存取//    NSArray *array = [lyricsUTF8 componentsSeparatedByString:@"\n"];//    for (int i = 0; i < array.count; i++) {////        获取每一行的内容//        NSString *lineStr = array[i];////        NSLog(@"%@", lineStr);//        NSArray *lineArray = [lineStr componentsSeparatedByString:@"]"];////        NSLog(@"%@", lineArray);//        NSLog(@"%@",lineArray[0]);////        NSLog(@"%@",lineArray[1]);////        NSLog(@"%@", lineArray[2]);////        如果长度大于8的时候才进行歌词的操作////        有歌词没歌词的判断//        if (lineArray.count > 1) {////           取出:和.,然后根据他们进行判断//            if ([[lineArray[0] substringWithRange:NSMakeRange(6, 1)] isEqualToString:@"."]) {//        //            NSArray *array1 = [lineArray[0] componentsSeparatedByString:@"."];//            NSLog(@"%@", array1[1]);//            NSLog(@"%@", array1);//            if ([array1[1] length] == 2) {//                NSArray *array = [array1[0] componentsSeparatedByString:@"["];////                NSLog(@"==========%@", lineArray[1]);//                //                [self.lyricsDictionary setObject:lineArray[1] forKey:array[1]];//            }//            }//        }//    }//    NSLog(@"====%@", self.lyricsDictionary);////    //    self.timeArray = [self.lyricsDictionary allKeys].mutableCopy;//    //将字符串切割成数组    NSArray *array = [lyricsUTF8 componentsSeparatedByString:@"\n"];    for (int i = 0; i < array.count; i++) {        NSString *linStr = [array objectAtIndex:i];        NSArray *lineArray = [linStr componentsSeparatedByString:@"]"];                //有的有歌词没时间        if (lineArray.count > 1) {            //取出:和.进行比较            NSString *str1 = [linStr substringWithRange:NSMakeRange(3, 1)];            NSString *str2 = [linStr substringWithRange:NSMakeRange(6, 1)];            if ([str1 isEqualToString:@":"] && [str2 isEqualToString:@"."]) {                //歌词                NSString *lrcStr = [lineArray objectAtIndex:1];                //时间                NSString *timeStr = [lineArray[0] substringWithRange:NSMakeRange(1, 5)];                [self.timeArray addObject:timeStr];                [self.lyricsDictionary setObject:lrcStr forKey:timeStr];                            }        }            }}#pragma mark - 播放按钮的响应方法- (IBAction)playButtonAction:(UIButton *)sender {//    判断是否正在播放修改相关的内容    if (!isPlay) {        [audioPlayer play];        [self.playButotn setImage:[UIImage imageNamed:@"c"] forState:UIControlStateNormal];        isPlay = YES;    } else {        [audioPlayer pause];        [self.playButotn setImage:[UIImage imageNamed:@"play"] forState:UIControlStateNormal];        isPlay = NO;    }}#pragma mark - 上一首的响应方法- (IBAction)backButotnAction:(UIButton *)sender {    if (self.playIndex == 0) {        self.playIndex = [MusicDataManager shareInstence].musicArray.count;    }    self.playIndex--;    [self updatePlayerSetting];}#pragma mark - 更新播放器的设置- (void)updatePlayerSetting {//    更改播放按钮的状态    [self.playButotn setBackgroundImage:[UIImage imageNamed:@"c"] forState:UIControlStateNormal];    isPlay = YES;//    获取播放的音乐对象    MusicModel *model = [MusicDataManager shareInstence].musicArray[self.playIndex];//    更新曲目    NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:model.musicName ofType:@"mp3"]];    audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil];//    音量的重置    audioPlayer.volume = self.volumnSlider.value;//    歌词的更新    self.timeArray = [NSMutableArray array];    self.lyricsDictionary = [NSMutableDictionary dictionary];    [self getLyrics];        [audioPlayer play];}#pragma mark - 下一首的响应方法- (IBAction)nextButtonAction:(UIButton *)sender {    if (self.playIndex == [MusicDataManager shareInstence].musicArray.count - 1) {        self.playIndex = -1;    }    self.playIndex++;    [self updatePlayerSetting];}- (void)didReceiveMemoryWarning {    [super didReceiveMemoryWarning];    // Dispose of any resources that can be recreated.}#pragma mark - TableView的代理方法- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {    return self.timeArray.count;}- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"musicLyricCell"];    if (cell == nil) {        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"musicLyricCell"];          }//    cell.textLabel.text = self.timeArray[indexPath.row];//    设置选中的样式    cell.selectionStyle = UITableViewCellSelectionStyleNone;    cell.backgroundColor = [UIColor clearColor];    cell.textLabel.text = [self.lyricsDictionary objectForKey:self.timeArray[indexPath.row]];    cell.textLabel.font = [UIFont systemFontOfSize:13];    cell.textLabel.textAlignment = NSTextAlignmentCenter;    return cell;}




0 0
原创粉丝点击