From a5287e00abc17a5404e84b8aee2c2dc2dfc7c225 Mon Sep 17 00:00:00 2001 From: Alejandro de Arriba Date: Fri, 19 Mar 2021 12:49:25 +0100 Subject: [PATCH 1/6] Interface and implementation for scene changing Created interface and powerpoint notes implementation for scene changing. --- SceneProcessors/ISceneDataProcessor.cs | 7 ++ SceneProcessors/PowerpointNoteProcessor.cs | 75 ++++++++++++++++++++++ 2 files changed, 82 insertions(+) create mode 100644 SceneProcessors/ISceneDataProcessor.cs create mode 100644 SceneProcessors/PowerpointNoteProcessor.cs diff --git a/SceneProcessors/ISceneDataProcessor.cs b/SceneProcessors/ISceneDataProcessor.cs new file mode 100644 index 0000000..1621360 --- /dev/null +++ b/SceneProcessors/ISceneDataProcessor.cs @@ -0,0 +1,7 @@ +namespace PowerPointToOBSSceneSwitcher.SceneProcessors +{ + public interface ISceneDataProcessor + { + void ProcessData(string data); + } +} diff --git a/SceneProcessors/PowerpointNoteProcessor.cs b/SceneProcessors/PowerpointNoteProcessor.cs new file mode 100644 index 0000000..73439f7 --- /dev/null +++ b/SceneProcessors/PowerpointNoteProcessor.cs @@ -0,0 +1,75 @@ +using PowerPointToOBSSceneSwitcher.OBS; +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; + +namespace PowerPointToOBSSceneSwitcher.SceneProcessors +{ + class PowerpointNoteProcessor : ISceneDataProcessor + { + private readonly IOBSManager _obs; + + public PowerpointNoteProcessor(IOBSManager obs) + { + _obs = obs; + } + public void ProcessData(string data) + { + var notereader = new StringReader(data); + bool sceneHandled = false; + string line; + + while ((line = notereader.ReadLine()) != null) + { + if (line.StartsWith("OBS:")) + { + line = line.Substring(4).Trim(); + sceneHandled = HandleChangeScene(line, sceneHandled); + } + + if (line.StartsWith("OBSDEF:")) + { + _obs.DefaultScene = line.Substring(7).Trim(); + } + + if (line.StartsWith("**START")) + { + _obs.StartRecording(); + } + + if (line.StartsWith("**STOP")) + { + _obs.StopRecording(); + } + + if (!sceneHandled) + { + Console.WriteLine($" Switching to OBS Default Scene named \"{_obs.DefaultScene}\""); + _obs.ChangeScene(_obs.DefaultScene); + } + } + } + + private bool HandleChangeScene(string sceneName, bool sceneHandled) + { + if (!sceneHandled) + { + try + { + sceneHandled = _obs.ChangeScene(sceneName); + } + catch (Exception ex) + { + Console.WriteLine($" ERROR: {ex.Message}"); + } + } + else + { + Console.WriteLine($" WARNING: Multiple scene definitions found. I used the first and have ignored \"{sceneName}\""); + } + + return sceneHandled; + } + } +} From d6dc85180681c6964f5b841a6db642a883519e30 Mon Sep 17 00:00:00 2001 From: Alejandro de Arriba Date: Fri, 19 Mar 2021 12:49:47 +0100 Subject: [PATCH 2/6] Interface and implementation for OBS manager --- OBS/IOBSManager.cs | 15 +++++ OBS/OBSManager.cs | 133 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 148 insertions(+) create mode 100644 OBS/IOBSManager.cs create mode 100644 OBS/OBSManager.cs diff --git a/OBS/IOBSManager.cs b/OBS/IOBSManager.cs new file mode 100644 index 0000000..01df60f --- /dev/null +++ b/OBS/IOBSManager.cs @@ -0,0 +1,15 @@ +using System; +using System.Threading.Tasks; + +namespace PowerPointToOBSSceneSwitcher.OBS +{ + public interface IOBSManager : IDisposable + { + public String DefaultScene { get; set; } + Task Connect(); + void Init(); + bool ChangeScene(string sceneName); + void StartRecording(); + void StopRecording(); + } +} diff --git a/OBS/OBSManager.cs b/OBS/OBSManager.cs new file mode 100644 index 0000000..268b086 --- /dev/null +++ b/OBS/OBSManager.cs @@ -0,0 +1,133 @@ +using OBS.WebSocket.NET; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace PowerPointToOBSSceneSwitcher.OBS +{ + public class OBSManager : IOBSManager + { + private ObsWebSocket _OBS; + private List _validScenes; + private bool _DisposedValue; + private string _defaultScene; + private string _currentScene; + + public OBSManager(){ } + + public string DefaultScene + { + get { return _defaultScene; } + set + { + if (_validScenes.Contains(value)) + { + _defaultScene = value; + Console.WriteLine($" Setting the default OBS Scene to \"{value}\""); + } + else + { + Console.WriteLine($"Scene named {value} does not exist and cannot be set as default"); + } + } + } + + public Task Connect() + { + _OBS = new ObsWebSocket(); + _OBS.Connect($"ws://127.0.0.1:4444", ""); + return Task.CompletedTask; + } + + public void Init() + { + GetScenes(); + } + + private void GetScenes() + { + var allScene = _OBS.Api.GetSceneList(); + var list = allScene.Scenes.Select(s => s.Name).ToList(); + Console.WriteLine("Valid Scenes:"); + foreach (var l in list) + { + Console.WriteLine(l); + } + _validScenes = list; + _defaultScene = _validScenes.FirstOrDefault(); + } + + public bool ChangeScene(string sceneName) + { + if (!_validScenes.Contains(sceneName)) + { + Console.WriteLine($"Scene named {sceneName} does not exist"); + if (String.IsNullOrEmpty(_defaultScene)) + { + Console.WriteLine("No default scene has been set!"); + return false; + } + + sceneName = _defaultScene; + } + + if(_currentScene != sceneName) + { + Console.WriteLine($" Switching to OBS Scene named \"{sceneName}\""); + _OBS.Api.SetCurrentScene(sceneName); + _currentScene = sceneName; + } + + return true; + } + + public void StartRecording() + { + try + { + _OBS.Api.StartRecording(); + Console.WriteLine($"Recording Started"); + } + catch { /* Recording already started */ } + } + + public void StopRecording() + { + try + { + _OBS.Api.StopRecording(); + Console.WriteLine($"Recording Stopped"); + } + catch { /* Recording already stopped */ } + } + + ~OBSManager() + { + // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method + Dispose(disposing: false); + } + + public void Dispose() + { + // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method + Dispose(disposing: true); + GC.SuppressFinalize(this); + } + + protected virtual void Dispose(bool disposing) + { + if (!_DisposedValue) + { + if (disposing) + { + // TODO: dispose managed state (managed objects) + } + + _OBS.Disconnect(); + _OBS = null; + _DisposedValue = true; + } + } + } +} From a48bde78c1fdb84204b9cc00a3dfe20c2ae40dec Mon Sep 17 00:00:00 2001 From: Alejandro de Arriba Date: Fri, 19 Mar 2021 12:50:35 +0100 Subject: [PATCH 3/6] Depend on interfaces instead of concrete implementations Changes for OBS manager and Scene managers to depend on interfaces --- OBS.cs | 115 ----------------------------------------------------- Program.cs | 61 ++++------------------------ 2 files changed, 7 insertions(+), 169 deletions(-) delete mode 100644 OBS.cs diff --git a/OBS.cs b/OBS.cs deleted file mode 100644 index 8fe7114..0000000 --- a/OBS.cs +++ /dev/null @@ -1,115 +0,0 @@ -using OBS.WebSocket.NET; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; - -namespace PowerPointToOBSSceneSwitcher -{ - - public class ObsLocal : IDisposable - { - private bool _DisposedValue; - private ObsWebSocket _OBS; - private List validScenes; - private string defaultScene; - - public ObsLocal() { } - - public Task Connect() - { - _OBS = new ObsWebSocket(); - _OBS.Connect($"ws://127.0.0.1:4444", ""); - return Task.CompletedTask; - } - - public string DefaultScene - { - get { return defaultScene; } - set - { - if (validScenes.Contains(value)) - { - defaultScene = value; - } - else - { - Console.WriteLine($"Scene named {value} does not exist and cannot be set as default"); - } - } - } - - public bool ChangeScene(string scene) - { - if (!validScenes.Contains(scene)) - { - Console.WriteLine($"Scene named {scene} does not exist"); - if (String.IsNullOrEmpty(defaultScene)) - { - Console.WriteLine("No default scene has been set!"); - return false; - } - - scene = defaultScene; - } - - _OBS.Api.SetCurrentScene(scene); - - return true; - } - - public void GetScenes() - { - var allScene = _OBS.Api.GetSceneList(); - var list = allScene.Scenes.Select(s => s.Name).ToList(); - Console.WriteLine("Valid Scenes:"); - foreach(var l in list) - { - Console.WriteLine(l); - } - validScenes = list; - } - - public bool StartRecording() - { - try { _OBS.Api.StartRecording(); } - catch { /* Recording already started */ } - return true; - } - - public bool StopRecording() - { - try { _OBS.Api.StopRecording(); } - catch { /* Recording already stopped */ } - return true; - } - - protected virtual void Dispose(bool disposing) - { - if (!_DisposedValue) - { - if (disposing) - { - // TODO: dispose managed state (managed objects) - } - - _OBS.Disconnect(); - _OBS = null; - _DisposedValue = true; - } - } - - ~ObsLocal() - { - // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method - Dispose(disposing: false); - } - - public void Dispose() - { - // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method - Dispose(disposing: true); - GC.SuppressFinalize(this); - } - } -} \ No newline at end of file diff --git a/Program.cs b/Program.cs index f02ae32..e56fe52 100644 --- a/Program.cs +++ b/Program.cs @@ -2,6 +2,8 @@ using System.IO; using System.Threading.Tasks; using Microsoft.Office.Interop.PowerPoint; +using PowerPointToOBSSceneSwitcher.OBS; +using PowerPointToOBSSceneSwitcher.SceneProcessors; //Thanks to CSharpFritz and EngstromJimmy for their gists, snippets, and thoughts. namespace PowerPointToOBSSceneSwitcher @@ -9,7 +11,7 @@ namespace PowerPointToOBSSceneSwitcher class Program { private static Application ppt = new Microsoft.Office.Interop.PowerPoint.Application(); - private static ObsLocal OBS; + private static IOBSManager OBS; static async Task Main(string[] args) { Console.Write("Connecting to PowerPoint..."); @@ -17,11 +19,11 @@ static async Task Main(string[] args) Console.WriteLine("connected"); Console.Write("Connecting to OBS..."); - OBS = new ObsLocal(); + OBS = new OBSManager(); await OBS.Connect(); Console.WriteLine("connected"); - OBS.GetScenes(); + OBS.Init(); Console.ReadLine(); } @@ -37,57 +39,8 @@ async static void App_SlideShowNextSlide(SlideShowWindow Wn) try { note = Wn.View.Slide.NotesPage.Shapes[2].TextFrame.TextRange.Text; } catch { /*no notes*/ } - bool sceneHandled = false; - - - var notereader = new StringReader(note); - string line; - while ((line = notereader.ReadLine()) != null) - { - if (line.StartsWith("OBS:")) - { - line = line.Substring(4).Trim(); - - if (!sceneHandled) - { - Console.WriteLine($" Switching to OBS Scene named \"{line}\""); - try - { - sceneHandled = OBS.ChangeScene(line); - } - catch (Exception ex) - { - Console.WriteLine($" ERROR: {ex.Message.ToString()}"); - } - } - else - { - Console.WriteLine($" WARNING: Multiple scene definitions found. I used the first and have ignored \"{line}\""); - } - } - - if (line.StartsWith("OBSDEF:")) - { - OBS.DefaultScene = line.Substring(7).Trim(); - Console.WriteLine($" Setting the default OBS Scene to \"{OBS.DefaultScene}\""); - } - - if (line.StartsWith("**START")) - { - OBS.StartRecording(); - } - - if (line.StartsWith("**STOP")) - { - OBS.StopRecording(); - } - - if (!sceneHandled) - { - OBS.ChangeScene(OBS.DefaultScene); - Console.WriteLine($" Switching to OBS Default Scene named \"{OBS.DefaultScene}\""); - } - } + ISceneDataProcessor reader = new PowerpointNoteProcessor(OBS); + reader.ProcessData(note); } } From 3f7358c16ce7c8cfa095153222643d19285b4cbd Mon Sep 17 00:00:00 2001 From: Alejandro de Arriba Date: Fri, 19 Mar 2021 14:33:27 +0100 Subject: [PATCH 4/6] Changed Scene manager folder name --- SceneManagers/ISceneManager.cs | 7 +++++++ .../PowerpointNotesSceneManager.cs | 6 +++--- SceneProcessors/ISceneDataProcessor.cs | 7 ------- 3 files changed, 10 insertions(+), 10 deletions(-) create mode 100644 SceneManagers/ISceneManager.cs rename SceneProcessors/PowerpointNoteProcessor.cs => SceneManagers/PowerpointNotesSceneManager.cs (92%) delete mode 100644 SceneProcessors/ISceneDataProcessor.cs diff --git a/SceneManagers/ISceneManager.cs b/SceneManagers/ISceneManager.cs new file mode 100644 index 0000000..d0d579e --- /dev/null +++ b/SceneManagers/ISceneManager.cs @@ -0,0 +1,7 @@ +namespace PowerPointToOBSSceneSwitcher.SceneManagers +{ + public interface ISceneManager + { + void ProcessData(string data); + } +} diff --git a/SceneProcessors/PowerpointNoteProcessor.cs b/SceneManagers/PowerpointNotesSceneManager.cs similarity index 92% rename from SceneProcessors/PowerpointNoteProcessor.cs rename to SceneManagers/PowerpointNotesSceneManager.cs index 73439f7..0c32ba2 100644 --- a/SceneProcessors/PowerpointNoteProcessor.cs +++ b/SceneManagers/PowerpointNotesSceneManager.cs @@ -4,13 +4,13 @@ using System.IO; using System.Text; -namespace PowerPointToOBSSceneSwitcher.SceneProcessors +namespace PowerPointToOBSSceneSwitcher.SceneManagers { - class PowerpointNoteProcessor : ISceneDataProcessor + class PowerpointNotesSceneManager : ISceneManager { private readonly IOBSManager _obs; - public PowerpointNoteProcessor(IOBSManager obs) + public PowerpointNotesSceneManager(IOBSManager obs) { _obs = obs; } diff --git a/SceneProcessors/ISceneDataProcessor.cs b/SceneProcessors/ISceneDataProcessor.cs deleted file mode 100644 index 1621360..0000000 --- a/SceneProcessors/ISceneDataProcessor.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace PowerPointToOBSSceneSwitcher.SceneProcessors -{ - public interface ISceneDataProcessor - { - void ProcessData(string data); - } -} From 9638979eda0ec2023e200b40736b05d07318a496 Mon Sep 17 00:00:00 2001 From: Alejandro de Arriba Date: Fri, 19 Mar 2021 14:37:43 +0100 Subject: [PATCH 5/6] Created a Powerpoint controller Encapsulate powerpoint logic inside a controller. --- PowerPointSwitcherController.cs | 47 +++++++++++++++++++++++++++++++++ Program.cs | 33 +++-------------------- 2 files changed, 51 insertions(+), 29 deletions(-) create mode 100644 PowerPointSwitcherController.cs diff --git a/PowerPointSwitcherController.cs b/PowerPointSwitcherController.cs new file mode 100644 index 0000000..11d468f --- /dev/null +++ b/PowerPointSwitcherController.cs @@ -0,0 +1,47 @@ +using Microsoft.Office.Interop.PowerPoint; +using PowerPointToOBSSceneSwitcher.OBS; +using PowerPointToOBSSceneSwitcher.SceneManagers; +using System; +using System.Threading.Tasks; + +namespace PowerPointToOBSSceneSwitcher +{ + public class PowerPointSwitcherController + { + private readonly Application _ppt; + private readonly IOBSManager _obsManager; + + public PowerPointSwitcherController(IOBSManager obsManager) + { + _ppt = new Application(); + _obsManager = obsManager; + } + + public async Task Connect() + { + Console.Write("Connecting to PowerPoint..."); + _ppt.SlideShowNextSlide += App_SlideShowNextSlide; + Console.WriteLine("connected"); + + Console.Write("Connecting to OBS..."); + await _obsManager.Connect(); + _obsManager.Init(); + Console.WriteLine("connected"); + } + + private void App_SlideShowNextSlide(SlideShowWindow Wn) + { + if (Wn != null) + { + Console.WriteLine($"Moved to Slide Number {Wn.View.Slide.SlideNumber}"); + //Text starts at Index 2 ¯\_(ツ)_/¯ + var note = String.Empty; + try { note = Wn.View.Slide.NotesPage.Shapes[2].TextFrame.TextRange.Text; } + catch { /*no notes*/ } + + ISceneManager reader = new PowerpointNotesSceneManager(_obsManager); + reader.ProcessData(note); + } + } + } +} diff --git a/Program.cs b/Program.cs index e56fe52..8e4c417 100644 --- a/Program.cs +++ b/Program.cs @@ -3,46 +3,21 @@ using System.Threading.Tasks; using Microsoft.Office.Interop.PowerPoint; using PowerPointToOBSSceneSwitcher.OBS; -using PowerPointToOBSSceneSwitcher.SceneProcessors; +using PowerPointToOBSSceneSwitcher.SceneManagers; //Thanks to CSharpFritz and EngstromJimmy for their gists, snippets, and thoughts. namespace PowerPointToOBSSceneSwitcher { class Program { - private static Application ppt = new Microsoft.Office.Interop.PowerPoint.Application(); - private static IOBSManager OBS; static async Task Main(string[] args) { - Console.Write("Connecting to PowerPoint..."); - ppt.SlideShowNextSlide += App_SlideShowNextSlide; - Console.WriteLine("connected"); + IOBSManager OBS = new OBSManager(); - Console.Write("Connecting to OBS..."); - OBS = new OBSManager(); - await OBS.Connect(); - Console.WriteLine("connected"); - - OBS.Init(); + PowerPointSwitcherController controller = new PowerPointSwitcherController(OBS); + await controller.Connect(); Console.ReadLine(); } - - - async static void App_SlideShowNextSlide(SlideShowWindow Wn) - { - if (Wn != null) - { - Console.WriteLine($"Moved to Slide Number {Wn.View.Slide.SlideNumber}"); - //Text starts at Index 2 ¯\_(ツ)_/¯ - var note = String.Empty; - try { note = Wn.View.Slide.NotesPage.Shapes[2].TextFrame.TextRange.Text; } - catch { /*no notes*/ } - - ISceneDataProcessor reader = new PowerpointNoteProcessor(OBS); - reader.ProcessData(note); - } - } - } } \ No newline at end of file From b846d54c626904b0b07fec22d9e5614ef5df0042 Mon Sep 17 00:00:00 2001 From: Alejandro de Arriba Date: Fri, 19 Mar 2021 14:47:10 +0100 Subject: [PATCH 6/6] Changed order of lines --- PowerPointSwitcherController.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PowerPointSwitcherController.cs b/PowerPointSwitcherController.cs index 11d468f..10324ae 100644 --- a/PowerPointSwitcherController.cs +++ b/PowerPointSwitcherController.cs @@ -25,8 +25,8 @@ public async Task Connect() Console.Write("Connecting to OBS..."); await _obsManager.Connect(); - _obsManager.Init(); Console.WriteLine("connected"); + _obsManager.Init(); } private void App_SlideShowNextSlide(SlideShowWindow Wn)