From 4b89706a79c6cd7e2d29cc4877ca965c4118ca73 Mon Sep 17 00:00:00 2001 From: bborgsdorf Date: Thu, 30 Jan 2014 23:02:37 +0000 Subject: [PATCH] updated BrowserHost to work with Remotes and use MediaPortal Keybindings (thx Jason and Brownard) --- .../OnlineVideos.MediaPortal1.csproj | 5 +- .../Player/WebBrowserVideoPlayer.cs | 11 +- .../App.config | 11 +- .../BrowserForm.cs | 147 +++++++++++++----- ...ineVideos.WebAutomation.BrowserHost.csproj | 14 +- .../Program.cs | 3 + .../4OD/Connectors/_4ODConnector.cs | 73 +++------ 7 files changed, 159 insertions(+), 105 deletions(-) diff --git a/OnlineVideos.MediaPortal1/OnlineVideos.MediaPortal1.csproj b/OnlineVideos.MediaPortal1/OnlineVideos.MediaPortal1.csproj index b02bbbdeb..cbddfa0da 100644 --- a/OnlineVideos.MediaPortal1/OnlineVideos.MediaPortal1.csproj +++ b/OnlineVideos.MediaPortal1/OnlineVideos.MediaPortal1.csproj @@ -1,4 +1,4 @@ - + Debug @@ -66,6 +66,9 @@ $(ProgramFiles)\Team MediaPortal\MediaPortal\log4net.dll False + + $(ProgramFiles)\Team MediaPortal\MediaPortal\RemotePlugins.dll + diff --git a/OnlineVideos.MediaPortal1/Player/WebBrowserVideoPlayer.cs b/OnlineVideos.MediaPortal1/Player/WebBrowserVideoPlayer.cs index 2d126d46f..c40d36924 100644 --- a/OnlineVideos.MediaPortal1/Player/WebBrowserVideoPlayer.cs +++ b/OnlineVideos.MediaPortal1/Player/WebBrowserVideoPlayer.cs @@ -7,6 +7,7 @@ using MediaPortal.Player; using OnlineVideos.Helpers; using OnlineVideos.Sites; +using MediaPortal.InputDevices; namespace OnlineVideos.MediaPortal1.Player { @@ -86,12 +87,11 @@ public override bool Play(string strFile) // Hide MediaPortal if (_browserProcess.Start()) { + ProcessHelper.SetForeground(_browserProcess.MainWindowHandle); SuspendMP(true); Redirect(_browserProcess.StandardError); } - - ProcessHelper.SetForeground(_browserProcess.MainWindowHandle); - + return true; } @@ -157,13 +157,14 @@ void SuspendMP(bool suspend) if (suspend) //suspend and hide MediaPortal { - //InputDevices.Stop(); + InputDevices.Stop(); //stop input devices so they don't interfere when the browser player starts listening // hide mediaportal and suspend rendering GUIGraphicsContext.BlankScreen = true; GUIGraphicsContext.form.Hide(); GUIGraphicsContext.CurrentState = GUIGraphicsContext.State.SUSPENDING; // Hide the window + ProcessHelper.SetWindowState("mediaportal", ProcessHelper.WINDOW_STATE.SW_MINIMIZE); _mpWindowHandle = ProcessHelper.SetWindowState("mediaportal", ProcessHelper.WINDOW_STATE.SW_HIDE); _mpWindowHidden = true; } @@ -172,7 +173,7 @@ void SuspendMP(bool suspend) // Restore the window ProcessHelper.RestoreWindow(_mpWindowHandle); - //InputDevices.Init(); + InputDevices.Init(); // Resume Mediaportal rendering GUIGraphicsContext.BlankScreen = false; diff --git a/OnlineVideos.WebAutomation.BrowserHost/App.config b/OnlineVideos.WebAutomation.BrowserHost/App.config index 9c209f70c..da29f6e2f 100644 --- a/OnlineVideos.WebAutomation.BrowserHost/App.config +++ b/OnlineVideos.WebAutomation.BrowserHost/App.config @@ -1,9 +1,6 @@ - - - - - - - + + + + \ No newline at end of file diff --git a/OnlineVideos.WebAutomation.BrowserHost/BrowserForm.cs b/OnlineVideos.WebAutomation.BrowserHost/BrowserForm.cs index 0d8ef3c70..999b44e2a 100644 --- a/OnlineVideos.WebAutomation.BrowserHost/BrowserForm.cs +++ b/OnlineVideos.WebAutomation.BrowserHost/BrowserForm.cs @@ -13,11 +13,23 @@ using System.Diagnostics; using System.Configuration; using OnlineVideos.Sites.Base; +using MediaPortal.GUI.Library; +using MediaPortal.InputDevices; +using Action = MediaPortal.GUI.Library.Action; namespace OnlineVideos.Sites.WebAutomation.BrowserHost { public partial class BrowserForm : Form { + /// + /// Which was the last of the 2 events fired between play/pause. We'll use this to handle the media key as that's a single play/pause button. + /// + private enum PlayPauseToggle + { + Play, + Pause + } + public bool ForceClose { get; private set; } private string _connectorType; @@ -26,15 +38,13 @@ public partial class BrowserForm : Form private string _password; private BrowserUtilConnector _connector; - private Keys? _playKey; - private Keys? _pauseKey; - private Keys? _stopKey; - private bool _debugMode = false; // Allow for the form to be resized/lose focus in debug mode - private Keys _lastKeyPressed; + private int _lastKeyPressed; private DateTime _lastKeyPressedTime; + private PlayPauseToggle _lastPlayPauseState = PlayPauseToggle.Play; + /// /// This form is used to play a video - we use separate exe as there is no reliable way to dispose of the web browser between sessions /// and this seemed to cause issues when playing multiple videos @@ -50,15 +60,20 @@ public BrowserForm(string connectorType, string videoInfo, string userName, stri _videoInfo = videoInfo; _userName = userName; _password = password; - _playKey = GetKeyForAction("PlayKey"); - _pauseKey = GetKeyForAction("PauseKey"); - _stopKey = GetKeyForAction("StopKey"); _debugMode = false; var configValue = ConfigurationManager.AppSettings["DebugMode"]; if (!string.IsNullOrEmpty(configValue) && configValue.ToUpper() == "TRUE") _debugMode = true; + + //Load keyboard mappings + ActionTranslator.Load(); + //Load remote mappings + InputDevices.Init(); + + //Some remotes will fire this event directly + GUIGraphicsContext.OnNewAction += OnNewAction; } /// @@ -97,7 +112,6 @@ private void BrowserForm_Load(object sender, EventArgs e) } catch (Exception ex) { - //MediaPortal.Common.Utils.Logger.CommonLogger.Instance.Error(MediaPortal.Common.Utils.Logger.CommonLogType.Error, ex); Log.Error(ex); ForceQuit(); } @@ -119,7 +133,7 @@ public bool ForceQuitting() /// private void BrowserForm_KeyDown(object sender, KeyEventArgs e) { - HandleKeyPress(e.KeyCode); + HandleKeyPress(e.KeyValue); } /// @@ -129,28 +143,99 @@ private void BrowserForm_KeyDown(object sender, KeyEventArgs e) /// private void webBrowser_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e) { - HandleKeyPress(e.KeyCode); + HandleKeyPress(e.KeyValue); + } + + //Used to pass messages to remotes. Lifted from MediaPortal.cs + protected override void WndProc(ref Message msg) + { + Action action; + char key; + Keys keyCode; + if (InputDevices.WndProc(ref msg, out action, out key, out keyCode)) + { + //If remote doesn't fire event directly we manually fire it + if (action != null && action.wID != Action.ActionType.ACTION_INVALID) + { + OnNewAction(action); + } + + if (keyCode != Keys.A) + { + var ke = new KeyEventArgs(keyCode); + OnKeyDown(ke); + } + return; // abort WndProc() + } + base.WndProc(ref msg); } /// /// Event sink for key press /// /// - private void HandleKeyPress(Keys keyPressed) + private void HandleKeyPress(int keyPressed) { - // Ignore duplicate presses within 1 second (happens because sometimes both the browser and form fire the event) - if (_lastKeyPressed == keyPressed && _lastKeyPressedTime.AddSeconds(1) > DateTime.Now) return; + // Ignore duplicate presses within 0.5 seconds (happens because sometimes both the browser and form fire the event) + if (_lastKeyPressed == keyPressed && _lastKeyPressedTime.AddSeconds(0.5) > DateTime.Now) return; _lastKeyPressed = keyPressed; _lastKeyPressedTime = DateTime.Now; - if (keyPressed == Keys.Escape) - ForceQuit(); - if (_playKey.HasValue && keyPressed == _playKey) - _connector.Play(); - if (_stopKey.HasValue && keyPressed == _stopKey) - ForceQuit(); - if (_pauseKey.HasValue && keyPressed == _pauseKey) - _connector.Pause(); + Action action = new Action(); + //Try and get corresponding Action from key. + //Some actions are mapped to KeyDown others to KeyPressed, try and handle both + if (ActionTranslator.GetAction(-1, new Key(0, keyPressed), ref action)) + { + OnNewAction(action); + } + else + { + //See if it's mapped to KeyPressed instead + if (keyPressed >= (int)Keys.A && keyPressed <= (int)Keys.Z) + keyPressed += 32; //convert to char code + if (ActionTranslator.GetAction(-1, new Key(keyPressed, 0), ref action)) + OnNewAction(action); + else + { + // Handle the mesdia keys (toggle the play/pause as they are one button in this instance) + switch (keyPressed) + { + case (int)Keys.MediaPlayPause: + if (_lastPlayPauseState == PlayPauseToggle.Play) + OnNewAction(new Action(Action.ActionType.ACTION_PAUSE, 0, 0)); + else + OnNewAction(new Action(Action.ActionType.ACTION_PLAY, 0, 0)); + break; + case (int)Keys.MediaStop: + OnNewAction(new Action(Action.ActionType.ACTION_STOP, 0, 0)); + break; + } + } + } + } + + /// + /// Handle actions + /// + /// + void OnNewAction(Action action) + { + switch (action.wID) + { + case Action.ActionType.ACTION_PLAY: + case Action.ActionType.ACTION_MUSIC_PLAY: + _connector.Play(); + _lastPlayPauseState = PlayPauseToggle.Play; + break; + case Action.ActionType.ACTION_PAUSE: + _connector.Pause(); + _lastPlayPauseState = PlayPauseToggle.Pause; + break; + case Action.ActionType.ACTION_STOP: + case Action.ActionType.ACTION_PREVIOUS_MENU: + ForceQuit(); + break; + } } /// @@ -174,22 +259,8 @@ private void ForceQuit() private void tmrKeepOnTop_Tick(object sender, EventArgs e) { ProcessHelper.SetForeground(Process.GetCurrentProcess().MainWindowHandle); - } - - /// - /// Lookup the key code for the specified action name - /// - /// - /// - private Keys? GetKeyForAction(string actionName) - { - var configValue = ConfigurationManager.AppSettings[actionName]; - if (string.IsNullOrEmpty(configValue)) return null; - - if (System.Enum.GetNames(typeof(Keys)).Where(x => x.ToUpper() == configValue).Count() > 0) - return (Keys)System.Enum.Parse(typeof(Keys), configValue, true); - - return null; + this.Activate(); + this.Focus(); } /// diff --git a/OnlineVideos.WebAutomation.BrowserHost/OnlineVideos.WebAutomation.BrowserHost.csproj b/OnlineVideos.WebAutomation.BrowserHost/OnlineVideos.WebAutomation.BrowserHost.csproj index 7f3957164..b9e5ab944 100644 --- a/OnlineVideos.WebAutomation.BrowserHost/OnlineVideos.WebAutomation.BrowserHost.csproj +++ b/OnlineVideos.WebAutomation.BrowserHost/OnlineVideos.WebAutomation.BrowserHost.csproj @@ -55,6 +55,14 @@ MinimumRecommendedRules.ruleset + + $(ProgramFiles)\Team MediaPortal\MediaPortal\Core.dll + False + + + $(ProgramFiles)\Team MediaPortal\MediaPortal\RemotePlugins.dll + False + @@ -111,15 +119,15 @@ {e0d9d390-cdd6-4b98-86f3-6eb04a958882} OnlineVideos - True + False - xcopy "$(TargetPath)" "%25programfiles(x86)%25\Team MediaPortal\MediaPortal\plugins\Windows\OnlineVideos" /Y /E /I -xcopy "$(TargetPath).config" "%25programfiles(x86)%25\Team MediaPortal\MediaPortal\plugins\Windows\OnlineVideos" /Y /E /I + xcopy "$(TargetPath)" "%25programfiles(x86)%25\Team MediaPortal\MediaPortal\plugins\windows\onlinevideos\" /Y /E /I +xcopy "$(TargetPath).config" "%25programfiles(x86)%25\Team MediaPortal\MediaPortal\plugins\windows\onlinevideos\" /Y /E /I