【问题标题】:iOS Determine Number of Frames in VideoiOS 确定视频中的帧数
【发布时间】:2015-04-08 05:10:23
【问题描述】:

如果我在 Swift 中有 MPMoviePlayerController:

MPMoviePlayerController mp = MPMoviePlayerController(contentURL: url)

有没有办法可以获取位于url 的视频中的帧数?如果没有,是否有其他方法来确定帧数?

【问题讨论】:

    标签: ios swift video mpmovieplayercontroller video-processing


    【解决方案1】:

    我不认为MPMoviePlayerController 可以帮助你。

    使用AVAssetReader 并计算它返回给您的CMSampleBuffers 的数量。您可以将其配置为甚至不解码帧,从而有效地解析文件,因此它应该是快速且内存高效的。

    类似

        var asset = AVURLAsset(URL: url, options: nil)
        var reader = AVAssetReader(asset: asset, error: nil)
        var videoTrack = asset.tracksWithMediaType(AVMediaTypeVideo)[0] as! AVAssetTrack
    
        var readerOutput = AVAssetReaderTrackOutput(track: videoTrack, outputSettings: nil) // NB: nil, should give you raw frames
        reader.addOutput(readerOutput)
        reader.startReading()
    
        var nFrames = 0
    
        while true {
            var sampleBuffer = readerOutput.copyNextSampleBuffer()
            if sampleBuffer == nil {
                break
            }
    
            nFrames++
        }
    
        println("Num frames: \(nFrames)")
    

    对不起,如果这不是惯用的,我不知道 swift。

    【讨论】:

    • 太棒了!你有什么简单的例子可以展示吗?这将是最有帮助的。
    【解决方案2】:

    斯威夫特 5

     func getNumberOfFrames(url: URL) -> Int {
            let asset = AVURLAsset(url: url, options: nil)
            do {
                let reader = try AVAssetReader(asset: asset)
            //AVAssetReader(asset: asset, error: nil)
                let videoTrack = asset.tracks(withMediaType: AVMediaType.video)[0]
    
                let readerOutput = AVAssetReaderTrackOutput(track: videoTrack, outputSettings: nil) // NB: nil, should give you raw frames
                reader.add(readerOutput)
            reader.startReading()
    
            var nFrames = 0
    
            while true {
                let sampleBuffer = readerOutput.copyNextSampleBuffer()
                if sampleBuffer == nil {
                    break
                }
    
                nFrames = nFrames+1
            }
    
            print("Num frames: \(nFrames)")
                return nFrames
            }catch {
                print("Error: \(error)")
            }
            return 0
        }
    

    【讨论】:

    • 请务必进行设置,否则您可能会得到错误的数字。 let readerSettings = [String(kCVPixelBufferPixelFormatTypeKey): Int(kCVPixelFormatType_32BGRA)] 会做
    【解决方案3】:

    您还可以使用每秒帧数来计算总帧数。

    var player: AVPlayer?
    var playerController = AVPlayerViewController()
    var videoFPS: Int = 0
    var totalFrames: Int?
    
    
    guard let videoURL = "" else { return }
    player = AVPlayer(url: videoURL)
    playerController.player = player
    guard player?.currentItem?.asset != nil else {
        return
    }
    let asset = self.player?.currentItem?.asset
    let tracks = asset!.tracks(withMediaType: .video)
    let fps = tracks.first?.nominalFrameRate
    let duration = self.player?.currentItem?.duration
    
    self.videoFPS = lround(Double(fps!))
    self.totalFrames = lround(Double(self!.videoFPS) * durationSeconds)
    

    【讨论】:

    • 如果视频以可变帧速率编码,此解决方案将给出估计值,而不是确切值。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-04
    相关资源
    最近更新 更多