add udpserver

switch to hevc in videotoolbox
move capturevideopreview to its own file
reorg
This commit is contained in:
neon443
2026-02-26 19:50:38 +00:00
parent 739b19bfb3
commit d412bc8824
6 changed files with 102 additions and 20 deletions

View File

@@ -8,6 +8,8 @@
/* Begin PBXBuildFile section */
A94E29F72F09B569006E583D /* ScreamPacket.swift in Sources */ = {isa = PBXBuildFile; fileRef = A94E29F62F09B569006E583D /* ScreamPacket.swift */; };
A98010132F50D19D00A58EF7 /* UDPServer.swift in Sources */ = {isa = PBXBuildFile; fileRef = A98010122F50D19D00A58EF7 /* UDPServer.swift */; };
A98010152F50D9B100A58EF7 /* CaptureVideoPreview.swift in Sources */ = {isa = PBXBuildFile; fileRef = A98010142F50D9B100A58EF7 /* CaptureVideoPreview.swift */; };
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 */; };
@@ -38,6 +40,8 @@
/* Begin PBXFileReference section */
A94E29F62F09B569006E583D /* ScreamPacket.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScreamPacket.swift; sourceTree = "<group>"; };
A98010122F50D19D00A58EF7 /* UDPServer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UDPServer.swift; sourceTree = "<group>"; };
A98010142F50D9B100A58EF7 /* CaptureVideoPreview.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CaptureVideoPreview.swift; sourceTree = "<group>"; };
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; };
@@ -81,9 +85,7 @@
A98E8BB72F05B26B006D4458 = {
isa = PBXGroup;
children = (
A94E29F62F09B569006E583D /* ScreamPacket.swift */,
A9D722602F07304C00050BB0 /* Config.xcconfig */,
A9D7225E2F070FE600050BB0 /* CaptureEngine.swift */,
A98E8BEF2F05B2A0006D4458 /* Scream */,
A98E8BF42F05B2A2006D4458 /* ScreamTests */,
A98E8BF82F05B2A5006D4458 /* ScreamUITests */,
@@ -109,6 +111,10 @@
A98E8BEC2F05B2A0006D4458 /* Assets.xcassets */,
A98E8BEE2F05B2A0006D4458 /* MainMenu.xib */,
A98E8BFC2F05D28D006D4458 /* ScreenRecorder.swift */,
A98010122F50D19D00A58EF7 /* UDPServer.swift */,
A9D7225E2F070FE600050BB0 /* CaptureEngine.swift */,
A94E29F62F09B569006E583D /* ScreamPacket.swift */,
A98010142F50D9B100A58EF7 /* CaptureVideoPreview.swift */,
);
path = Scream;
sourceTree = "<group>";
@@ -272,6 +278,8 @@
A98E8BF02F05B2A0006D4458 /* AppDelegate.swift in Sources */,
A9D7225F2F070FE600050BB0 /* CaptureEngine.swift in Sources */,
A98E8BFD2F05D28D006D4458 /* ScreenRecorder.swift in Sources */,
A98010132F50D19D00A58EF7 /* UDPServer.swift in Sources */,
A98010152F50D9B100A58EF7 /* CaptureVideoPreview.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};

View File

@@ -10,6 +10,7 @@ import Cocoa
@main
class AppDelegate: NSObject, NSApplicationDelegate {
let sr = ScreenRecorder()
let udpserver = UDPServerImplementation(port: 03067)
@IBOutlet var window: NSWindow!
@@ -18,6 +19,9 @@ class AppDelegate: NSObject, NSApplicationDelegate {
await sr.start()
}
}
@IBAction func Button2(_ sender: Any) {
udpserver.start()
}
func applicationDidFinishLaunching(_ aNotification: Notification) {
// Insert code here to initialize your application
@@ -25,6 +29,7 @@ class AppDelegate: NSObject, NSApplicationDelegate {
preview.frame.size = window.contentView!.frame.size
window.contentView?.addSubview(preview)
Button(self)
Button2(self)
}
func applicationWillTerminate(_ aNotification: Notification) {
@@ -34,19 +39,4 @@ class AppDelegate: NSObject, NSApplicationDelegate {
func applicationSupportsSecureRestorableState(_ app: NSApplication) -> Bool {
return true
}
}
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

@@ -42,7 +42,7 @@ class CaptureEngine: NSObject {
allocator: kCFAllocatorDefault,
width: 3200,
height: 1800,
codecType: kCMVideoCodecType_H264,
codecType: kCMVideoCodecType_HEVC,
encoderSpecification: videoEncoderSpec,
imageBufferAttributes: sourceImageBufferAttrs,
compressedDataAllocator: nil,
@@ -71,7 +71,7 @@ class CaptureEngine: NSObject {
frameProperties: nil,
infoFlagsOut: nil
) { status, infoFlags, sampleBuffer in
print()
// print()
}
// outputHandler: self.outputHandler)
@@ -144,7 +144,7 @@ class CaptureEngine: NSObject {
err = VTSessionSetProperty(session, key: kVTCompressionPropertyKey_ExpectedFrameRate, value: expectedFrameRate as CFNumber)
if err != noErr { print("failed to set to framerte \(err)") }
err = VTSessionSetProperty(session, key: kVTCompressionPropertyKey_ProfileLevel, value: kVTProfileLevel_H264_Main_AutoLevel)
err = VTSessionSetProperty(session, key: kVTCompressionPropertyKey_ProfileLevel, value: kVTProfileLevel_HEVC_Main_AutoLevel)
if err != noErr { print("failed to set to profile level \(err)") }
err = VTSessionSetProperty(session, key: kVTCompressionPropertyKey_AverageBitRate, value: 10 as CFNumber)

View File

@@ -0,0 +1,22 @@
//
// CaptureVideoPreview.swift
// Scream
//
// Created by neon443 on 26/02/2026.
//
import Foundation
import Cocoa
class CaptureVideoPreview: NSView {
init(layer: CALayer) {
super.init(frame: .zero)
wantsLayer = true
self.layer = layer
layer.autoresizingMask = [.layerWidthSizable, .layerHeightSizable]
}
required init?(coder: NSCoder) {
fatalError()
}
}

62
Scream/UDPServer.swift Normal file
View File

@@ -0,0 +1,62 @@
//
// UDPServer.swift
// Scream
//
// Created by neon443 on 26/02/2026.
//
import Foundation
import Network
final class UDPServerImplementation: Sendable {
private let connectionListener: NWListener
//init a udp server at x port
init(port: UInt16) {
connectionListener = try! NWListener(
using: .udp,
on: NWEndpoint.Port(integerLiteral: port)
)
connectionListener.newConnectionHandler = { [weak self] connection in
connection.start(queue: .global())
self?.receive(on: connection)
}
connectionListener.stateUpdateHandler = { state in
print("state: \(state)")
}
}
}
protocol UDPServer {
func start()
func stop()
}
extension UDPServerImplementation: UDPServer {
func start() {
connectionListener.start(queue: .global())
print("server started")
}
func stop() {
connectionListener.cancel()
print("server stoped")
}
}
private extension UDPServerImplementation {
func receive(on connection: NWConnection) {
connection.receiveMessage { data, contentContext, isComplete, error in
if let error {
print("error \(error)")
}
if let data,
let message = String(data: data, encoding: .utf8) {
print(message)
}
}
}
}