如何在AVPlayer中获取当前播放时间和总播放时间?

88

在 AVPlayer 中是否可以获取播放时间和总播放时间?如果可以,如何实现?

10个回答

179
你可以使用currentItem属性来访问当前播放的项目:
AVPlayerItem *currentItem = yourAVPlayer.currentItem;

那么您可以轻松地获取所需的时间值

CMTime duration = currentItem.duration; //total time
CMTime currentTime = currentItem.currentTime; //playing time

Swift 5:

if let currentItem = player.currentItem {
    let duration = CMTimeGetSeconds(currentItem.duration)
    let currentTime = CMTimeGetSeconds(currentItem.currentTime())

    print("Duration: \(duration) s")
    print("Current time: \(currentTime) s")
}

16
还有一种方便的方法CMTimeGetSeconds可以获取NSTimeInterval: NSTimeInterval duration = CMTimeGetSeconds(currentItem.duration); NSTimeInterval currentTime = CMTimeGetSeconds(currentItem.currentTime); - slamor
我不得不在主队列中调用它,才能返回正确的值(或者您的AVPlayer正在运行的任何队列)。 - Pnar Sbi Wer
1
如何将此属性赋给标签? - Mr. Bond
1
我正在从URL播放歌曲。但是在CMTime持续时间和CMTime当前时间,我得到了0。这里的问题是什么导致了0值?有人知道解决方案吗? - Moxarth
NSTimeInterval duration3 = CMTimeGetSeconds(currentItem.duration); NSTimeInterval currentTime3 = CMTimeGetSeconds(currentItem.currentTime);NSLog(@"%f 和 %f",duration3,currentTime3);self.playbackSlider.value = currentTime3/duration3; - Genevios
为什么 currentTime().seconds 有时候会比 duration 大?我找不到答案,每次当资源播放完毕(我每半秒取一次 currentTime)都会发生这种情况:currentTime: 19.50039306 of 20.0 -> currentTime: 20.0002372 of 20.0 -> currentTime: 20.000558334 of 20.0 - JastinBall

24
_audioPlayer = [self playerWithAudio:_audio];
_observer =
[_audioPlayer addPeriodicTimeObserverForInterval:CMTimeMake(1, 2)
                                           queue:dispatch_get_main_queue()
                                      usingBlock:^(CMTime time)
                                      {
                                          _progress = CMTimeGetSeconds(time);
                                      }];

22

Swift 3

let currentTime:Double = player.currentItem.currentTime().seconds

通过访问 currentTime()seconds 属性,您可以获取当前时间的秒数。这将返回一个代表时间秒数的 Double 类型。然后,您可以使用此值构建可读的时间以呈现给用户。

首先,包含一个方法来返回您将向用户显示的 H:mm:ss 时间变量:

func getHoursMinutesSecondsFrom(seconds: Double) -> (hours: Int, minutes: Int, seconds: Int) {
    let secs = Int(seconds)
    let hours = secs / 3600
    let minutes = (secs % 3600) / 60
    let seconds = (secs % 3600) % 60
    return (hours, minutes, seconds)
}

接下来,一个将上述检索到的值转换为可读字符串的方法:


func formatTimeFor(seconds: Double) -> String {
    let result = getHoursMinutesSecondsFrom(seconds: seconds)
    let hoursString = "\(result.hours)"
    var minutesString = "\(result.minutes)"
    if minutesString.characters.count == 1 {
        minutesString = "0\(result.minutes)"
    }
    var secondsString = "\(result.seconds)"
    if secondsString.characters.count == 1 {
        secondsString = "0\(result.seconds)"
    }
    var time = "\(hoursString):"
    if result.hours >= 1 {
        time.append("\(minutesString):\(secondsString)")
    }
    else {
        time = "\(minutesString):\(secondsString)"
    }
    return time
}

现在,使用之前的计算结果更新用户界面:

func updateTime() {
    // Access current item
    if let currentItem = player.currentItem {
        // Get the current time in seconds
        let playhead = currentItem.currentTime().seconds
        let duration = currentItem.duration.seconds
        // Format seconds for human readable string
        playheadLabel.text = formatTimeFor(seconds: playhead)
        durationLabel.text = formatTimeFor(seconds: duration)
    }
}

在player中是否有一个返回毫秒的属性? - bibscy

16

Swift 4

    self.playerItem = AVPlayerItem(url: videoUrl!)
    self.player = AVPlayer(playerItem: self.playerItem)

    self.player?.addPeriodicTimeObserver(forInterval: CMTimeMakeWithSeconds(1, 1), queue: DispatchQueue.main, using: { (time) in
        if self.player!.currentItem?.status == .readyToPlay {
            let currentTime = CMTimeGetSeconds(self.player!.currentTime())

            let secs = Int(currentTime)
            self.timeLabel.text = NSString(format: "%02d:%02d", secs/60, secs%60) as String//"\(secs/60):\(secs%60)"

    })
}

16

使用 Swift 4.2,使用以下代码:


let currentPlayer = AVPlayer()
if let currentItem = currentPlayer.currentItem {
    let duration = currentItem.asset.duration
}
let currentTime = currentPlayer.currentTime()

我尝试使用AVPlayer.currentTime(),但是没有成功,出现了bad access错误。 - KavyaKavita
currentPlayer.currentItem.currentTime()- 您将获得正确的时间。 - Dolly Vaish
这个答案是100%正确的,但如果你没有使用AVAsset来初始化播放器,你必须使用:*player?.currentItem?.duration。最好使用一个AVAsset。 - Lance Samaria
有人可以提供一个完整的 SwiftUI 使用示例吗? - Aiyush
@ Aiyush,你需要在SwiftUI中使用VideoPlayer。 - Kemal Can Kaynak
@KemalCanKaynak 我遇到了困难。我该如何使用VideoPlayer获取当前时间,例如如果视频的当前时间为10秒,则打印“Hello”或显示一些文本等等...我真的非常感激 :) - Aiyush

6

Swift 5: 如果你想要一个平滑的进度条,Timer.scheduledTimer似乎比addPeriodicTimeObserver更好

static public var currenTime = 0.0
static public var currenTimeString = "00:00"

        Timer.scheduledTimer(withTimeInterval: 1/60, repeats: true) { timer in

            if self.player!.currentItem?.status == .readyToPlay {

                let timeElapsed = CMTimeGetSeconds(self.player!.currentTime())
                let secs = Int(timeElapsed)
                self.currenTime = timeElapsed
                self.currenTimeString = NSString(format: "%02d:%02d", secs/60, secs%60) as String


                print("AudioPlayer TIME UPDATE: \(self.currenTime)    \(self.currenTimeString)")
            }
        }

真的,你必须要让进度条平滑地从一个点到另一个点进行动画处理 - 这并不容易。你肯定永远不会使用1/60的计时器(无论出于何种原因)- 只需使用CADisplayLink即可。 - Fattie

5
     AVPlayerItem *currentItem = player.currentItem;
     NSTimeInterval currentTime = CMTimeGetSeconds(currentItem.currentTime);
     NSLog(@" Capturing Time :%f ",currentTime);

我正在从URL播放歌曲。但是在CMTime持续时间和CMTime当前时间,我得到了0。这里的问题是什么导致了0值?有人知道解决方案吗? - Moxarth

5

Swift:

let currentItem = yourAVPlayer.currentItem

let duration = currentItem.asset.duration
var currentTime = currentItem.asset.currentTime

1

Swift 4.2:

let currentItem = yourAVPlayer.currentItem
let duration = currentItem.asset.duration
let currentTime = currentItem.currentTime()

1

在Swift 5+中

您可以直接查询播放器以查找正在播放的AVPlayerItem的当前时间。 时间存储在CMTime结构体中,便于转换为各种比例,例如十分之一秒、百分之一秒等。 在大多数情况下,我们需要以秒为单位表示时间,因此以下内容将向您展示所需内容。

let currentTimeInSecs = CMTimeGetSeconds(player.currentTime())

2
增加了 :) 希望这有所帮助。 - Umar Cheema
您介意提供一个在SwiftUI中完整实现的示例吗?这将非常感激! :) - Aiyush
这超出了上述问题的范围,但是这里有一个不错的教程,你可能会觉得有帮助:https://www.letsbuildthatapp.com/course_video?id=282 - Umar Cheema

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接