9

MPMoviePlayerController 有一个名为 playableDuration 的属性。

playableDuration当前可播放内容的数量(只读)。

@property(非原子,只读)NSTimeInterval playableDuration

对于逐步下载的网络内容,该属性反映了现在可以播放的内容量。

AVPlayer 有类似的东西吗?我在 Apple Docs 或 Google 中找不到任何东西(甚至在 Stackoverflow.com 上也找不到)

提前致谢。

4

5 回答 5

17

playableDuration 大致可以通过以下过程实现:

- (NSTimeInterval) playableDuration
{
//  use loadedTimeRanges to compute playableDuration.
AVPlayerItem * item = _moviePlayer.currentItem;

if (item.status == AVPlayerItemStatusReadyToPlay) {
    NSArray * timeRangeArray = item.loadedTimeRanges;

    CMTimeRange aTimeRange = [[timeRangeArray objectAtIndex:0] CMTimeRangeValue];

    double startTime = CMTimeGetSeconds(aTimeRange.start);
    double loadedDuration = CMTimeGetSeconds(aTimeRange.duration);

    // FIXME: shoule we sum up all sections to have a total playable duration,
    // or we just use first section as whole?

    NSLog(@"get time range, its start is %f seconds, its duration is %f seconds.", startTime, loadedDuration);


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

_moviePlayer 是您的AVPlayer 实例,通过检查AVPlayerItem 的loadedTimeRanges,您可以计算出估计的playableDuration。

对于只有 1 个部分的视频,您可以使用此过程;但对于多节视频,您可能需要检查loadedTimeRagnes 数组中的所有时间范围以获得正确答案。

于 2012-09-04T09:37:26.840 回答
7

所有你需要的是

self.player.currentItem.asset.duration

简直是最好的

于 2014-11-26T07:41:45.333 回答
4

以约翰的回答为基础……</p>

这是Apple播放器明显的默认行为:“显示包含当前时间的可播放范围的最大时间”

- (NSTimeInterval)currentItemPlayableDuration{

//  use loadedTimeRanges to compute playableDuration.
AVPlayerItem * item = self.audioPlayer.currentItem;

if (item.status == AVPlayerItemStatusReadyToPlay) {
    NSArray * timeRangeArray = item.loadedTimeRanges;

    CMTime currentTime = self.audioPlayer.currentTime;

    __block CMTimeRange aTimeRange;

    [timeRangeArray enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {

       aTimeRange = [[timeRangeArray objectAtIndex:0] CMTimeRangeValue];

        if(CMTimeRangeContainsTime(aTimeRange, currentTime))
            *stop = YES;

    }];

    CMTime maxTime = CMTimeRangeGetEnd(aTimeRange);

    return CMTimeGetSeconds(maxTime);
}
else
{
    return(CMTimeGetSeconds(kCMTimeInvalid));
}

}

于 2013-08-29T19:48:37.490 回答
2

您必须检测 AVPlayer 何时准备好播放您的媒体文件。让我知道,如果你不知道该怎么做。

但是,一旦加载了媒体文件,您就可以使用以下方法:

#import <AVFoundation/AVFoundation.h>

/**
 * Get the duration for the currently set AVPlayer's item. 
 */
- (CMTime)playerItemDuration {
    AVPlayerItem *playerItem = [mPlayer currentItem];
    if (playerItem.status == AVPlayerItemStatusReadyToPlay) {
        return [[playerItem asset] duration];
    }
    return(kCMTimeInvalid);
}

当您使用此方法时,重要的是要了解(因为您正在流式传输内容)长度值可能无效或其他原因。因此,您必须在使用它进行处理之前检查这一点。

CMTime playerDuration = [self playerItemDuration];
if (CMTIME_IS_INVALID(playerDuration)) {
    return;
}
double duration = CMTimeGetSeconds(playerDuration);
于 2011-08-05T15:57:00.583 回答
1

Swift 版本关闭可播放持续时间:

var playableDuration: TimeInterval? {
    guard let currentItem = currentItem else { return nil }
    guard currentItem.status == .readyToPlay else { return nil }

    let timeRangeArray = currentItem.loadedTimeRanges
    let currentTime = self.currentTime()

    for value in timeRangeArray {
        let timeRange = value.timeRangeValue
        if CMTimeRangeContainsTime(timeRange, currentTime) {
            return CMTimeGetSeconds(CMTimeRangeGetEnd(timeRange))
        }
    }

    guard let timeRange = timeRangeArray.first?.timeRangeValue else { return 0}

    let startTime = CMTimeGetSeconds(timeRange.start)
    let loadedDuration = CMTimeGetSeconds(timeRange.duration)
    return startTime + loadedDuration
}
于 2017-09-01T11:14:43.907 回答