Получите воспроизведение миллисекунд - PullRequest
0 голосов
/ 27 сентября 2018

Надеюсь, большая часть работы уже выполнена, но в этой части все еще идет борьба.

Я хочу получить миллисекунды воспроизведения.С этим кодом.я получаю duration и current 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 голосов
/ 09 октября 2018

Ваш код работает нормально.каждые 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 миллисекунду не очень хорошая идея.

0 голосов
/ 02 октября 2018

Я думаю, что ваш главный вопрос в том, как я могу получить обратный вызов от 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
    })
}
...