Swift - 关于 OS X 添加子层问题的 AVFoundation

Swift - AVFoundation on OS X adding sublayer issue

我正在尝试在自定义视图中预览我的视频设备。 但我得到的只是一个空 window。我看到我可以毫无问题地访问我的相机。一旦应用程序启动,我就会看到我的罗技摄像头 LED 灯亮起。 我假设我的问题是将预览层添加为子层。

这是我的简单代码:

import Cocoa
import AVFoundation

@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {

@IBOutlet weak var video: NSView!
@IBOutlet weak var window: NSWindow!

let captureSession = AVCaptureSession()
var captureDevice : AVCaptureDevice?
var previewLayer : AVCaptureVideoPreviewLayer?

func applicationDidFinishLaunching(aNotification: NSNotification) {

    captureSession.sessionPreset = AVCaptureSessionPresetLow
    let devices = AVCaptureDevice.devices()
    for device in devices {

        if (device.hasMediaType(AVMediaTypeVideo)) {
            captureDevice = device as? AVCaptureDevice
            println(captureDevice)
        }
    }

    if captureDevice != nil {
        beginSession()
    }


}

func beginSession() {

    println("begin")
    var err : NSError? = nil
    captureSession.addInput(AVCaptureDeviceInput(device: captureDevice, error: &err))

    if err != nil {
        println("error: \(err?.localizedDescription)")
    }



    previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
    previewLayer!.frame = self.video.bounds
    previewLayer!.videoGravity = AVLayerVideoGravityResizeAspectFill
    self.video.layer?.addSublayer(previewLayer)
    captureSession.startRunning()
}

func applicationWillTerminate(aNotification: NSNotification) {
    // Insert code here to tear down your application
}


}

解决了。在 Interface Builder 中,我需要在核心动画中添加自定义视图。

对于我的小型 swift-base AVFoundation 采集器,这个问答 post 帮助了我。我注意到以下检查对于界面生成器中的 "Custom View" 很重要:

  • 属性检查器 > 检查 "Can Draw Concurrently":
  • View Effects Inspector > 检查 "Core Animation Layer list" 上的自定义视图(甚至可以取消选中主视图控制器)

在 Swift 2 中,错误处理已更改。如果您使用 Main.storyboard,则以下方法应该有效:

class ViewController: NSViewController {

let captureSession = AVCaptureSession()
var captureDevice: AVCaptureDevice?
var previewLayer: AVCaptureVideoPreviewLayer?
var previewPanel: NSView!

override func viewDidLoad() {
    super.viewDidLoad()
    captureSession.sessionPreset = AVCaptureSessionPresetLow
    let devices = AVCaptureDevice.devices()
    for device in devices {
        if (device.hasMediaType(AVMediaTypeVideo)) {
            captureDevice = device as? AVCaptureDevice
            //Swift.print("device: \(captureDevice)")
        }
    }
    Swift.print("beginning")
    do {
        let deviceInput = try AVCaptureDeviceInput(device: captureDevice)
        captureSession.addInput(deviceInput)
        // get the CustomView as preview panel
        previewPanel = self.view.subviews.first
        previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
        previewLayer!.frame = self.view.bounds
        // add layer to preview
        previewLayer!.videoGravity = AVLayerVideoGravityResizeAspectFill
        previewPanel.layer?.addSublayer(previewLayer!)
        captureSession.startRunning()
    } catch let error as NSError {
        Swift.print("Error: no valid camera input in \(error.domain)")
    }
}
override var representedObject: AnyObject? {
    didSet {
        // Update the view, if already loaded.
    }
}

不要忘记添加 CustomView。