5
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Swift:Macのインカメラから取得した映像を鏡写し(左右反転)で保存する(プレビュー付き)

Posted at

インカメラから映像を取得するのも録画するのも簡単だが,鏡写しで保存するのに意外と手こずったので備忘録.

CustomView
import Cocoa
import AVFoundation

class CameraView: NSView {
    
    let output = AVCaptureMovieFileOutput() // ファイル出力用
    let session = AVCaptureSession()
    var camera: AVCaptureDevice? = nil
    var previewLayer: AVCaptureVideoPreviewLayer? = nil // プレビュー用

    required init?(coder decoder: NSCoder) {
        super.init(coder: decoder)
        
        wantsLayer = true
        let devices = AVCaptureDevice.devices(for: AVMediaType.video)
        if devices.count > 0 {
            camera = devices.first!
        } else {
            Swift.print("No Available Devices")
            return
        }
        do {
            let input = try AVCaptureDeviceInput(device: camera!)
            // プレビューの設定
            if session.canAddInput(input) {
                session.addInput(input)
                session.sessionPreset = AVCaptureSession.Preset.medium
                previewLayer = AVCaptureVideoPreviewLayer(session: session)
                previewLayer!.frame = bounds
                previewLayer!.videoGravity = AVLayerVideoGravity.resizeAspectFill
                previewLayer!.setAffineTransform(CGAffineTransform(scaleX: -1, y: 1))
                layer?.addSublayer(previewLayer!)
            }
            // ファイル出力の設定
            if session.canAddOutput(output) {
                session.addOutput(output)
                // ここからが鏡写しのキモ
                session.beginConfiguration()
                if let connection = output.connection(with: AVMediaType.video) {
                    if connection.isVideoMirroringSupported {
                        connection.automaticallyAdjustsVideoMirroring = false
                        connection.isVideoMirrored = true
                    }
                }
                session.commitConfiguration()
            }
        } catch {
            Swift.print("No Available Devices")
        }
    }
    
    // 画面のリサイズ対応
    public func resizeWindow() {
        previewLayer!.frame = bounds
    }
    
}
ViewController
import Cocoa
import AVFoundation

class CameraVC: NSViewController, NSWindowDelegate, AVCaptureFileOutputRecordingDelegate {

    @IBOutlet weak var cameraView: CameraView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        cameraView.session.startRunning()
    }
    
    override func viewWillAppear() {
        self.view.window?.delegate = self
    }
    
    override func viewWillDisappear() {
        cameraView.output.stopRecording()
        cameraView.session.stopRunning()
    }
    
    // 画面のリサイズに対応
    func windowDidResize(_ notification: Notification) {
        cameraView.resizeWindow()
    }
    
    public func startRecording() {
        let fileName = "sample.mov"
        // とりあえず書類フォルダに保存する
        guard let docDir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first else {
            return
        }
        let url = docDir.appendingPathComponent(fileName)
        cameraView.output.startRecording(to: url, recordingDelegate: self)
    }
    
    public func stopRecording() {
        cameraView.output.stopRecording()
    }
    
    func fileOutput(_ output: AVCaptureFileOutput, didFinishRecordingTo outputFileURL: URL, from connections: [AVCaptureConnection], error: Error?) {
        Swift.print("Finish Recording.")
    }
    
}
5
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?