DOUAudioStreamer设置currentTime无效

关于DOUAudioStreamer

DOUAudioStreamer是基于豆瓣团队Core Audio实现的用于iOS/Mac的开源流媒体播放引擎。代码托管地址:https://github.com/douban/DOUAudioStreamer

示例Demo

1、官方有个demo:https://github.com/douban/DOUAudioStreamer/tree/master/example/DOUASDemo
2、另一个功能比较完善的demo:https://github.com/Aufree/ESTMusicPlayer

遇到的问题

因为需求问题,我需要在初始化DOUAudioStreamer对象时,就去设置currentTime属性:

_streamer = [DOUAudioStreamer streamerWithAudioFile:track];
_streamer.currentTime = 10.0; 
[_streamer play];

然而,这并不像我们相信那样,从10s的时候开始播放。

猥琐的解决办法

当然如果你正常的播放音频文件,然后拖动滑动条从某个时间点开始播放是没有问题的,完全正常。也就是说streamer在play之前有个加载音频文件的缓冲时间。所以想到一个比较猥琐的办法,

_streamer = [DOUAudioStreamer streamerWithAudioFile:track];
[_streamer play];
[NSThread sleepForTimeInterval:0.5];
_audioStreamer.currentTime = 10.0;

嗯,貌似草草的解决了。

如果看过demo的知道,demo里会有几个KVO的方法,其中有一个是监听 updateSliderValue方法,监听_audioStreamer当前播放进度。

- (void)removeStreamerObserver {
[_audioStreamer removeObserver:self forKeyPath:@"status"];
[_audioStreamer removeObserver:self forKeyPath:@"duration"];
[_audioStreamer removeObserver:self forKeyPath:@"bufferingRatio"];
}

- (void)addStreamerObserver {
[_audioStreamer addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:kStatusKVOKey];
[_audioStreamer addObserver:self forKeyPath:@"duration" options:NSKeyValueObservingOptionNew context:kDurationKVOKey];
[_audioStreamer addObserver:self forKeyPath:@"bufferingRatio" options:NSKeyValueObservingOptionNew context:kBufferingRatioKVOKey];
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
if (context == kStatusKVOKey) {
[self performSelector:@selector(updateStatus)
onThread:[NSThread mainThread]
withObject:nil
waitUntilDone:NO];
} else if (context == kDurationKVOKey) {
[self performSelector:@selector(updateSliderValue:)
onThread:[NSThread mainThread]
withObject:nil
waitUntilDone:NO];
} else if (context == kBufferingRatioKVOKey) {
[self performSelector:@selector(updateBufferingStatus)
onThread:[NSThread mainThread]
withObject:nil
waitUntilDone:NO];
} else {
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
}
}

所以又意淫出另外一个方法,如果 self.audioStreamer.currentTime < 10, 我就设置 self.audioStreamer.currentTime = 10;,

初始化

_streamer = [DOUAudioStreamer streamerWithAudioFile:track];
[_streamer play];

然后,在updateSliderValue方法里做判断

 if (self.audioStreamer.currentTime<10)
 {
      self.audioStreamer.currentTime = 10;
 }

后记

当然遇到这样问题,也去Github上提交了issue(https://github.com/douban/DOUAudioStreamer/issues/102),但是一直没有回复,也没有精力去研究源码,改一改,也没用那水平,所以就这样解决了。

也想过找另外类似的播放引擎,确实找打一个StreamingKit:https://github.com/tumtumtum/StreamingKit
确实也简单易用,但是和DOUAudioStreamer存在同样的问题,最终还是选择了DOUAudioStreamer。