Я хочу получить доступ к iPad-iPad в приложении Swift Playgrounds iPad. Я обнаружил, что невозможно захватить видеоданные, хотя моя игровая площадка работает нормально.
captureOutput(_ captureOutput: AVCaptureOutput!, didOutputSampleBuffer sampleBuffer: CMSampleBuffer!, from connection: AVCaptureConnection!)
, метод делегата протокола AVCaptureVideoDataOutputSampleBufferDelegate
не вызван (вероятно, из-за отсутствия видеоданных), в то время как он находится в моем приложении iOS.
Предполагается, что на моей игровой площадке будет отображаться вид камеры FaceTime. Почему я не могу отобразить вывод камеры, даже если Apple явно говорит, что это разрешено делать? Кроме того, приложение Playground запрашивает у меня разрешения на камеру, как только я открою свою игровую площадку, поэтому это должно быть разрешено каким-то образом.
import UIKit
import CoreImage
import AVFoundation
import ImageIO
import PlaygroundSupport
class Visage: NSObject, AVCaptureVideoDataOutputSampleBufferDelegate {
var visageCameraView : UIView = UIView()
fileprivate var faceDetector : CIDetector?
fileprivate var videoDataOutput : AVCaptureVideoDataOutput?
fileprivate var videoDataOutputQueue : DispatchQueue?
fileprivate var cameraPreviewLayer : AVCaptureVideoPreviewLayer?
fileprivate var captureSession : AVCaptureSession = AVCaptureSession()
fileprivate let notificationCenter : NotificationCenter = NotificationCenter.default
override init() {
super.init()
self.captureSetup(AVCaptureDevicePosition.front)
var faceDetectorOptions : [String : AnyObject]?
faceDetectorOptions = [CIDetectorAccuracy : CIDetectorAccuracyHigh as AnyObject]
self.faceDetector = CIDetector(ofType: CIDetectorTypeFace, context: nil, options: faceDetectorOptions)
}
func beginFaceDetection() {
self.captureSession.startRunning()
}
func endFaceDetection() {
self.captureSession.stopRunning()
}
fileprivate func captureSetup (_ position : AVCaptureDevicePosition) {
var captureError : NSError?
var captureDevice : AVCaptureDevice!
for testedDevice in AVCaptureDevice.devices(withMediaType: AVMediaTypeVideo){
if ((testedDevice as AnyObject).position == position) {
captureDevice = testedDevice as! AVCaptureDevice
}
}
if (captureDevice == nil) {
captureDevice = AVCaptureDevice.defaultDevice(withMediaType: AVMediaTypeVideo)
}
var deviceInput : AVCaptureDeviceInput?
do {
deviceInput = try AVCaptureDeviceInput(device: captureDevice)
} catch let error as NSError {
captureError = error
deviceInput = nil
}
captureSession.sessionPreset = AVCaptureSessionPresetHigh
if (captureError == nil) {
if (captureSession.canAddInput(deviceInput)) {
captureSession.addInput(deviceInput)
}
self.videoDataOutput = AVCaptureVideoDataOutput()
self.videoDataOutput!.videoSettings = [kCVPixelBufferPixelFormatTypeKey as AnyHashable: Int(kCVPixelFormatType_32BGRA)]
self.videoDataOutput!.alwaysDiscardsLateVideoFrames = true
self.videoDataOutputQueue = DispatchQueue(label: "VideoDataOutputQueue", attributes: [])
self.videoDataOutput!.setSampleBufferDelegate(self, queue: self.videoDataOutputQueue!)
if (captureSession.canAddOutput(self.videoDataOutput)) {
captureSession.addOutput(self.videoDataOutput)
}
}
visageCameraView.frame = UIScreen.main.bounds
let previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
previewLayer?.frame = UIScreen.main.bounds
previewLayer?.videoGravity = AVLayerVideoGravityResizeAspectFill
visageCameraView.layer.addSublayer(previewLayer!)
}
// NOT CALLED
func captureOutput(_ captureOutput: AVCaptureOutput!, didOutputSampleBuffer sampleBuffer: CMSampleBuffer!, from connection: AVCaptureConnection!) {
print("delegate method called!")
}
}
class SmileView: UIView {
let smileView = UIView()
var smileRec: Visage!
override init(frame: CGRect) {
super.init(frame: frame)
self.addSubview(smileView)
self.translatesAutoresizingMaskIntoConstraints = false
smileRec = Visage()
smileRec.beginFaceDetection()
let cameraView = smileRec.visageCameraView
self.addSubview(cameraView)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
let frame = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height)
let sView = SmileView(frame: frame)
PlaygroundPage.current.liveView = sView