Skip to content

Commit

Permalink
overlay app picker
Browse files Browse the repository at this point in the history
  • Loading branch information
jcm committed Jan 25, 2024
1 parent 78fca07 commit c93fe5b
Show file tree
Hide file tree
Showing 13 changed files with 504 additions and 287 deletions.
2 changes: 2 additions & 0 deletions CaptureSample/CaptureEngine.swift
Original file line number Diff line number Diff line change
Expand Up @@ -157,8 +157,10 @@ class CaptureEngineStreamOutput: NSObject, SCStreamOutput, SCStreamDelegate {
switch outputType {
case .screen:
if let frame = self.createFrame(for: sampleBuffer) {
IOSurfaceLock(frame.surface!, [], nil)
self.capturedFrameHandler?(frame)
self.sink.enqueue(frame.surface!)
IOSurfaceUnlock(frame.surface!, [], nil)
}
case .audio:
if let copy = self.createAudioFrame(for: sampleBuffer) {
Expand Down
52 changes: 48 additions & 4 deletions CaptureSample/RecordCameraStreamSink.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ class RecordCameraStreamSink: NSObject {
private var timer: Timer?
private var propTimer: Timer?

func getJustProperty(streamId: CMIOStreamID) -> String? {
let selector = "just".convertedToCMIOObjectPropertySelectorName()
func getTestProperty(streamId: CMIOStreamID) -> String? {
let selector = FourCharCode("just")
var address = CMIOObjectPropertyAddress(selector, .global, .main)
let exists = CMIOObjectHasProperty(streamId, &address)
if exists {
Expand All @@ -45,8 +45,8 @@ class RecordCameraStreamSink: NSObject {
}
}

func setJustProperty(streamId: CMIOStreamID, newValue: String) {
let selector = "just".convertedToCMIOObjectPropertySelectorName()
func setTestProperty(streamId: CMIOStreamID, newValue: String) {
let selector = FourCharCode("just")
var address = CMIOObjectPropertyAddress(selector, .global, .main)
let exists = CMIOObjectHasProperty(streamId, &address)
if exists {
Expand All @@ -59,6 +59,7 @@ class RecordCameraStreamSink: NSObject {
CMIOObjectGetPropertyDataSize(streamId, &address, 0, nil, &dataSize)
var newName: CFString = newValue as NSString
CMIOObjectSetPropertyData(streamId, &address, 0, nil, dataSize, &newName)
print("setting test property")
}
}

Expand Down Expand Up @@ -179,6 +180,7 @@ class RecordCameraStreamSink: NSObject {
if let sbuf = sbuf {
let pointerRef = UnsafeMutableRawPointer(Unmanaged.passRetained(sbuf).toOpaque())
CMSimpleQueueEnqueue(self.sinkQueue!, element: pointerRef)
self.setTestProperty(streamId: self.sourceStream!, newValue: "a")
}
}
} else {
Expand All @@ -188,6 +190,48 @@ class RecordCameraStreamSink: NSObject {

}

extension FourCharCode: ExpressibleByStringLiteral {

public init(stringLiteral value: StringLiteralType) {
var code: FourCharCode = 0
// Value has to consist of 4 printable ASCII characters, e.g. '420v'.
// Note: This implementation does not enforce printable range (32-126)
if value.count == 4 && value.utf8.count == 4 {
for byte in value.utf8 {
code = code << 8 + FourCharCode(byte)
}
}
else {
print("FourCharCode: Can't initialize with '\(value)', only printable ASCII allowed. Setting to '????'.")
code = 0x3F3F3F3F // = '????'
}
self = code
}

public init(extendedGraphemeClusterLiteral value: String) {
self = FourCharCode(stringLiteral: value)
}

public init(unicodeScalarLiteral value: String) {
self = FourCharCode(stringLiteral: value)
}

public init(_ value: String) {
self = FourCharCode(stringLiteral: value)
}

public var string: String? {
let cString: [CChar] = [
CChar(self >> 24 & 0xFF),
CChar(self >> 16 & 0xFF),
CChar(self >> 8 & 0xFF),
CChar(self & 0xFF),
0
]
return String(cString: cString)
}
}

extension String {
func convertedToCMIOObjectPropertySelectorName() -> CMIOObjectPropertySelector {
let noName: CMIOObjectPropertySelector = 0
Expand Down
10 changes: 6 additions & 4 deletions CaptureSample/ScreenRecorder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import Combine
import OSLog
import SwiftUI
import AVFoundation
import com_jcm_record_RecordVirtualCam
import SystemExtensions

/// A provider of audio levels from the captured samples.
Expand Down Expand Up @@ -199,7 +198,7 @@ class ScreenRecorder: ObservableObject {
didSet { updateEngine() }
}

@Published var selectedApplications = Set<String>() {
@Published var selectedApplications = Set<SCRunningApplication>() {
willSet {
print("setting selected applications \(newValue)")
}
Expand All @@ -209,6 +208,8 @@ class ScreenRecorder: ObservableObject {
}
}

@State var bindingBool = [String : Binding<Bool>]()

@AppStorage("excludeSelf") var isAppExcluded = true {
didSet { updateEngine() }
}
Expand Down Expand Up @@ -574,7 +575,7 @@ class ScreenRecorder: ObservableObject {
}

func testSetProperty() {
print("poop")
print("a")
}

/// - Tag: UpdateFilter
Expand All @@ -587,7 +588,7 @@ class ScreenRecorder: ObservableObject {
// If a user chooses to exclude the app from the stream,
// exclude it by matching its bundle identifier.
excludedApps = availableApps.filter { app in
self.selectedApplications.contains(app.id)
!self.selectedApplications.contains(app)
}
// Create a content filter with excluded apps.
filter = SCContentFilter(display: display,
Expand Down Expand Up @@ -674,6 +675,7 @@ class ScreenRecorder: ObservableObject {
availableWindows = windows
}
availableApps = availableContent.applications
selectedApplications = Set<SCRunningApplication>(availableApps.filter({UserDefaults.standard.bool(forKey: $0.bundleIdentifier) == true}))

if selectedDisplay == nil {
selectedDisplay = availableDisplays.first
Expand Down
107 changes: 107 additions & 0 deletions CaptureSample/Views/CaptureConfigurationOverlay.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
//
// CaptureConfigurationOverlay.swift
// Record
//
// Created by John Moody on 1/21/24.
// Copyright © 2024 jcm. All rights reserved.
//

import SwiftUI
import ScreenCaptureKit

struct CaptureConfigurationOverlay: View {
@ObservedObject var screenRecorder: ScreenRecorder

var availableApps = [SCRunningApplication]()

var columns = [GridItem(.flexible(minimum: 100, maximum: 200)), GridItem(.flexible(minimum: 100, maximum: 200))]

var body: some View {

switch screenRecorder.captureType {
case .display:
GroupBox {
LazyVGrid(columns: columns) {
ForEach(screenRecorder.availableApps, id: \.self) { app in
VStack {
HStack {
Toggle("butt", isOn: Binding( get: {
return screenRecorder.selectedApplications.contains(app)
}, set: { isOn in
if isOn { screenRecorder.selectedApplications.insert(app) }
else { screenRecorder.selectedApplications.remove(app) }
UserDefaults.standard.setValue(isOn, forKey: app.bundleIdentifier)
}))
.controlSize(.large)
Text(app.applicationName)
.font(.title2)
.tag(app)
.fontWeight(.regular)
.opacity(0.8)
Spacer(minLength: 1)
Rectangle()
.fill(.quinary)
//.padding(EdgeInsets(top: -20, leading: 0, bottom: -20, trailing: 0))
.frame(width: 1, height: 200)
}
.frame(height: 25)
Rectangle()
.fill(.quinary)
.frame(width: 1000, height: 1)
//.padding(EdgeInsets(top: 0, leading: -20, bottom: 0, trailing: -20))
.gridCellColumns(2)
}
}
}
.padding(EdgeInsets(top: 20, leading: 0, bottom: 20, trailing: -32))
}
/*Grid {
List(screenRecorder.availableApps, selection: $screenRecorder.selectedApplications) { app in
HStack {
Toggle("butt", isOn: Binding( get: {
return screenRecorder.selectedApplications.contains(app)
}, set: { isOn in
if isOn { screenRecorder.selectedApplications.insert(app) }
else { screenRecorder.selectedApplications.remove(app) }
}))
.controlSize(.large)
Text(app.applicationName)
.font(.title2)
.frame(height: 30)
.tag(app)
}
}
}*/
.frame(width: 440)
.labelsHidden()
.background(OverlayMaterialView())
.cornerRadius(20.0)
//.padding(EdgeInsets(top: 50, leading: 0, bottom: 50, trailing: 0))
//.opacity(0.6)




case .window:
Picker("Window", selection: $screenRecorder.selectedWindow) {
ForEach(screenRecorder.availableWindows, id: \.self) { window in
Text(window.displayName)
.tag(SCWindow?.some(window))
}
}
.onHover(perform: { hovering in
Task {
await self.screenRecorder.refreshAvailableContent()
}
})
}

}
}

struct ApplicationProxy: Identifiable {
var id: ObjectIdentifier

var isToggled = false
var application: SCRunningApplication
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,12 @@ import SwiftUI
struct AudioConfigurationView: View {
@ObservedObject var screenRecorder: ScreenRecorder
var body: some View {
VStack(alignment: .trailing) {
Toggle("Capture audio", isOn: $screenRecorder.isAudioCaptureEnabled)
.padding(EdgeInsets(top: 0, leading: 48, bottom: 0, trailing: 0))
.controlSize(.small)
GroupBox {
VStack(alignment: .imageTitleAlignmentGuide) {
Toggle("Capture audio", isOn: $screenRecorder.isAudioCaptureEnabled)
.padding(EdgeInsets(top: 0, leading: 48, bottom: 0, trailing: 0))
.controlSize(.small)
}
}
.modifier(ConfigurationSubViewStyle())
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ struct ConfigurationSubViewStyle: ViewModifier {
.frame(width: 260)
.padding(EdgeInsets(top: 13, leading: 15, bottom: 13, trailing: 15))
.controlSize(.small)
.background(.quinary, in: RoundedRectangle(cornerRadius: 5))
.overlay(
//.background(.quinary, in: RoundedRectangle(cornerRadius: 5))
/*.overlay(
RoundedRectangle(cornerRadius: 5)
.stroke(Color(.quinaryLabel), lineWidth: 1)
)
)*/
}
}
Loading

0 comments on commit c93fe5b

Please sign in to comment.