在公司的项目中需要用到音频播放功能.刚开始做的比较简单.给个URL用AVplayer播放就能搞定了,后来版本迭代.要加入缓存功能.于是开始研究音频框架,在一周多的时间里研究了各种框架各有利弊,使用豆瓣的框架DOUAudioStreamer的使用遇到了个奇葩问题.当点下一曲的时候的会快速切换十几首歌.不知道是不是我的使用姿势不对.我们重点说FreeStreamer这个框架吧.
最基本的使用我就不再这里赘述了.说遇到的坑.第一个就是我们项目中也有用到科大讯飞的语音.和录音的功能这些东西都需要对AVAudioSession进行操作.在切换使用AVAudioSession的时候就会报[AVAudioSession setActive:withOptions:error:]: Deactivating an audio session that has running I/O. All I/O should be stopped or paused prior to deactivating the audio session. 这样的错误,这个错会导致音频在播放但是没有声音. 我的解决办法是搜索框架中所有的setActive:NO,把NO改成YES,这个问题就完美的解决了.
第二个坑就是当刚开始缓存但是没有出声音的时候这个时候调暂停的方法是没用的,即使调用了暂停的方法.但是音频还是会播放.我刚开始的解决办法是在监听FSAudioStreamState的kFsAudioStreamPlaying状态.在playFromURL:的时候设置了一个属性Buffering置为YES,在调用kFsAudioStreamPlaying的置为NO,这样在暂停方法里这样写
- (void)suspentFM { if (self.isSuspendFM==YES) return; if (self.Buffering ==YES) { [_audioStream stop]; }else { [_audioStream pause]; } self.isSuspendFM = YES; _suspentBtn.hidden = NO; }
就解决了这个问题.但是解决的并不完美.kFsAudioStreamPlaying这个状态会调用很多次.这样在少数情况下还是会有问题,具体情况已经忘了.于是乎我就放出了终极大招在定时器里监听进度
if ( progressView.progress<0.007) {
self.Buffering = YES;
}else {
self.Buffering = NO;
}
到这里才完美的解决这个问题
在接下来说使用小技巧吧.就是缓存的进度和播放的进度
FSStreamPosition cur = self.audioStream.currentTimePlayed; self.playbackTime =cur.playbackTimeInSeconds/1; self.ProgressView.progress = cur.position;//播放进度 self.progress = cur.position; float prebuffer = (float)self.audioStream.prebufferedByteCount; float contentlength = (float)self.audioStream.contentLength; if (contentlength>0) { self.ProgressView.cacheProgress = prebuffer /contentlength;//缓存进度 }
还有获取缓存的大小
- (CGFloat)cachesize { _audioStream = [[FSAudioStream alloc]init]; float totalCacheSize = 0; NSMutableArray *cachedFiles = [[NSMutableArray alloc] init]; for (NSString *file in [[NSFileManager defaultManager] contentsOfDirectoryAtPath:_audioStream.configuration.cacheDirectory error:nil]) { if ([file hasPrefix:@"FSCache-"]) { YKTCacheObject *cacheObj = [[YKTCacheObject alloc] init]; cacheObj.name = file; cacheObj.path = [NSString stringWithFormat:@"%@/%@", _audioStream.configuration.cacheDirectory, cacheObj.name]; cacheObj.attributes = [[NSFileManager defaultManager] attributesOfItemAtPath:cacheObj.path error:nil]; totalCacheSize += [cacheObj fileSize]; if (![cacheObj.name hasSuffix:@".metadata"]) { [cachedFiles addObject:cacheObj]; } } } return totalCacheSize/1000000; }