iOS:AVPlayer - 获取视频当前帧的快照

标签 ios objective-c video avfoundation avplayer

我花了一整天的时间浏览了很多 SO 答案、Apple 引用资料、文档等,但没有成功。

我想要一件简单的事情:我正在使用 AVPlayer 播放视频,我想暂停它并获取当前帧作为 UIImage。就是这样。

我的视频是一个位于互联网上的m3u8文件,它在AVPlayerLayer中正常播放没有任何问题。

我尝试了什么:

  1. AVAssetImageGenerator 它不起作用,方法 copyCGImageAtTime:actualTime: error: 返回空图像引用。根据回答here AVAssetImageGenerator 不适用于流式视频。
  2. 拍摄播放器 View 的快照。我首先在 AVPlayerLayer 上尝试了 renderInContext:,但后来我意识到它不是这种渲染方式“特殊”层。然后我发现了 iOS 7 中引入的一种新方法 - drawViewHierarchyInRect:afterScreenUpdates: 它应该也可以渲染特殊层,但运气不好,仍然得到了视频所在的带有空白黑色区域的 UI 快照显示。
  3. AVPlayerItemVideoOutput 我已经为我的 AVPlayerItem 添加了视频输出,但是每当我调用 hasNewPixelBufferForItemTime: 时它返回 NO。我猜问题又出在流媒体视频和 I am not alone有这个问题。
  4. AVAssetReader. 本来想试试的,但发现相关问题后决定不浪费时间here .

那么,是否有任何方法可以获取我现在在屏幕上看到的内容的快照?我简直不敢相信。

最佳答案

AVAssetImageGenerator 是拍摄视频的最佳方式,此方法异步返回一个 UIImage :

import AVFoundation

// ...

var player:AVPlayer? = // ...

func screenshot(handler:@escaping ((UIImage)->Void)) {
    guard let player = player ,
        let asset = player.currentItem?.asset else {
            return
    }

    let imageGenerator = AVAssetImageGenerator(asset: asset)
    imageGenerator.appliesPreferredTrackTransform = true
    let times = [NSValue(time:player.currentTime())]

    imageGenerator.generateCGImagesAsynchronously(forTimes: times) { _, image, _, _, _ in
        if image != nil {
            handler(UIImage(cgImage: image!))
        }
    }
}

(这是 Swift 4.2)

关于iOS:AVPlayer - 获取视频当前帧的快照,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39551459/

相关文章:

ios - 如何将按钮的状态保存到 NSUserDefaults?

objective-c - 在 Objective C 中创建单例类的另一个实例

linux - 命令行视频编辑工具

java - 为什么 Android SDK QuickBlox 只能进行第一个视频通话?

ios - 是什么导致了 <Error> : CGContextSetBaseCTM: invalid context 0x0 when implementing loadView?

ios - Apple 推送通知类服务,仅在前台运行时

java - 推送通知 - 由 : java. io.IOException 引起:toDerInputStream 拒绝标记类型 45

ios - 无法将数据获取到 MasterViewController 中的 UITableView 中

image - 有什么办法可以拯救脏 Canvas ?

ios - 当格式说明符错误地传递给方法时如何发出警告