2011-10-07 119 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)); 
}