2011-10-07 109 views
30

我成功使用AVPlayer传输来自服务器的音频,而现在我想要做的是显示一个显示缓冲进度的自定义UISliderAVPlayer流式传输进度

事情是这样的:

enter image description here

随着AVPlayer似乎有不被一种方式来获得总下载大小或音频文件的当前下载量,仅当前播放时间和总播放时间。

这有什么解决方法吗?

+3

的代码你有没有实现这个UI部分?我需要这个,如果已经有东西出现,我宁愿不要推出自己的产品。 –

+3

查看这个问题的UI部分的最佳答案:http://stackoverflow.com/questions/4495433/uislider-with-progressview-combined – Form

+1

实现上述UI的简单解决方案是简单地将UIProgressBar放在UISlider下面,设置滑块的'maximumTrackTintColor'为'[UIColor clearColor]'。 – inorganik

回答

51

我只是在做这个,到目前为止,有以下几点:

- (NSTimeInterval) availableDuration; 
{ 
    NSArray *loadedTimeRanges = [[self.player currentItem] loadedTimeRanges]; 
    CMTimeRange timeRange = [[loadedTimeRanges objectAtIndex:0] CMTimeRangeValue]; 
    Float64 startSeconds = CMTimeGetSeconds(timeRange.start); 
    Float64 durationSeconds = CMTimeGetSeconds(timeRange.duration); 
    NSTimeInterval result = startSeconds + durationSeconds; 
    return result; 
} 
+0

要添加到此,您正在查找的值是AVPlayerItem属性loadedtimeRanges。它是一个包含CMTimeRange的NSValue的NSArray。这个代码块是我遇到麻烦的时候,也就是如何将这些数据转化为有用的东西。 –

+0

你为什么第一次,而不是最后? [loadedTimeRanges lastObject] – HotJard

+0

我记得我写过一个函数来观察它的行为,并且总是只看到数组中的一个元素,所以这可能是第一次或最后一次采取的模拟/随机操作。更理论上的“正确”计算是使用这个数组,并根据最大开始时间和持续时间找到最大持续时间,但在实践中并非必要。 –

8

它应该很好地工作:

的Objective-C:

- (CMTime)availableDuration 
{ 
    NSValue *range = self.player.currentItem.loadedTimeRanges.firstObject; 
    if (range != nil){ 
     return CMTimeRangeGetEnd(range.CMTimeRangeValue); 
    } 
    return kCMTimeZero; 
} 

斯威夫特版本:

func availableDuration() -> CMTime 
{ 
    if let range = self.player?.currentItem?.loadedTimeRanges.first { 
     return CMTimeRangeGetEnd(range.timeRangeValue) 
    } 
    return kCMTimeZero 
} 

要观看当前时间值,您可以使用: CMTimeShow([self availableDuration]); CMTimeShow(availableDuration())(对于SWIFT)

0

此方法将返回缓冲时间间隔为您UISlider

public var bufferAvail: NSTimeInterval { 

    // Check if there is a player instance 
    if ((player.currentItem) != nil) { 

     // Get current AVPlayerItem 
     var item: AVPlayerItem = player.currentItem 
     if (item.status == AVPlayerItemStatus.ReadyToPlay) { 

      var timeRangeArray: NSArray = item.loadedTimeRanges 
      var aTimeRange: CMTimeRange = timeRangeArray.objectAtIndex(0).CMTimeRangeValue 
      var startTime = CMTimeGetSeconds(aTimeRange.start) 
      var loadedDuration = CMTimeGetSeconds(aTimeRange.duration) 

      return (NSTimeInterval)(startTime + loadedDuration); 
     } 
     else { 
      return(CMTimeGetSeconds(kCMTimeInvalid)) 
     } 
    } 
    else { 
     return(CMTimeGetSeconds(kCMTimeInvalid)) 
    } 
} 
+0

您能否再解释一下代码的作用以及它如何解决OP的问题?在目前的格式中,阅读起来有点困难 – Draken

0

选择的答案可能会导致你的问题,如果返回的数组空。这里有一个固定的功能:

- (NSTimeInterval) availableDuration 
{ 
    NSArray *loadedTimeRanges = [[_player currentItem] loadedTimeRanges]; 
    if ([loadedTimeRanges count]) 
    { 
     CMTimeRange timeRange = [[loadedTimeRanges objectAtIndex:0] CMTimeRangeValue]; 
     Float64 startSeconds = CMTimeGetSeconds(timeRange.start); 
     Float64 durationSeconds = CMTimeGetSeconds(timeRange.duration); 
     NSTimeInterval result = startSeconds + durationSeconds; 
     return result; 
    } 
    return 0; 
} 
0

从苏雷什Kansujiya目标C

NSTimeInterval bufferAvail; 

if (player.currentItem != nil) { 

    AVPlayerItem *item = player.currentItem; 
    if (item.status == AVPlayerStatusReadyToPlay) { 
     NSArray *timeRangeArray = item.loadedTimeRanges; 
     CMTimeRange aTimeRange = [[timeRangeArray objectAtIndex:0] CMTimeRangeValue]; 
     Float64 startTime = CMTimeGetSeconds(aTimeRange.start); 
     Float64 loadedDuration = CMTimeGetSeconds(aTimeRange.duration); 

     bufferAvail = startTime + loadedDuration; 

     NSLog(@"%@ - %f", [self class], bufferAvail); 
    } else { 
     NSLog(@"%@ - %f", [self class], CMTimeGetSeconds(kCMTimeInvalid)); } 
} 
else { 
    NSLog(@"%@ - %f", [self class], CMTimeGetSeconds(kCMTimeInvalid)); 
}