iOS определяет количество кадров в видео

Если у меня есть MPMoviePlayerController в Swift:

MPMoviePlayerController mp = MPMoviePlayerController(contentURL: url)

Есть ли способ получить количество кадров в видео, расположенном в url? Если нет, есть ли другой способ определить количество кадров?


person Oliver Spryn    schedule 08.04.2015    source источник


Ответы (3)


Я не думаю, что MPMoviePlayerController может вам помочь.

Используйте AVAssetReader и посчитайте количество CMSampleBuffer, которое он вам вернет. Вы можете настроить его так, чтобы он даже не декодировал кадры, эффективно анализируя файл, поэтому он должен быть быстрым и эффективным с точки зрения памяти.

Что-то типа

    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.

person Rhythmic Fistman    schedule 08.04.2015
comment
Превосходно! У вас есть быстрый пример, который вы могли бы показать? Это было бы очень полезно. - person Oliver Spryn; 08.04.2015

Свифт 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
    }
person Amal T S    schedule 26.06.2019
comment
не забудьте установить настройки, иначе вы можете получить неправильный номер. let readerSettings = [String(kCVPixelBufferPixelFormatTypeKey): Int(kCVPixelFormatType_32BGRA)] сделаю - person yuji; 05.01.2021

Вы также можете использовать количество кадров в секунду для расчета общего количества кадров.

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)
person Chathuranga Silva    schedule 10.06.2021