阅读了很多有关此的教程,但尚未找到可以轻松实现到XCode11中的解决方案。
我想从photoLibrary中获取视频,然后简单地写一个布尔值来说明视频在任何时间点是否都存在人脸。
有没有简单的方法可以写这个?我的想象是,从照相馆加载视频,使用AVFoundations播放,然后使用观察者将视频逐帧输出到视觉中,使用VNSequenceHandler进行面部识别。
有人可以帮忙吗?
谢谢! 詹姆斯
应评论者的要求,这是我尝试做的事情:
import UIKit
import AVFoundation
import CoreML
import Vision
class ViewController: UIViewController {
var player: AVPlayer!
var videoOutput: AVPlayerItemVideoOutput?
override func viewDidLoad() {
super.viewDidLoad()
let URL = NSURL(fileURLWithPath: "videplayback.mp4")
let player = AVPlayer(URL: URL)
player.play()
player.currentItem?.addObserver(
self,
forKeyPath: #keyPath(AVPlayerItem.status),
options: [.initial, .old, .new],
context: nil)
player.addPeriodicTimeObserver(
forInterval: CMTime(value: 1, timescale: 30),
queue: DispatchQueue(label: "videoProcessing", qos: .background),
using: { time in
self.Facerecognition()
})
self.player = player
}
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
guard let keyPath = keyPath, let item = object as? AVPlayerItem
else { return }
switch keyPath {
case #keyPath(AVPlayerItem.status):
if item.status == .readyToPlay {
self.setUpOutput()
}
break
default: break
}
}
func setUpOutput() {
guard self.videoOutput == nil else { return }
let videoItem = player.currentItem!
if videoItem.status != AVPlayerItem.Status.readyToPlay {
return
}
let pixelBuffAttributes = [
kCVPixelBufferPixelFormatTypeKey as String: kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange,
] as [String: Any]
let videoOutput = AVPlayerItemVideoOutput(pixelBufferAttributes: pixelBuffAttributes)
videoItem.add(videoOutput)
self.videoOutput = videoOutput
}
func getNewFrame() -> CVPixelBuffer? {
guard let videoOutput = videoOutput, let currentItem = player.currentItem else { return nil }
let time = currentItem.currentTime()
if !videoOutput.hasNewPixelBuffer(forItemTime: time) { return nil }
guard let buffer = videoOutput.copyPixelBuffer(forItemTime: time, itemTimeForDisplay: nil)
else { return nil }
return buffer
}
func Facerecognition() {
guard let buffer = getNewFrame() else { return }
let visionSequenceHandler = VNSequenceRequestHandler()
let request = VNTrackObjectRequest(detectedObjectObservation: lastObservation, completionHandler: self.handleVisionRequestUpdate)
request.trackingLevel = .accurate
do {
try self.visionSequenceHandler.perform([request], on: buffer)
} catch {
print("Throws: \(error)")
}
}
}