我花了一整天的时间浏览了很多 SO 答案、Apple 引用资料、文档等,但没有成功。
我想要一件简单的事情:我正在使用 AVPlayer 播放视频,我想暂停它并获取当前帧作为 UIImage
。就是这样。
我的视频是一个位于互联网上的m3u8文件,它在AVPlayerLayer
中正常播放没有任何问题。
我尝试了什么:
AVAssetImageGenerator
。 它不起作用,方法copyCGImageAtTime:actualTime: error:
返回空图像引用。根据回答hereAVAssetImageGenerator
不适用于流式视频。- 拍摄播放器 View 的快照。我首先在
AVPlayerLayer
上尝试了renderInContext:
,但后来我意识到它不是这种渲染方式“特殊”层。然后我发现了 iOS 7 中引入的一种新方法 -drawViewHierarchyInRect:afterScreenUpdates:
它应该也可以渲染特殊层,但运气不好,仍然得到了视频所在的带有空白黑色区域的 UI 快照显示。 AVPlayerItemVideoOutput
。 我已经为我的AVPlayerItem
添加了视频输出,但是每当我调用hasNewPixelBufferForItemTime:
时它返回NO
。我猜问题又出在流媒体视频和 I am not alone有这个问题。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/