-
-
Notifications
You must be signed in to change notification settings - Fork 626
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1123 from shogo4405/feature/add-screencapturekit
Support ScreenCaptureKit on macOS
- Loading branch information
Showing
7 changed files
with
315 additions
and
33 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import AppKit | ||
import Foundation | ||
|
||
final class PreferenceViewController: NSViewController { | ||
@IBOutlet private weak var urlField: NSTextField! | ||
@IBOutlet private weak var streamNameField: NSTextField! | ||
|
||
override func viewDidLoad() { | ||
super.viewDidLoad() | ||
urlField.stringValue = Preference.defaultInstance.uri ?? "" | ||
streamNameField.stringValue = Preference.defaultInstance.streamName ?? "" | ||
} | ||
} | ||
|
||
extension PreferenceViewController: NSTextFieldDelegate { | ||
func controlTextDidChange(_ obj: Notification) { | ||
guard let textFile = obj.object as? NSTextField else { | ||
return | ||
} | ||
if textFile == urlField { | ||
Preference.defaultInstance.uri = textFile.stringValue | ||
} | ||
if textFile == streamNameField { | ||
Preference.defaultInstance.streamName = textFile.stringValue | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
import AppKit | ||
import Foundation | ||
import HaishinKit | ||
#if canImport(ScreenCaptureKit) | ||
import ScreenCaptureKit | ||
#endif | ||
|
||
class SCStreamPublishViewController: NSViewController { | ||
@IBOutlet private weak var cameraPopUpButton: NSPopUpButton! | ||
@IBOutlet private weak var urlField: NSTextField! | ||
|
||
private var currentStream: NetStream? | ||
private var rtmpConnection = RTMPConnection() | ||
private lazy var rtmpStream: RTMPStream = { | ||
let rtmpStream = RTMPStream(connection: rtmpConnection) | ||
return rtmpStream | ||
}() | ||
|
||
private var _stream: Any? | ||
|
||
@available(macOS 12.3, *) | ||
private var stream: SCStream? { | ||
get { | ||
_stream as? SCStream | ||
} | ||
set { | ||
_stream = newValue | ||
Task { | ||
try? newValue?.addStreamOutput(rtmpStream, type: .screen, sampleHandlerQueue: DispatchQueue.main) | ||
if #available(macOS 13.0, *) { | ||
try? newValue?.addStreamOutput(rtmpStream, type: .audio, sampleHandlerQueue: DispatchQueue.main) | ||
} | ||
try? await newValue?.startCapture() | ||
} | ||
} | ||
} | ||
|
||
override func viewDidLoad() { | ||
super.viewDidLoad() | ||
urlField.stringValue = Preference.defaultInstance.uri ?? "" | ||
if #available(macOS 12.3, *) { | ||
Task { | ||
try await SCShareableContent.current.windows.forEach { | ||
cameraPopUpButton.addItem(withTitle: $0.owningApplication?.applicationName ?? "") | ||
} | ||
} | ||
} | ||
} | ||
|
||
override func viewWillAppear() { | ||
super.viewWillAppear() | ||
currentStream = rtmpStream | ||
} | ||
|
||
@IBAction private func selectCamera(_ sender: AnyObject) { | ||
if #available(macOS 12.3, *) { | ||
Task { | ||
guard let window = try? await SCShareableContent.current.windows.first(where: { $0.owningApplication?.applicationName == cameraPopUpButton.title }) else { | ||
return | ||
} | ||
let filter = SCContentFilter(desktopIndependentWindow: window) | ||
let configuration = SCStreamConfiguration() | ||
configuration.width = Int(window.frame.width) | ||
configuration.height = Int(window.frame.height) | ||
configuration.showsCursor = true | ||
self.stream = SCStream(filter: filter, configuration: configuration, delegate: nil) | ||
} | ||
} | ||
} | ||
|
||
@IBAction private func publishOrStop(_ sender: NSButton) { | ||
// Publish | ||
if sender.title == "Publish" { | ||
sender.title = "Stop" | ||
rtmpConnection.addEventListener(.rtmpStatus, selector: #selector(rtmpStatusHandler), observer: self) | ||
rtmpConnection.connect(Preference.defaultInstance.uri ?? "") | ||
return | ||
} | ||
// Stop | ||
sender.title = "Publish" | ||
rtmpConnection.removeEventListener(.rtmpStatus, selector: #selector(rtmpStatusHandler), observer: self) | ||
rtmpConnection.close() | ||
return | ||
} | ||
|
||
@objc | ||
private func rtmpStatusHandler(_ notification: Notification) { | ||
let e = Event.from(notification) | ||
guard | ||
let data: ASObject = e.data as? ASObject, | ||
let code: String = data["code"] as? String else { | ||
return | ||
} | ||
logger.info(data) | ||
switch code { | ||
case RTMPConnection.Code.connectSuccess.rawValue: | ||
rtmpStream.publish(Preference.defaultInstance.streamName) | ||
default: | ||
break | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters