]> git.r.bdr.sh - rbdr/captura/blame - Captura/Domain/CapturaCaptureSession.swift
Format the code
[rbdr/captura] / Captura / Domain / CapturaCaptureSession.swift
CommitLineData
c9b9e1d6 1import AVFoundation
505c1e62 2import AppKit
c9b9e1d6 3
505c1e62
RBR
4class CapturaCaptureSession: AVCaptureSession, AVCaptureFileOutputRecordingDelegate,
5 AVCaptureVideoDataOutputSampleBufferDelegate
6{
c9b9e1d6
RBR
7
8 let videoOutput = AVCaptureVideoDataOutput()
9 let movieFileOutput = AVCaptureMovieFileOutput()
10 var receivedFrames = false
505c1e62 11
c9b9e1d6
RBR
12 init(_ screen: NSScreen, box: NSRect) {
13 super.init()
505c1e62
RBR
14
15 let displayId =
16 screen.deviceDescription[NSDeviceDescriptionKey("NSScreenNumber")] as! CGDirectDisplayID
c9b9e1d6 17 let screenInput = AVCaptureScreenInput(displayID: displayId)
082b61f3
RBR
18 var croppingBox = NSOffsetRect(box, -screen.frame.origin.x, -screen.frame.origin.y)
19 if croppingBox.width.truncatingRemainder(dividingBy: 2) != 0 {
20 croppingBox.size.width -= 1
21 }
22 screenInput?.cropRect = croppingBox.insetBy(dx: 1, dy: 1)
505c1e62 23
c9b9e1d6
RBR
24 if self.canAddInput(screenInput!) {
25 self.addInput(screenInput!)
26 }
505c1e62
RBR
27
28 videoOutput.setSampleBufferDelegate(
29 self, queue: Dispatch.DispatchQueue(label: "sample buffer delegate", attributes: []))
30
c9b9e1d6
RBR
31 if self.canAddOutput(videoOutput) {
32 self.addOutput(videoOutput)
33 }
505c1e62 34
c9b9e1d6
RBR
35 if self.canAddOutput(movieFileOutput) {
36 self.addOutput(movieFileOutput)
37 }
38 }
505c1e62 39
c9b9e1d6
RBR
40 func startRecording() {
41 receivedFrames = false
42 self.startRunning()
505c1e62 43
c9b9e1d6
RBR
44 DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
45 if !self.receivedFrames {
46 NotificationCenter.default.post(name: .failedToStart, object: nil, userInfo: nil)
47 }
48 }
49 }
505c1e62 50
c9b9e1d6
RBR
51 func startRecording(to url: URL) {
52 self.startRecording()
53 movieFileOutput.startRecording(to: url, recordingDelegate: self)
54 }
505c1e62 55
c9b9e1d6 56 // MARK: - AVCaptureVideoDataOutputSampleBufferDelegate Implementation
505c1e62
RBR
57
58 func captureOutput(
59 _ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer,
60 from connection: AVCaptureConnection
61 ) {
c9b9e1d6 62 receivedFrames = true
505c1e62 63
c9b9e1d6 64 guard let imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) else { return }
505c1e62
RBR
65 NotificationCenter.default.post(
66 name: .receivedFrame, object: nil, userInfo: ["frame": imageBuffer])
c9b9e1d6 67 }
505c1e62 68
c9b9e1d6 69 // MARK: - AVCaptureFileOutputRecordingDelegate Implementation
505c1e62
RBR
70
71 func fileOutput(
72 _ output: AVCaptureFileOutput, didFinishRecordingTo outputFileURL: URL,
73 from connections: [AVCaptureConnection], error: Error?
74 ) {}
c9b9e1d6 75}