diff --git a/Common/Localizable.xcstrings b/Common/Localizable.xcstrings index 7c22aca6f..d8ec9e77c 100644 --- a/Common/Localizable.xcstrings +++ b/Common/Localizable.xcstrings @@ -58276,6 +58276,9 @@ } } } + }, + "Force scene switch transition" : { + }, "Foreground" : { "localizations" : { @@ -100417,6 +100420,9 @@ } } } + }, + "RTMP, SRT(LA), screen capture and media player video sources can instantly be switched to, but if you want consistency you can force scene switch transitions to these as well." : { + }, "rtmp://a.rtmp.youtube.com/live2" : { "localizations" : { diff --git a/Moblin/Various/Media.swift b/Moblin/Various/Media.swift index 185a89314..cc4db724e 100644 --- a/Moblin/Various/Media.swift +++ b/Moblin/Various/Media.swift @@ -812,8 +812,8 @@ final class Media: NSObject { func attachReplaceCamera( device: AVCaptureDevice?, cameraPreviewLayer: AVCaptureVideoPreviewLayer?, - showCameraPreview _: Bool, - cameraId: UUID + cameraId: UUID, + ignoreFramesAfterAttachSeconds: Double ) { netStream?.attachCamera( device, @@ -821,7 +821,7 @@ final class Media: NSObject { false, .off, false, - 0.0, + ignoreFramesAfterAttachSeconds, replaceVideoCameraId: cameraId ) } diff --git a/Moblin/Various/Model.swift b/Moblin/Various/Model.swift index cc0a36d0d..001c30235 100644 --- a/Moblin/Various/Model.swift +++ b/Moblin/Various/Model.swift @@ -6433,6 +6433,14 @@ final class Model: NSObject, ObservableObject, @unchecked Sendable { return Double(database.debug.cameraSwitchRemoveBlackish!) } + private func getIgnoreFramesAfterAttachSecondsReplaceCamera() -> Double { + if database.forceSceneSwitchTransition! { + return Double(database.debug.cameraSwitchRemoveBlackish!) + } else { + return 0.0 + } + } + private func attachReplaceCamera(cameraId: UUID) { cameraDevice = nil cameraPosition = nil @@ -6441,8 +6449,8 @@ final class Model: NSObject, ObservableObject, @unchecked Sendable { media.attachReplaceCamera( device: getVideoSourceBuiltinCameraDevice(), cameraPreviewLayer: cameraPreviewLayer, - showCameraPreview: updateShowCameraPreview(), - cameraId: cameraId + cameraId: cameraId, + ignoreFramesAfterAttachSeconds: getIgnoreFramesAfterAttachSecondsReplaceCamera() ) media.usePendingAfterAttachEffects() } diff --git a/Moblin/Various/Settings.swift b/Moblin/Various/Settings.swift index bb318af9c..59dc4b6d3 100644 --- a/Moblin/Various/Settings.swift +++ b/Moblin/Various/Settings.swift @@ -2677,6 +2677,7 @@ class Database: Codable { var pixellateStrength: Float? = 0.3 var moblink: SettingsMoblinkRelay? = .init() var sceneSwitchTransition: SettingsSceneSwitchTransition? = .blur + var forceSceneSwitchTransition: Bool? = false static func fromString(settings: String) throws -> Database { let database = try JSONDecoder().decode( @@ -4609,5 +4610,9 @@ final class Settings { realDatabase.sceneSwitchTransition = realDatabase.debug.blurSceneSwitch! ? .blur : .freeze store() } + if realDatabase.forceSceneSwitchTransition == nil { + realDatabase.forceSceneSwitchTransition = false + store() + } } } diff --git a/Moblin/View/Settings/Scenes/ScenesSettingsView.swift b/Moblin/View/Settings/Scenes/ScenesSettingsView.swift index 350047c45..bc99766c6 100644 --- a/Moblin/View/Settings/Scenes/ScenesSettingsView.swift +++ b/Moblin/View/Settings/Scenes/ScenesSettingsView.swift @@ -65,15 +65,27 @@ private struct ScenesSwitchTransition: View { @State var sceneSwitchTransition: String var body: some View { - Picker("Scene switch transition", selection: $sceneSwitchTransition) { - ForEach(sceneSwitchTransitions, id: \.self) { transition in - Text(transition) + Section { + Picker("Scene switch transition", selection: $sceneSwitchTransition) { + ForEach(sceneSwitchTransitions, id: \.self) { transition in + Text(transition) + } } - } - .onChange(of: sceneSwitchTransition) { _ in - model.database.sceneSwitchTransition = SettingsSceneSwitchTransition - .fromString(value: sceneSwitchTransition) - model.setSceneSwitchTransition() + .onChange(of: sceneSwitchTransition) { _ in + model.database.sceneSwitchTransition = SettingsSceneSwitchTransition + .fromString(value: sceneSwitchTransition) + model.setSceneSwitchTransition() + } + Toggle("Force scene switch transition", isOn: Binding(get: { + model.database.forceSceneSwitchTransition! + }, set: { value in + model.database.forceSceneSwitchTransition = value + })) + } footer: { + Text(""" + RTMP, SRT(LA), screen capture and media player video sources can instantly be switched \ + to, but if you want consistency you can force scene switch transitions to these as well. + """) } } }