简体   繁体   English

iOS - 如何获得AVPlayer的可播放持续时间

[英]iOS - How can i get the playable duration of AVPlayer

The MPMoviePlayerController has a property called playableDuration. MPMoviePlayerController有一个名为playableDuration的属性。

playableDuration The amount of currently playable content (read-only). playableDuration当前可播放内容的数量(只读)。

@property (nonatomic, readonly) NSTimeInterval playableDuration @property(nonatomic,readonly)NSTimeInterval playableDuration

For progressively downloaded network content, this property reflects the amount of content that can be played now. 对于逐步下载的网络内容,此属性反映了现在可以播放的内容量。

Is there something similar for AVPlayer? AVPlayer有类似的东西吗? I can't find anything in the Apple Docs or Google (not even here at Stackoverflow.com) 我在Apple Docs或Google中找不到任何内容(甚至不在Stackoverflow.com)

Thanks in advance. 提前致谢。

playableDuration can be roughly implemented by following procedure: 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 is your AVPlayer instance, by checking AVPlayerItem's loadedTimeRanges, you can compute a estimated playableDuration. _moviePlayer是您的AVPlayer实例,通过检查AVPlayerItem的loadedTimeRanges,您可以计算估计的playableDuration。

For videos that has only 1 secion, you can use this procedure; 对于只有1秒的视频,您可以使用此程序; but for multi-section video, you may want to check all time ranges in array of loadedTimeRagnes to get correct answer. 但对于多节视频,您可能需要检查loadedTimeRagnes数组中的所有时间范围以获得正确的答案。

all you need is 所有你需要的是

self.player.currentItem.asset.duration

simply best 最好的

Building on John's Answer… 以约翰的答案为基础......

This is the apparent default behavior of Apple players: "Show the Max Time of the playable range that encloses the current time" 这是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));
}

} }

You will have to detect when the AVPlayer is ready to play your media file. 您必须检测AVPlayer何时准备好播放您的媒体文件。 Let me know, if you don't know how to do this. 如果您不知道该怎么做,请告诉我。

However, once the media file is loaded, you can use this method: 但是,一旦加载了媒体文件,您就可以使用此方法:

#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);
}

When you use this method its important to understand (because you're streaming content) that the length value may be invalid or something. 当您使用此方法时,了解(因为您是流内容)重要的是长度值可能无效或其他。 So you must check this before using it for processing. 所以在使用它进行处理之前必须先检查一下。

CMTime playerDuration = [self playerItemDuration];
if (CMTIME_IS_INVALID(playerDuration)) {
    return;
}
double duration = CMTimeGetSeconds(playerDuration);

Swift version of closes playable duration: 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
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM