Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Iphone 如何从AVPlayer(不是AVAudioPlayer)获取持续时间?_Iphone_Objective C_Xcode_Streaming - Fatal编程技术网

Iphone 如何从AVPlayer(不是AVAudioPlayer)获取持续时间?

Iphone 如何从AVPlayer(不是AVAudioPlayer)获取持续时间?,iphone,objective-c,xcode,streaming,Iphone,Objective C,Xcode,Streaming,我想为我的AVPlayer制作一个UISlider(洗涤器)。但由于这不是一个AVAudioPlayer,它没有内置的持续时间。有没有关于如何创建快进、快退和播放进度滑块的建议 我在AVPlayer上阅读了文档,它有一个内置的seekToTime或seekToTime:tolerance before:tolerance after:。我真的不明白。这就是我的滑块的答案吗?AVPlayer还有addPeriodicTimeObserverForInterval:queue:usingBlock:

我想为我的AVPlayer制作一个UISlider(洗涤器)。但由于这不是一个AVAudioPlayer,它没有内置的持续时间。有没有关于如何创建快进、快退和播放进度滑块的建议

我在AVPlayer上阅读了文档,它有一个内置的seekToTime或seekToTime:tolerance before:tolerance after:。我真的不明白。这就是我的滑块的答案吗?AVPlayer还有addPeriodicTimeObserverForInterval:queue:usingBlock:,这是用来获取我的曲目的持续时间的吗?有人能给我一个如何实现这段代码的例子吗?我不喜欢苹果的文档。这似乎很难理解

self.player.currentItem.asset.duration

明白了

标题

#import <AVFoundation/AVPlayer.h>
#import <AVFoundation/AVPlayerItem.h>
#import <AVFoundation/AVAsset.h>
AVFoundation
CoreMedia
框架

#import <AVFoundation/AVPlayer.h>
#import <AVFoundation/AVPlayerItem.h>
#import <AVFoundation/AVAsset.h>
AVFoundation
CoreMedia

从iOS 4.3开始,您可以使用略短的:

self.player.currentItem.duration;
注明

您应该使用
player.currentItem.duration

- (CMTime)playerItemDuration
{
    AVPlayerItem *thePlayerItem = [player currentItem];
    if (thePlayerItem.status == AVPlayerItemStatusReadyToPlay)
    {        
        /* 
         NOTE:
         Because of the dynamic nature of HTTP Live Streaming Media, the best practice 
         for obtaining the duration of an AVPlayerItem object has changed in iOS 4.3. 
         Prior to iOS 4.3, you would obtain the duration of a player item by fetching 
         the value of the duration property of its associated AVAsset object. However, 
         note that for HTTP Live Streaming Media the duration of a player item during 
         any particular playback session may differ from the duration of its asset. For 
         this reason a new key-value observable duration property has been defined on 
         AVPlayerItem.

         See the AV Foundation Release Notes for iOS 4.3 for more information.
         */     

        return([playerItem duration]);
    }

    return(kCMTimeInvalid);
}

在本例中,avPlayer是avPlayer实例

我构建了一个视频控件,它使用以下功能:

要定位滑块,请使用类似的方法获取播放头在电影中的百分比,您需要反复启动此功能。所以我会像这样运行函数:

float scrubberBarLocation = (scrubberBgImageView.frame.size.width / 100.0f) * [self moviePercentage];


- (float)moviePercentage {

    CMTime t1 = [avPlayer currentTime];
    CMTime t2 = avPlayer.currentItem.asset.duration;

    float myCurrentTime = CMTimeGetSeconds(t1);
    float myDuration = CMTimeGetSeconds(t2);

    float percent = (myCurrentTime / myDuration)*100.0f;
    return percent;

}
然后,要更新视频,我会执行以下操作:

- (void)updateVideoPercent:(float)thisPercent {

    CMTime t2 = avPlayer.currentItem.asset.duration;
    float myDuration = CMTimeGetSeconds(t2);

    float result = myDuration * thisPercent /100.0f;

    //NSLog(@"this result = %f",result); // debug

    CMTime seekTime = CMTimeMake(result, 1);

    [avPlayer seekToTime:seekTime];

}

让Swift以秒为单位获取持续时间

if let duration = player.currentItem?.asset.duration {
    let seconds = CMTimeGetSeconds(duration)
    print("Seconds :: \(seconds)")
}

Swift 5

将此代码放入所需的某个函数中:

let duration = player.currentItem?.duration.seconds ?? 0
let playDuration = formatTime(seconds: duration) //Duration RESULT
创建一个名为:formatTime(秒:双精度)的函数

然后,使用另一个函数将秒转换为小时、分钟和秒。由于layerLayer.player?.currentItem?.duration.seconds显示的秒数将是长的两倍,因此需要使其成为人类可读的

func timeDivider(seconds: Double) -> (hours: Int, minutes: Int, seconds: Int) {
    guard !(seconds.isNaN || seconds.isInfinite) else {
        return (0,0,0)
    }
    let secs: Int = Int(seconds)
    let hours = secs / 3600
    let minutes = (secs % 3600) / 60
    let seconds = (secs % 3600) % 60
    return (hours, minutes, seconds)
}

希望这是你完整的答案

虽然这里的答案是正确的,但我认为值得补充的是,您可以要求
AVAsset
加载持续时间(或任何其他属性),并在加载后获得回调,以便访问该值。这是对许多评论的回应,
player.currentItem.asset.duration的值返回0.00,直到加载资产

它是这样使用的:

let asset = AVURLAsset(url: url)
asset.loadValuesAsynchronously(forKeys: ["duration"]) {
            
    var error: NSError? = nil
    let item: PlaylistItem
            
    // If the duration was loaded, construct a "normal" item,
    // otherwise construct an error item.
    switch asset.statusOfValue(forKey: "duration", error: &error) {
    case .loaded:
        item = PlaylistItem(url: url, title: title, artist: artist, duration: asset.duration)        
    case .failed where error != nil:
        item = PlaylistItem(title: title, artist: artist, error: error!) 
    default:
        let error = NSError(domain: NSCocoaErrorDomain, code: NSFileReadCorruptFileError)
        item = PlaylistItem(title: title, artist: artist, error: error)
    }           
}

这段代码来自Apple的示例代码。

哇,谢谢!令人沮丧的是,self.player.currentItem.duration为长视频编译浮点值:)的.CMTimeGetSeconds(以上代码)在某些情况下不起作用。返回0.00。知道吗?有时返回n在加载视频资源之前,该值为0.00有时返回n可能是可以接受的答案。仅调用
AVPlayerItem.duration
从未为我返回正确的值。使用
CMTimeGetSeconds
对我很有效。