ios - 使用 Swift AVPlayer 显示视频轨道的时间码

标签 ios swift avfoundation avplayer timecodes

我正在开发一个用于导航和播放视频的小应用程序,其中包括帧率 和初始时间码 信息(例如:"TimeCode": "09:25 :15:08")。我正在使用 AVKit Player View Controller 来显示我的视频,我想添加一个显示当前时间码的 UILabel。

我已准备好添加自定义 UI 元素的方法,但我不知道如何计算 timecode 并使其在视频播放的每一帧更新。

我已经阅读了 AVFoundation - Timecode Support with AVAssetWriter and AVAssetReader ,但我不确定我是否理解了它。

任何解释、指导或要查看的内容都将不胜感激。

更新:

经过一段时间的思考,我认为我可以使用帧计数来建立我自己的时间码引用。

注意 item 是 AVPlayer

使用 var totalTime = CMTimeGetSeconds(item.currentItem.asset.duration)我可以获得视频轨道的总长度(以秒为单位),并且 currentTime = CMTimeGetSeconds(item.currentItem.currentTime ())获取其当前时间位置。

然后我可以执行 var fps = item.currentItem.asset.tracks[0].nominalFrameRate 获取帧率并使用此变量划分 totalTimecurrentTime获取总帧数以及当前帧。

有了这个,我正在考虑从总帧数中为每个帧建立一个以秒为单位的预归一化时间数组的想法。这样我就可以知道什么确切的帧与时间戳相关。

我从来不需要处理时间码或日期,所以如果有人知道如何做到这一点,我将不胜感激。

基本上,时间码看起来像这样:HH:MM:SS:FF(FF 是当前帧)。 如果fps = 24,则每秒每24帧添加到SS中,依此类推。

测试用例:

import UIKit
import AVKit
import AVFoundation

class ViewController: UIViewController {
    var player = AVPlayer()

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        var url=NSURL(string: "http://km.support.apple.com/library/APPLE/APPLECARE_ALLGEOS/HT1211/sample_iTunes.mov")
        player = AVPlayer(URL: url)
        let playerController = AVPlayerViewController()

        playerController.player = player
        self.addChildViewController(playerController)
        self.view.addSubview(playerController.view)
        playerController.view.frame = self.view.frame

        //Debug btn
        var btn = UIButton()
        btn.frame = CGRect(x:10, y:50, width:100, height:30)
        btn.setTitle("FPS", forState: .Normal)
        btn.addTarget(self, action: "buttonTapAction:", forControlEvents: UIControlEvents.TouchUpInside)
        playerController.view.addSubview(btn)

        player.play()
//        getFps(player)
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    func getFps(item:AVPlayer) {
        var fps = item.currentItem.asset.tracks[0].nominalFrameRate
        println("FPS: \(fps)")

        var timeRange_src = CMTimeGetSeconds(item.currentItem.asset.duration)
        var timeRange = Float(timeRange_src)
        println("time Range: \(timeRange)")
        var frameCount = timeRange * fps
        println("total frames: \(frameCount)")

        var timeIs = Float(CMTimeGetSeconds(item.currentItem.currentTime()))
        var frameIs = timeIs * fps
        println("current time: \(timeIs)")
        println("current frame: \(frameIs)")

    }

    func buttonTapAction(sender:UIButton!)
    {
        getFps(player)
    }


}

最佳答案

这是我最近用 Swift 3 做的:

func formatTimecode(frame: Int, fps: Double) -> String {
    let FF = Int(Double(frame).truncatingRemainder(dividingBy: fps))
    let seconds = Int(Double(frame - FF) / fps)
    let SS = seconds % 60
    let MM = (seconds % 3600) / 60
    let HH = seconds / 3600

    let timecode = [String(format: "%02d", HH), String(format: "%02d", MM), String(format: "%02d", SS), String(format: "%02d", FF)];

    return timecode.joined(separator: ":")
}

关于ios - 使用 Swift AVPlayer 显示视频轨道的时间码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31149502/

相关文章:

ios - swift - 限制同一 VC 中两个不同文本字段上的文本字符

ios - iOS app开发,是否可以检测相机是否拍过照片?

ios - snapchat 是如何实现设置下拉菜单的?

ios6 - AVAssetWriter finishWritingWithCompletionHandler 错误与未知错误

ios - 标签栏重叠 View 后面

swift - 两个 NSDate 的计算差异是错误的 - 已修复

ios - 如何正确地将 UITextField 添加到 UITableViewCell

iphone - 使用 AVFoundation 捕获视频不会捕获任何音频

ios - 在 iOS 上混合视频流

iphone - 在 loadView 中访问 self.view.frame 导致 EXC_BAD_ACCESS 崩溃