YAYAYAYAYAYAAYAYAYA VIDEOOO

we have video! supports macOS 12.3 and up
This commit is contained in:
neon443
2026-01-01 22:44:13 +00:00
parent 018a589c5a
commit 79ebd5fee9
4 changed files with 32 additions and 7 deletions

View File

@@ -37,11 +37,16 @@ class CaptureEngine: NSObject {
streamOutput.pcmBufferHandler = { print($0) } streamOutput.pcmBufferHandler = { print($0) }
do { do {
streamOutput.frameBufferHandler = { frame in
// print("got frame \(frame.size) at \(frame.contentRect)")
continuation.yield(frame)
}
stream = SCStream(filter: filter, configuration: config, delegate: streamOutput) stream = SCStream(filter: filter, configuration: config, delegate: streamOutput)
try stream?.addStreamOutput(streamOutput, type: .screen, sampleHandlerQueue: videoSampleBufferQueue) try stream?.addStreamOutput(streamOutput, type: .screen, sampleHandlerQueue: videoSampleBufferQueue)
try stream?.addStreamOutput(streamOutput, type: .audio, sampleHandlerQueue: audioSampleBufferQueue) // try stream?.addStreamOutput(streamOutput, type: .audio, sampleHandlerQueue: audioSampleBufferQueue)
try stream?.addStreamOutput(streamOutput, type: .microphone, sampleHandlerQueue: videoSampleBufferQueue) // try stream?.addStreamOutput(streamOutput, type: .microphone, sampleHandlerQueue: videoSampleBufferQueue)
stream?.startCapture()
} catch { } catch {
continuation.finish(throwing: error) continuation.finish(throwing: error)
} }

View File

@@ -462,6 +462,7 @@
"$(inherited)", "$(inherited)",
"@executable_path/../Frameworks", "@executable_path/../Frameworks",
); );
MACOSX_DEPLOYMENT_TARGET = 12.3;
MARKETING_VERSION = 1.0; MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.neon443.Scream; PRODUCT_BUNDLE_IDENTIFIER = com.neon443.Scream;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
@@ -506,6 +507,7 @@
"$(inherited)", "$(inherited)",
"@executable_path/../Frameworks", "@executable_path/../Frameworks",
); );
MACOSX_DEPLOYMENT_TARGET = 12.3;
MARKETING_VERSION = 1.0; MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.neon443.Scream; PRODUCT_BUNDLE_IDENTIFIER = com.neon443.Scream;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";

View File

@@ -21,6 +21,9 @@ class AppDelegate: NSObject, NSApplicationDelegate {
func applicationDidFinishLaunching(_ aNotification: Notification) { func applicationDidFinishLaunching(_ aNotification: Notification) {
// Insert code here to initialize your application // Insert code here to initialize your application
let preview = CaptureVideoPreview(layer: sr.contentLayer)
preview.frame.size = window.contentView!.frame.size
window.contentView?.addSubview(preview)
} }
func applicationWillTerminate(_ aNotification: Notification) { func applicationWillTerminate(_ aNotification: Notification) {
@@ -34,3 +37,15 @@ class AppDelegate: NSObject, NSApplicationDelegate {
} }
class CaptureVideoPreview: NSView {
init(layer: CALayer) {
super.init(frame: .zero)
wantsLayer = true
self.layer = layer
layer.autoresizingMask = [.layerWidthSizable, .layerHeightSizable]
}
required init?(coder: NSCoder) {
fatalError()
}
}

View File

@@ -10,7 +10,7 @@ import ScreenCaptureKit
class ScreenRecorder: NSObject { class ScreenRecorder: NSObject {
var isRunning: Bool = false var isRunning: Bool = false
var isAppExluded: Bool = false var isAppExluded: Bool = true
var isAudioEnabled: Bool = false var isAudioEnabled: Bool = false
var filter: SCContentFilter? var filter: SCContentFilter?
@@ -30,8 +30,8 @@ class ScreenRecorder: NSObject {
var streamConfig: SCStreamConfiguration { var streamConfig: SCStreamConfiguration {
var streamConfig = SCStreamConfiguration() var streamConfig = SCStreamConfiguration()
//TODO: hdr //TODO: hdr
streamConfig.capturesAudio = isAudioEnabled // streamConfig.capturesAudio = isAudioEnabled
streamConfig.excludesCurrentProcessAudio = false // streamConfig.excludesCurrentProcessAudio = false
// streamConfig.captureMicrophone = true // streamConfig.captureMicrophone = true
streamConfig.width = Int(NSScreen.main?.frame.width ?? 100) streamConfig.width = Int(NSScreen.main?.frame.width ?? 100)
@@ -43,6 +43,8 @@ class ScreenRecorder: NSObject {
} }
let captureEngine = CaptureEngine() let captureEngine = CaptureEngine()
var contentLayer = CALayer()
var canRecord: Bool { var canRecord: Bool {
true true
} }
@@ -70,7 +72,7 @@ class ScreenRecorder: NSObject {
do { do {
isRunning = true isRunning = true
for try await frame in captureEngine.startCapture(config: streamConfig, filter: filter!) { for try await frame in captureEngine.startCapture(config: streamConfig, filter: filter!) {
print(frame) contentLayer.contents = frame.surface
} }
} catch { } catch {
isRunning = false isRunning = false
@@ -87,10 +89,11 @@ class ScreenRecorder: NSObject {
} }
extension ScreenRecorder: SCContentSharingPickerObserver { extension ScreenRecorder: SCContentSharingPickerObserver {
@available(macOS 14, *)
func contentSharingPicker(_ picker: SCContentSharingPicker, didCancelFor stream: SCStream?) { func contentSharingPicker(_ picker: SCContentSharingPicker, didCancelFor stream: SCStream?) {
print("canceleed picker") print("canceleed picker")
} }
@available(macOS 14, *)
func contentSharingPicker(_ picker: SCContentSharingPicker, didUpdateWith filter: SCContentFilter, for stream: SCStream?) { func contentSharingPicker(_ picker: SCContentSharingPicker, didUpdateWith filter: SCContentFilter, for stream: SCStream?) {
print(picker.description) print(picker.description)
} }