取得播放毫秒数

时间:2018-09-27 18:08:26

标签: swift swift3

已经完成了大部分工作,但在这一部分仍然很困难。

我想获得播放毫秒数。有了这段代码。我得到了durationcurrent playing time。但是我也希望毫秒数成为我的字幕应用程序的一部分。

好的,所以我们从秒开始。这段代码给了我我想要的:

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 the millisecond here aswell?

        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
        self.statics.text = "Current time: \(formatTimeFor(seconds: playhead)) ---> Full: \(formatTimeFor(seconds: duration))"

    }
}

谢谢。非常感谢您的帮助

更新

当前检查播放时间的方法是让计时器每0.5秒触发一次功能。像这样:

func scheduledTimerWithTimeInterval(){
    // Scheduling timer to Call the function "updateCounting" with the interval of 1 seconds
    timer = Timer.scheduledTimer(timeInterval: 0.5, target: self, selector: #selector(self.updateCounting), userInfo: nil, repeats: true)
}

旁注。我确实以某种方式得到了毫秒:

let millisecondsInt =  (seconds.truncatingRemainder(dividingBy: 1) * 1000)

问题是。每 0.5 秒,就会触发update_time()功能。这给了我腐败的信息。例如。如果我想在00:16:267处加上字幕,则由于数字是随机的,因此有10%的机会运行代码。

我认为这段代码在某种程度上是不正确的,我想让counter以此方式完成工作:

Current time: 00:14:266 ---> Full: 04:12:610
Current time: 00:14:267 ---> Full: 04:12:610 // 267 milliseconds +1
Current time: 00:14:268 ---> Full: 04:12:610
Current time: 00:14:269 ---> Full: 04:12:610
Current time: 00:14:270 ---> Full: 04:12:610
Current time: 00:14:271 ---> Full: 04:12:610
Current time: 00:14:272 ---> Full: 04:12:610

不是这种随机数跳转方式:

Current time: 00:13:767 ---> Full: 04:12:610
Current time: 00:14:267 ---> Full: 04:12:610
Current time: 00:14:767 ---> Full: 04:12:610
Current time: 00:15:266 ---> Full: 04:12:610
Current time: 00:15:767 ---> Full: 04:12:610
Current time: 00:16:267 ---> Full: 04:12:610
Current time: 00:16:767 ---> Full: 04:12:610

2 个答案:

答案 0 :(得分:2)

我认为您的主要问题是,如何在特定时间从avplayer获得回调,以便添加正确的字幕。

对于这个问题,我找到了addBoundaryTimeObserver

我没有对此进行测试,但是看起来您可以添加字幕的开始时间(可能还有结束时间),并在回调中添加addSubtitle(或类似功能)函数。

下面是一些代码示例:

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    let videoURL = NSURL(string: "https://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4")
    let player = AVPlayer(url: videoURL! as URL)
    let controller = AVPlayerViewController()
    controller.player = player

    present(controller, animated: true) {
        player.play()
    }
    var times = [NSValue]()

    let smallValue1 = 2.0
    let frameTime1 = CMTime(seconds: smallValue1, preferredTimescale: 1000000)
    times.append(frameTime1 as NSValue)

    let smallValue2 = 4.0
    let frameTime2 = CMTime(seconds: smallValue2, preferredTimescale: 1000000)
    times.append(frameTime2 as NSValue)

    var timeObserverToken = player.addBoundaryTimeObserver(forTimes: times, queue: DispatchQueue.main, using: {
            [weak self] in
            print("time observer callback")
            // do your thing here
    })
}

答案 1 :(得分:2)

您的代码可以正常工作。它每0.5秒给出一次时间,以毫秒为单位为500。看14:267-13:767 = 0:500。如果要每1毫秒实现工作代码,则必须使用

运行代码
Timer.scheduledTimer(timeInterval: 0.001, target: self, selector: #selector(self.updateCounting), userInfo: nil, repeats: true)

但是我认为那不行。因为每1毫秒调用一次函数不是一个好主意。