sob i have no idea whats going on trying to set up the capture but i never seem to get any data

This commit is contained in:
neon443
2026-01-01 20:20:48 +00:00
parent 85daea1770
commit 91319f7fc3
7 changed files with 275 additions and 38 deletions

View File

@@ -3,9 +3,21 @@
archiveVersion = 1;
classes = {
};
objectVersion = 77;
objectVersion = 63;
objects = {
/* Begin PBXBuildFile section */
A98E8BF02F05B2A0006D4458 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = A98E8BEB2F05B2A0006D4458 /* AppDelegate.swift */; };
A98E8BF12F05B2A0006D4458 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = A98E8BEC2F05B2A0006D4458 /* Assets.xcassets */; };
A98E8BF22F05B2A0006D4458 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = A98E8BEE2F05B2A0006D4458 /* MainMenu.xib */; };
A98E8BF52F05B2A2006D4458 /* ScreamTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A98E8BF32F05B2A2006D4458 /* ScreamTests.swift */; };
A98E8BF92F05B2A5006D4458 /* ScreamUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A98E8BF62F05B2A5006D4458 /* ScreamUITests.swift */; };
A98E8BFA2F05B2A5006D4458 /* ScreamUITestsLaunchTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A98E8BF72F05B2A5006D4458 /* ScreamUITestsLaunchTests.swift */; };
A98E8BFD2F05D28D006D4458 /* ScreenRecorder.swift in Sources */ = {isa = PBXBuildFile; fileRef = A98E8BFC2F05D28D006D4458 /* ScreenRecorder.swift */; };
A98E8BFF2F06F46C006D4458 /* SCStreamOutput.swift in Sources */ = {isa = PBXBuildFile; fileRef = A98E8BFE2F06F46C006D4458 /* SCStreamOutput.swift */; };
A98E8C012F06F496006D4458 /* StreamDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = A98E8C002F06F496006D4458 /* StreamDelegate.swift */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
A98E8BCF2F05B26D006D4458 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
@@ -27,26 +39,18 @@
A98E8BC02F05B26B006D4458 /* Scream.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Scream.app; sourceTree = BUILT_PRODUCTS_DIR; };
A98E8BCE2F05B26D006D4458 /* ScreamTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ScreamTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
A98E8BD82F05B26D006D4458 /* ScreamUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ScreamUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
A98E8BEB2F05B2A0006D4458 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
A98E8BEC2F05B2A0006D4458 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
A98E8BED2F05B2A0006D4458 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = "<group>"; };
A98E8BF32F05B2A2006D4458 /* ScreamTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScreamTests.swift; sourceTree = "<group>"; };
A98E8BF62F05B2A5006D4458 /* ScreamUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScreamUITests.swift; sourceTree = "<group>"; };
A98E8BF72F05B2A5006D4458 /* ScreamUITestsLaunchTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScreamUITestsLaunchTests.swift; sourceTree = "<group>"; };
A98E8BFB2F05C7B6006D4458 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = "<group>"; };
A98E8BFC2F05D28D006D4458 /* ScreenRecorder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScreenRecorder.swift; sourceTree = "<group>"; };
A98E8BFE2F06F46C006D4458 /* SCStreamOutput.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SCStreamOutput.swift; sourceTree = "<group>"; };
A98E8C002F06F496006D4458 /* StreamDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StreamDelegate.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFileSystemSynchronizedRootGroup section */
A98E8BC22F05B26B006D4458 /* Scream */ = {
isa = PBXFileSystemSynchronizedRootGroup;
path = Scream;
sourceTree = "<group>";
};
A98E8BD12F05B26D006D4458 /* ScreamTests */ = {
isa = PBXFileSystemSynchronizedRootGroup;
path = ScreamTests;
sourceTree = "<group>";
};
A98E8BDB2F05B26D006D4458 /* ScreamUITests */ = {
isa = PBXFileSystemSynchronizedRootGroup;
path = ScreamUITests;
sourceTree = "<group>";
};
/* End PBXFileSystemSynchronizedRootGroup section */
/* Begin PBXFrameworksBuildPhase section */
A98E8BBD2F05B26B006D4458 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
@@ -75,9 +79,9 @@
A98E8BB72F05B26B006D4458 = {
isa = PBXGroup;
children = (
A98E8BC22F05B26B006D4458 /* Scream */,
A98E8BD12F05B26D006D4458 /* ScreamTests */,
A98E8BDB2F05B26D006D4458 /* ScreamUITests */,
A98E8BEF2F05B2A0006D4458 /* Scream */,
A98E8BF42F05B2A2006D4458 /* ScreamTests */,
A98E8BF82F05B2A5006D4458 /* ScreamUITests */,
A98E8BC12F05B26B006D4458 /* Products */,
);
sourceTree = "<group>";
@@ -92,6 +96,37 @@
name = Products;
sourceTree = "<group>";
};
A98E8BEF2F05B2A0006D4458 /* Scream */ = {
isa = PBXGroup;
children = (
A98E8BFB2F05C7B6006D4458 /* Info.plist */,
A98E8BEB2F05B2A0006D4458 /* AppDelegate.swift */,
A98E8BEC2F05B2A0006D4458 /* Assets.xcassets */,
A98E8BEE2F05B2A0006D4458 /* MainMenu.xib */,
A98E8BFC2F05D28D006D4458 /* ScreenRecorder.swift */,
A98E8C002F06F496006D4458 /* StreamDelegate.swift */,
A98E8BFE2F06F46C006D4458 /* SCStreamOutput.swift */,
);
path = Scream;
sourceTree = "<group>";
};
A98E8BF42F05B2A2006D4458 /* ScreamTests */ = {
isa = PBXGroup;
children = (
A98E8BF32F05B2A2006D4458 /* ScreamTests.swift */,
);
path = ScreamTests;
sourceTree = "<group>";
};
A98E8BF82F05B2A5006D4458 /* ScreamUITests */ = {
isa = PBXGroup;
children = (
A98E8BF62F05B2A5006D4458 /* ScreamUITests.swift */,
A98E8BF72F05B2A5006D4458 /* ScreamUITestsLaunchTests.swift */,
);
path = ScreamUITests;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
@@ -107,9 +142,6 @@
);
dependencies = (
);
fileSystemSynchronizedGroups = (
A98E8BC22F05B26B006D4458 /* Scream */,
);
name = Scream;
packageProductDependencies = (
);
@@ -130,9 +162,6 @@
dependencies = (
A98E8BD02F05B26D006D4458 /* PBXTargetDependency */,
);
fileSystemSynchronizedGroups = (
A98E8BD12F05B26D006D4458 /* ScreamTests */,
);
name = ScreamTests;
packageProductDependencies = (
);
@@ -153,9 +182,6 @@
dependencies = (
A98E8BDA2F05B26D006D4458 /* PBXTargetDependency */,
);
fileSystemSynchronizedGroups = (
A98E8BDB2F05B26D006D4458 /* ScreamUITests */,
);
name = ScreamUITests;
packageProductDependencies = (
);
@@ -187,6 +213,7 @@
};
};
buildConfigurationList = A98E8BBB2F05B26B006D4458 /* Build configuration list for PBXProject "Scream" */;
compatibilityVersion = "Xcode 12.0";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
@@ -195,7 +222,6 @@
);
mainGroup = A98E8BB72F05B26B006D4458;
minimizedProjectReferenceProxies = 1;
preferredProjectObjectVersion = 77;
productRefGroup = A98E8BC12F05B26B006D4458 /* Products */;
projectDirPath = "";
projectRoot = "";
@@ -212,6 +238,8 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
A98E8BF12F05B2A0006D4458 /* Assets.xcassets in Resources */,
A98E8BF22F05B2A0006D4458 /* MainMenu.xib in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -236,6 +264,10 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
A98E8BF02F05B2A0006D4458 /* AppDelegate.swift in Sources */,
A98E8BFF2F06F46C006D4458 /* SCStreamOutput.swift in Sources */,
A98E8C012F06F496006D4458 /* StreamDelegate.swift in Sources */,
A98E8BFD2F05D28D006D4458 /* ScreenRecorder.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -243,6 +275,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
A98E8BF52F05B2A2006D4458 /* ScreamTests.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -250,6 +283,8 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
A98E8BF92F05B2A5006D4458 /* ScreamUITests.swift in Sources */,
A98E8BFA2F05B2A5006D4458 /* ScreamUITestsLaunchTests.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -268,6 +303,17 @@
};
/* End PBXTargetDependency section */
/* Begin PBXVariantGroup section */
A98E8BEE2F05B2A0006D4458 /* MainMenu.xib */ = {
isa = PBXVariantGroup;
children = (
A98E8BED2F05B2A0006D4458 /* Base */,
);
name = MainMenu.xib;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
A98E8BE02F05B26D006D4458 /* Debug */ = {
isa = XCBuildConfiguration;
@@ -400,8 +446,19 @@
DEVELOPMENT_TEAM = 8JGND254B7;
ENABLE_APP_SANDBOX = YES;
ENABLE_HARDENED_RUNTIME = YES;
ENABLE_INCOMING_NETWORK_CONNECTIONS = YES;
ENABLE_OUTGOING_NETWORK_CONNECTIONS = YES;
ENABLE_RESOURCE_ACCESS_AUDIO_INPUT = NO;
ENABLE_RESOURCE_ACCESS_BLUETOOTH = NO;
ENABLE_RESOURCE_ACCESS_CALENDARS = NO;
ENABLE_RESOURCE_ACCESS_CAMERA = NO;
ENABLE_RESOURCE_ACCESS_CONTACTS = NO;
ENABLE_RESOURCE_ACCESS_LOCATION = NO;
ENABLE_RESOURCE_ACCESS_PRINTING = NO;
ENABLE_RESOURCE_ACCESS_USB = NO;
ENABLE_USER_SELECTED_FILES = readonly;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = Scream/Info.plist;
INFOPLIST_KEY_NSHumanReadableCopyright = "";
INFOPLIST_KEY_NSMainNibFile = MainMenu;
INFOPLIST_KEY_NSPrincipalClass = NSApplication;
@@ -433,8 +490,19 @@
DEVELOPMENT_TEAM = 8JGND254B7;
ENABLE_APP_SANDBOX = YES;
ENABLE_HARDENED_RUNTIME = YES;
ENABLE_INCOMING_NETWORK_CONNECTIONS = YES;
ENABLE_OUTGOING_NETWORK_CONNECTIONS = YES;
ENABLE_RESOURCE_ACCESS_AUDIO_INPUT = NO;
ENABLE_RESOURCE_ACCESS_BLUETOOTH = NO;
ENABLE_RESOURCE_ACCESS_CALENDARS = NO;
ENABLE_RESOURCE_ACCESS_CAMERA = NO;
ENABLE_RESOURCE_ACCESS_CONTACTS = NO;
ENABLE_RESOURCE_ACCESS_LOCATION = NO;
ENABLE_RESOURCE_ACCESS_PRINTING = NO;
ENABLE_RESOURCE_ACCESS_USB = NO;
ENABLE_USER_SELECTED_FILES = readonly;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = Scream/Info.plist;
INFOPLIST_KEY_NSHumanReadableCopyright = "";
INFOPLIST_KEY_NSMainNibFile = MainMenu;
INFOPLIST_KEY_NSPrincipalClass = NSApplication;

View File

@@ -9,9 +9,15 @@ import Cocoa
@main
class AppDelegate: NSObject, NSApplicationDelegate {
let sr = ScreenRecorder()
@IBOutlet var window: NSWindow!
@IBAction func Button(_ sender: Any) {
Task {
await sr.start()
}
}
func applicationDidFinishLaunching(_ aNotification: Notification) {
// Insert code here to initialize your application

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="17150" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="24506" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="17150"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="24506"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
@@ -11,8 +11,8 @@
</connections>
</customObject>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application"/>
<customObject id="Voe-Tx-rLC" customClass="AppDelegate" customModuleProvider="target">
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
<customObject id="Voe-Tx-rLC" customClass="AppDelegate" customModule="Scream" customModuleProvider="target">
<connections>
<outlet property="window" destination="QvC-M9-y7g" id="gIp-Ho-8D9"/>
</connections>
@@ -684,10 +684,23 @@
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
<rect key="contentRect" x="335" y="390" width="480" height="360"/>
<rect key="screenRect" x="0.0" y="0.0" width="2560" height="1415"/>
<rect key="screenRect" x="0.0" y="0.0" width="3200" height="1775"/>
<view key="contentView" id="EiT-Mj-1SZ">
<rect key="frame" x="0.0" y="0.0" width="480" height="360"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="8In-w0-vJZ">
<rect key="frame" x="203" y="163" width="75" height="32"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="push" title="Button" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="ycE-q8-8mw">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="Button:" target="Voe-Tx-rLC" id="9Qu-NJ-TM0"/>
</connections>
</button>
</subviews>
</view>
<connections>
<outlet property="delegate" destination="Voe-Tx-rLC" id="top-28-M4D"/>

5
Scream/Info.plist Normal file
View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict/>
</plist>

View File

@@ -0,0 +1,31 @@
//
// SCStreamOutput.swift
// Scream
//
// Created by neon443 on 01/01/2026.
//
import Foundation
import ScreenCaptureKit
class StreamOutputDelegate: NSObject, SCStreamOutput {
func stream(_ stream: SCStream, didOutputSampleBuffer sampleBuffer: CMSampleBuffer, of type: SCStreamOutputType) {
guard sampleBuffer.isValid else { return }
switch type {
case .screen:
print("got a screen buffer")
guard let attachmentsArr = CMSampleBufferGetSampleAttachmentsArray(
sampleBuffer,
createIfNecessary: false
) as? [[SCStreamFrameInfo: Any]],
let attachments = attachmentsArr.first else { return }
case .audio:
print("got an audio buffer")
case .microphone:
print("got a mic buffer")
@unknown default:
fatalError("wtf is ur stream sample type")
}
}
}

View File

@@ -0,0 +1,83 @@
//
// ScreenRecorder.swift
// Scream
//
// Created by neon443 on 31/12/2025.
//
import Foundation
import ScreenCaptureKit
class ScreenRecorder: NSObject {
var isRunning: Bool = false
var isAppExluded: Bool = false
var isAudioEnabled: Bool = true
var filter: SCContentFilter?
var streamConfig = SCStreamConfiguration()
var stream: SCStream?
var streamDelegate = StreamDelegate()
var streamOutput = StreamOutputDelegate()
let videoSampleBufferQueue = DispatchQueue(label: "videoSampleBufferQueue")
let audioSampleBufferQueue = DispatchQueue(label: "audioSampleBufferQueue")
var canRecord: Bool {
true
}
func start() async {
guard !isRunning else { return }
let availableContent: SCShareableContent
do {
availableContent = try await SCShareableContent.excludingDesktopWindows(false, onScreenWindowsOnly: true)
} catch {
print(error.localizedDescription)
return
}
var excludedApps = [SCRunningApplication]()
//if users exclude Scream from the screen share
//exclude by matching bundleid
if isAppExluded {
excludedApps = availableContent.applications.filter { app in
Bundle.main.bundleIdentifier == app.bundleIdentifier
}
}
filter = SCContentFilter(display: availableContent.displays.first!, excludingApplications: excludedApps, exceptingWindows: [])
//TODO: hdr
streamConfig.capturesAudio = isAudioEnabled
streamConfig.excludesCurrentProcessAudio = true
// streamConfig.captureMicrophone = true
streamConfig.width = Int(NSScreen.main?.frame.width ?? 100)
streamConfig.height = Int(NSScreen.main?.frame.height ?? 100)
streamConfig.minimumFrameInterval = CMTime(value: 1, timescale: 20)
streamConfig.queueDepth = 5
stream = SCStream(filter: filter!, configuration: streamConfig, delegate: streamDelegate)
try! stream?.addStreamOutput(streamOutput, type: .screen, sampleHandlerQueue: videoSampleBufferQueue)
try! stream?.addStreamOutput(streamOutput, type: .audio, sampleHandlerQueue: audioSampleBufferQueue)
// try! stream?.addStreamOutput(streamOutput, type: .microphone, sampleHandlerQueue: videoSampleBufferQueue)
//update the config using stream.updateConfiguration or .updateContentFilter
}
}
extension ScreenRecorder: SCContentSharingPickerObserver {
func contentSharingPicker(_ picker: SCContentSharingPicker, didCancelFor stream: SCStream?) {
print("canceleed picker")
}
func contentSharingPicker(_ picker: SCContentSharingPicker, didUpdateWith filter: SCContentFilter, for stream: SCStream?) {
print(picker.description)
}
func contentSharingPickerStartDidFailWithError(_ error: any Error) {
print(error.localizedDescription)
}
}

View File

@@ -0,0 +1,31 @@
//
// StreamDelegate.swift
// Scream
//
// Created by neon443 on 01/01/2026.
//
import Foundation
import ScreenCaptureKit
class StreamDelegate: NSObject, SCStreamDelegate {
func outputVideoEffectDidStart(for stream: SCStream) {
print("presenter overlay started")
}
func outputVideoEffectDidStop(for stream: SCStream) {
print("presenter overlay stopped")
}
func streamDidBecomeActive(_ stream: SCStream) {
print("stream became Active")
}
func streamDidBecomeInactive(_ stream: SCStream) {
print("stream became Inactive")
}
func stream(_ stream: SCStream, didStopWithError error: any Error) {
print(error.localizedDescription)
}
}