mirror of
https://github.com/neon443/Scream.git
synced 2026-03-11 13:26:18 +00:00
add udpserver
switch to hevc in videotoolbox move capturevideopreview to its own file reorg
This commit is contained in:
@@ -8,6 +8,8 @@
|
|||||||
|
|
||||||
/* Begin PBXBuildFile section */
|
/* Begin PBXBuildFile section */
|
||||||
A94E29F72F09B569006E583D /* ScreamPacket.swift in Sources */ = {isa = PBXBuildFile; fileRef = A94E29F62F09B569006E583D /* ScreamPacket.swift */; };
|
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 */; };
|
A98E8BF02F05B2A0006D4458 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = A98E8BEB2F05B2A0006D4458 /* AppDelegate.swift */; };
|
||||||
A98E8BF12F05B2A0006D4458 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = A98E8BEC2F05B2A0006D4458 /* Assets.xcassets */; };
|
A98E8BF12F05B2A0006D4458 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = A98E8BEC2F05B2A0006D4458 /* Assets.xcassets */; };
|
||||||
A98E8BF22F05B2A0006D4458 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = A98E8BEE2F05B2A0006D4458 /* MainMenu.xib */; };
|
A98E8BF22F05B2A0006D4458 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = A98E8BEE2F05B2A0006D4458 /* MainMenu.xib */; };
|
||||||
@@ -38,6 +40,8 @@
|
|||||||
|
|
||||||
/* Begin PBXFileReference section */
|
/* Begin PBXFileReference section */
|
||||||
A94E29F62F09B569006E583D /* ScreamPacket.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScreamPacket.swift; sourceTree = "<group>"; };
|
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; };
|
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; };
|
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; };
|
A98E8BD82F05B26D006D4458 /* ScreamUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ScreamUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
@@ -81,9 +85,7 @@
|
|||||||
A98E8BB72F05B26B006D4458 = {
|
A98E8BB72F05B26B006D4458 = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
A94E29F62F09B569006E583D /* ScreamPacket.swift */,
|
|
||||||
A9D722602F07304C00050BB0 /* Config.xcconfig */,
|
A9D722602F07304C00050BB0 /* Config.xcconfig */,
|
||||||
A9D7225E2F070FE600050BB0 /* CaptureEngine.swift */,
|
|
||||||
A98E8BEF2F05B2A0006D4458 /* Scream */,
|
A98E8BEF2F05B2A0006D4458 /* Scream */,
|
||||||
A98E8BF42F05B2A2006D4458 /* ScreamTests */,
|
A98E8BF42F05B2A2006D4458 /* ScreamTests */,
|
||||||
A98E8BF82F05B2A5006D4458 /* ScreamUITests */,
|
A98E8BF82F05B2A5006D4458 /* ScreamUITests */,
|
||||||
@@ -109,6 +111,10 @@
|
|||||||
A98E8BEC2F05B2A0006D4458 /* Assets.xcassets */,
|
A98E8BEC2F05B2A0006D4458 /* Assets.xcassets */,
|
||||||
A98E8BEE2F05B2A0006D4458 /* MainMenu.xib */,
|
A98E8BEE2F05B2A0006D4458 /* MainMenu.xib */,
|
||||||
A98E8BFC2F05D28D006D4458 /* ScreenRecorder.swift */,
|
A98E8BFC2F05D28D006D4458 /* ScreenRecorder.swift */,
|
||||||
|
A98010122F50D19D00A58EF7 /* UDPServer.swift */,
|
||||||
|
A9D7225E2F070FE600050BB0 /* CaptureEngine.swift */,
|
||||||
|
A94E29F62F09B569006E583D /* ScreamPacket.swift */,
|
||||||
|
A98010142F50D9B100A58EF7 /* CaptureVideoPreview.swift */,
|
||||||
);
|
);
|
||||||
path = Scream;
|
path = Scream;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@@ -272,6 +278,8 @@
|
|||||||
A98E8BF02F05B2A0006D4458 /* AppDelegate.swift in Sources */,
|
A98E8BF02F05B2A0006D4458 /* AppDelegate.swift in Sources */,
|
||||||
A9D7225F2F070FE600050BB0 /* CaptureEngine.swift in Sources */,
|
A9D7225F2F070FE600050BB0 /* CaptureEngine.swift in Sources */,
|
||||||
A98E8BFD2F05D28D006D4458 /* ScreenRecorder.swift in Sources */,
|
A98E8BFD2F05D28D006D4458 /* ScreenRecorder.swift in Sources */,
|
||||||
|
A98010132F50D19D00A58EF7 /* UDPServer.swift in Sources */,
|
||||||
|
A98010152F50D9B100A58EF7 /* CaptureVideoPreview.swift in Sources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import Cocoa
|
|||||||
@main
|
@main
|
||||||
class AppDelegate: NSObject, NSApplicationDelegate {
|
class AppDelegate: NSObject, NSApplicationDelegate {
|
||||||
let sr = ScreenRecorder()
|
let sr = ScreenRecorder()
|
||||||
|
let udpserver = UDPServerImplementation(port: 03067)
|
||||||
|
|
||||||
@IBOutlet var window: NSWindow!
|
@IBOutlet var window: NSWindow!
|
||||||
|
|
||||||
@@ -18,6 +19,9 @@ class AppDelegate: NSObject, NSApplicationDelegate {
|
|||||||
await sr.start()
|
await sr.start()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@IBAction func Button2(_ sender: Any) {
|
||||||
|
udpserver.start()
|
||||||
|
}
|
||||||
|
|
||||||
func applicationDidFinishLaunching(_ aNotification: Notification) {
|
func applicationDidFinishLaunching(_ aNotification: Notification) {
|
||||||
// Insert code here to initialize your application
|
// Insert code here to initialize your application
|
||||||
@@ -25,6 +29,7 @@ class AppDelegate: NSObject, NSApplicationDelegate {
|
|||||||
preview.frame.size = window.contentView!.frame.size
|
preview.frame.size = window.contentView!.frame.size
|
||||||
window.contentView?.addSubview(preview)
|
window.contentView?.addSubview(preview)
|
||||||
Button(self)
|
Button(self)
|
||||||
|
Button2(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
func applicationWillTerminate(_ aNotification: Notification) {
|
func applicationWillTerminate(_ aNotification: Notification) {
|
||||||
@@ -34,19 +39,4 @@ class AppDelegate: NSObject, NSApplicationDelegate {
|
|||||||
func applicationSupportsSecureRestorableState(_ app: NSApplication) -> Bool {
|
func applicationSupportsSecureRestorableState(_ app: NSApplication) -> Bool {
|
||||||
return true
|
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()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ class CaptureEngine: NSObject {
|
|||||||
allocator: kCFAllocatorDefault,
|
allocator: kCFAllocatorDefault,
|
||||||
width: 3200,
|
width: 3200,
|
||||||
height: 1800,
|
height: 1800,
|
||||||
codecType: kCMVideoCodecType_H264,
|
codecType: kCMVideoCodecType_HEVC,
|
||||||
encoderSpecification: videoEncoderSpec,
|
encoderSpecification: videoEncoderSpec,
|
||||||
imageBufferAttributes: sourceImageBufferAttrs,
|
imageBufferAttributes: sourceImageBufferAttrs,
|
||||||
compressedDataAllocator: nil,
|
compressedDataAllocator: nil,
|
||||||
@@ -71,7 +71,7 @@ class CaptureEngine: NSObject {
|
|||||||
frameProperties: nil,
|
frameProperties: nil,
|
||||||
infoFlagsOut: nil
|
infoFlagsOut: nil
|
||||||
) { status, infoFlags, sampleBuffer in
|
) { status, infoFlags, sampleBuffer in
|
||||||
print()
|
// print()
|
||||||
|
|
||||||
}
|
}
|
||||||
// outputHandler: self.outputHandler)
|
// outputHandler: self.outputHandler)
|
||||||
@@ -144,7 +144,7 @@ class CaptureEngine: NSObject {
|
|||||||
err = VTSessionSetProperty(session, key: kVTCompressionPropertyKey_ExpectedFrameRate, value: expectedFrameRate as CFNumber)
|
err = VTSessionSetProperty(session, key: kVTCompressionPropertyKey_ExpectedFrameRate, value: expectedFrameRate as CFNumber)
|
||||||
if err != noErr { print("failed to set to framerte \(err)") }
|
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)") }
|
if err != noErr { print("failed to set to profile level \(err)") }
|
||||||
|
|
||||||
err = VTSessionSetProperty(session, key: kVTCompressionPropertyKey_AverageBitRate, value: 10 as CFNumber)
|
err = VTSessionSetProperty(session, key: kVTCompressionPropertyKey_AverageBitRate, value: 10 as CFNumber)
|
||||||
22
Scream/CaptureVideoPreview.swift
Normal file
22
Scream/CaptureVideoPreview.swift
Normal 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
62
Scream/UDPServer.swift
Normal 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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user