【问题标题】:How to access Mac default camera using swift xcode如何使用 swift xcode 访问 Mac 默认相机
【发布时间】:2023-03-15 07:50:01
【问题描述】:

今天我是第一次为 Mac 编写代码。我想要做的是访问默认相机并显示预览。第二步,如果需要,我将记录或拍一张照片。对于第一步,我编写了以下代码

import Cocoa
import AVFoundation
class ViewController: NSViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        var session:AVCaptureSession = AVCaptureSession()
        session.sessionPreset = AVCaptureSessionPresetLow
        var device:AVCaptureDevice = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo)
        //Preview
        var previewLayer:AVCaptureVideoPreviewLayer = AVCaptureVideoPreviewLayer(session: session)
        var myView:NSView = self.view
        previewLayer.frame = myView.bounds
        previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill
        self.view.layer?.addSublayer(previewLayer)
        session.startRunning()
    }
    override var representedObject: AnyObject? {
        didSet {
        // Update the view, if already loaded.
        }
    }
}

我没有看到此代码正在打开我的笔记本电脑默认摄像头或在视图上显示任何内容。我在这里做错了什么?我可以寻找的任何方向或任何示例,即使它在 Obj-C 中真的很有帮助。 TIA。

【问题讨论】:

  • 沙盒问题?您查看控制台日志了吗?
  • 抱歉,沙盒问题是什么?控制台上没有错误,即使在调试时也没有抛出错误。在没有开发证书的情况下运行,因为还没有 mac 开发证书
  • Mac 应用程序可以在沙盒中运行(或者如果您将它们放在 AppStore 上则需要)。所以你可以忘记...
  • @KD。你有什么收获吗?

标签: xcode macos swift avcapturedevice


【解决方案1】:

在你的代码中

self.view.layer?.addSublayer(previewLayer)

不会被执行,因为self.view.layernil 所以不会被执行。

唉,这似乎不是唯一的问题,因为即使添加图层,相机也无法开始工作。您可能需要深入研究:

https://developer.apple.com/library/mac/samplecode/AVRecorder/Introduction/Intro.html

【讨论】:

  • 试试self.view.wantsLayer = true
【解决方案2】:

swift 5 中的工作代码。

import Cocoa
import AVFoundation

class SomwViewController: NSViewController {
    @IBOutlet private var cameraView: NSView?
    let session: AVCaptureSession = AVCaptureSession()

    override func viewDidLoad() {
        super.viewDidLoad()
        cameraView?.wantsLayer = true
        cameraView?.layer?.backgroundColor = NSColor.black.cgColor
        session.sessionPreset = AVCaptureSession.Preset.low
        let input: AVCaptureInput = try! AVCaptureDeviceInput(device: AVCaptureDevice.default(for: .video)!)
        session.addInput(input)
        let previewLayer: AVCaptureVideoPreviewLayer = AVCaptureVideoPreviewLayer(session: session)
        previewLayer.frame = cameraView!.bounds
        previewLayer.videoGravity = AVLayerVideoGravity.resizeAspectFill

        cameraView?.layer?.addSublayer(previewLayer)
    }

    override func viewDidAppear() {
        session.startRunning()
    }

    override func viewDidDisappear() {
        session.stopRunning()
    }
}

你绝对不应该使用强制展开,这只是一个例子。

【讨论】:

    【解决方案3】:

    请务必检查您的视图在 IB 中是否有核心动画层:

    【讨论】:

    • 这很有帮助。谢谢你,瑞克!很遗憾,不检查,代码就无异常运行,什么都不做。
    • 其实我觉得挺好的。在 Swift 中,您可以使用 '?' 选择加入该行为。在 IB 的情况下,你需要告诉它你想要什么。这就像忘记添加视图,然后因为您想要的视图没有出现而感到沮丧。
    【解决方案4】:

    如果有人仍然希望在 Mac OS X 中使用 swift 3 启动网络摄像头

    这里是代码

    @IBOutlet var previewCam: PreviewCam!
    override func viewDidLoad()
    {
        super.viewDidLoad()
        view.wantsLayer = true
        previewCam.wantsLayer = true
        let session:AVCaptureSession = AVCaptureSession()
        session.sessionPreset = AVCaptureSessionPresetLow
        let device:AVCaptureDevice = AVCaptureDevice.defaultDevice(withMediaType: AVMediaTypeVideo)
        print("device found = ",device)
    
        let device_input : AVCaptureDeviceInput = try! AVCaptureDeviceInput(device: device)
    
    
        let previewLayer:AVCaptureVideoPreviewLayer = AVCaptureVideoPreviewLayer(session: session)
    
        previewLayer.frame = previewCam.bounds
        previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill
        self.previewCam.layer?.addSublayer(previewLayer)
        if session.canAddInput(device_input)
        {
            session.addInput(device_input)
        }
        session.startRunning()
    }
    

    对于那些询问预览摄像头的人

    #import "PreviewCam.h"
    
    @implementation PreviewCam
    
    - (void)drawRect:(NSRect)dirtyRect {
        [super drawRect:dirtyRect];
    
        // Drawing code here.
        CGContextRef context = [[NSGraphicsContext currentContext]graphicsPort];
        CGContextSetRGBFillColor(context, 0, 0, 0, 0.75);
        CGContextFillRect(context, NSRectToCGRect(dirtyRect));
        self.layer.borderColor = [[NSColor whiteColor]CGColor];
        self.layer.borderWidth = 2.0f;
    }
    

    【讨论】:

    • 什么是“PreviewCam”类型?
    • 预览凸轮是一小段代码,我将用它编辑我以前的答案
    • 未来的互联网旅行者:所有这些都可以在没有 PreviewCam 或 IB builder 的情况下以编程方式完成。
    • @GitSync 你能详细说明一下吗?我正在努力让这个工作
    • 那条评论的意义何在?如果您不能或不愿意帮助社区的其他成员,那么为什么要发表评论呢?
    猜你喜欢
    • 2021-07-26
    • 1970-01-01
    • 2020-03-27
    • 1970-01-01
    • 2015-10-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多