5.4.8.8 Beta

This commit is contained in:
Frank Skare
2021-05-09 15:50:09 +02:00
parent cdf3eb1373
commit 18c8f5783b
14 changed files with 248 additions and 88 deletions

View File

@@ -61,6 +61,7 @@ Features
- Customizable context menu defined in the same file as the key bindings - Customizable context menu defined in the same file as the key bindings
- Config dialog - Config dialog
- Shorcut key editor - Shorcut key editor
- Global hotkeys
- Many features like the config editor and shortcut key editor are fully searchable - Many features like the config editor and shortcut key editor are fully searchable
- Configuration files that are easy to read and edit - Configuration files that are easy to read and edit
- Command palette to quickly find commands and keys - Command palette to quickly find commands and keys

View File

@@ -1,15 +1,18 @@
5.4.8.8 Beta (not yet released) 5.4.8.8 Beta (2021-05-09)
========================= =========================
- Improved window scaling. - Improved window scaling.
- Title property implementation. - Title property implementation.
- Command palette shows commands without assigned menu item. - Command palette shows commands without assigned menu item.
- The code from the included JavaScript file was ported into the core player - The code from the included JavaScript file was ported into the core
because JavaScript is currently broken in the builds of shinshiro. player because JavaScript is currently broken in the builds of shinshiro.
- New option `--command=<input command>`, can be used in combination - New option `--command=<input command>`, can be used in combination
with `process-instance=single` to control mpv.net via command line, with `process-instance=single` to control mpv.net via command line,
for instance to create global hotkeys with AutoHotkey. for instance to create global hotkeys with AutoHotkey.
- New global hotkey feature added using the file global-input.conf.
- The global-media-keys option was removed because global-input.conf
can be used instead.
- MediaInfo 21.3 - MediaInfo 21.3
- libmpv shinchiro 2021-04-04 - libmpv shinchiro 2021-04-04

View File

@@ -10,6 +10,7 @@ Table of contents
* [Installation](#installation) * [Installation](#installation)
* [Support](#support) * [Support](#support)
* [Settings](#settings) * [Settings](#settings)
* [Input and context menu](#input-and-context-menu)
* [Command Line Interface](#command-line-interface) * [Command Line Interface](#command-line-interface)
* [Terminal](#terminal) * [Terminal](#terminal)
* [mpv.net specific options](#mpvnet-specific-options) * [mpv.net specific options](#mpvnet-specific-options)
@@ -66,6 +67,13 @@ There is a setup exe and a portable zip file download.
For internet streaming youtube-dl must be downloaded and installed manually, For internet streaming youtube-dl must be downloaded and installed manually,
meaning it must be located in the PATH environment variable or in the startup directory. meaning it must be located in the PATH environment variable or in the startup directory.
mpvnet.exe is platform agnostic, users that need x86 have to replace 4 native tools:
- Everything.dll
- mpv-1.dll
- MediaInfo.dll
- mpvnet.com
#### File Associations #### File Associations
@@ -116,12 +124,16 @@ mpv.net generates it with the following defaults:
mpv.net specific settings are stored in the file mpvnet.conf. mpv.net specific settings are stored in the file mpvnet.conf.
Input and context menu
----------------------
The input (key/mouse) bindings and the context menu definitions are stored in the The input (key/mouse) bindings and the context menu definitions are stored in the
input.conf file, if it's missing mpv.net generates it with the following defaults: input.conf file, if it's missing mpv.net generates it with the following defaults:
[input.conf defaults](../../../tree/master/src/Resources/input.conf.txt) [input.conf defaults](../../../tree/master/src/Resources/input.conf.txt)
mpv.net supports almost all mpv settings and features. Global hotkeys are supported via global-input.conf file.
The config folder can be opened from the context menu: `Settings > Open Config Folder` The config folder can be opened from the context menu: `Settings > Open Config Folder`
@@ -185,7 +197,7 @@ Adds files to the playlist, requires [--process-instance=single](#--process-inst
#### --command=\<input command\> #### --command=\<input command\>
Sends a input commands. Useful to control mpv.net from the command line, for instance Sends a input command. Useful to control mpv.net from the command line, for instance
to create global hotkeys with AutoHotkey, for that [process-instance=single](#--process-instancevalue) to create global hotkeys with AutoHotkey, for that [process-instance=single](#--process-instancevalue)
must be used. Spaces have to be escaped with quotes and quotes have to be escaped with double quotes. must be used. Spaces have to be escaped with quotes and quotes have to be escaped with double quotes.
@@ -239,13 +251,6 @@ For single files automatically load the entire directory into the playlist.
Can be suppressed via shift key. Default: yes Can be suppressed via shift key. Default: yes
### Input
#### --global-media-keys=\<yes|no\>
Enable global media keys next track, previous track, play/pause, stop. Default: no
### General ### General
#### --update-check=\<yes|no\> #### --update-check=\<yes|no\>

View File

@@ -170,7 +170,6 @@ namespace mpvnet
{ {
switch (name) switch (name)
{ {
case "global-media-keys": GlobalMediaKeys = value == "yes"; return true;
case "remember-position": RememberPosition = value == "yes"; return true; case "remember-position": RememberPosition = value == "yes"; return true;
case "debug-mode": DebugMode = value == "yes"; return true; case "debug-mode": DebugMode = value == "yes"; return true;
case "remember-volume": RememberVolume = value == "yes"; return true; case "remember-volume": RememberVolume = value == "yes"; return true;

191
src/Misc/GlobalHotkey.cs Normal file
View File

@@ -0,0 +1,191 @@

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Runtime.InteropServices;
using static mpvnet.Core;
namespace mpvnet
{
class GlobalHotkey
{
public static Dictionary<int, string> Commands { get; set; }
static int ID;
static IntPtr HWND;
public static void RegisterGlobalHotkeys(IntPtr hwnd)
{
HWND = hwnd;
string path = core.ConfigFolder + "global-input.conf";
if (!File.Exists(path))
return;
foreach (string i in File.ReadAllLines(path))
{
string line = i.Trim();
if (line.StartsWith("#") || !line.Contains(" "))
continue;
ProcessGlobalHotkeyLine(line);
}
}
static void ProcessGlobalHotkeyLine(string line)
{
string key = line.Substring(0, line.IndexOf(" "));
string command = line.Substring(line.IndexOf(" ") + 1);
string[] parts = key.Split('+');
KeyModifiers mod = KeyModifiers.None;
int vk;
for (int i = 0; i < parts.Length - 1; i++)
{
string umod = parts[i].ToUpper();
if (umod == "ALT") mod |= KeyModifiers.Alt;
if (umod == "CTRL") mod |= KeyModifiers.Ctrl;
if (umod == "SHIFT") mod |= KeyModifiers.Shift;
if (umod == "WIN") mod |= KeyModifiers.Win;
}
key = parts[parts.Length - 1];
if (key.Length == 1)
{
short result = VkKeyScanEx(key[0], GetKeyboardLayout(0));
int hi = result >> 8;
int lo = result & 0xFF;
if (lo == -1)
return;
vk = lo;
if ((hi & 1) == 1) mod |= KeyModifiers.Shift;
if ((hi & 2) == 2) mod |= KeyModifiers.Ctrl;
if ((hi & 4) == 4) mod |= KeyModifiers.Alt;
}
else
vk = mpv_to_VK(key);
if (Commands == null)
Commands = new Dictionary<int, string>();
if (vk > 0)
{
Commands[ID] = command.Trim();
bool success = RegisterHotKey(HWND, ID++, mod, vk);
if (!success)
ConsoleHelp.WriteError(line + ": " + new Win32Exception().Message + "\n", "global-input.conf");
}
}
public static void Execute(int id)
{
if (Commands.ContainsKey(id))
core.command(Commands[id]);
}
static int mpv_to_VK(string value)
{
switch (value.ToUpperEx())
{
case "NEXT" : return 0xB0; // VK_MEDIA_NEXT_TRACK
case "PREV" : return 0xB1; // VK_MEDIA_PREV_TRACK
case "STOP" : return 0xB2; // VK_MEDIA_STOP
case "PLAYPAUSE" : return 0xB3; // VK_MEDIA_PLAY_PAUSE
case "SLEEP" : return 0x5F; // VK_SLEEP
case "RIGHT" : return 0x27; // VK_RIGHT
case "UP" : return 0x26; // VK_UP
case "LEFT" : return 0x25; // VK_LEFT
case "DOWN" : return 0x28; // VK_DOWN
case "PGUP" : return 0x21; // VK_PRIOR
case "PGDWN" : return 0x22; // VK_NEXT
case "PAUSE" : return 0x13; // VK_PAUSE
case "PRINT" : return 0x2A; // VK_PRINT
case "HOME" : return 0x24; // VK_HOME
case "INS" : return 0x2D; // VK_INSERT
case "KP_INS" : return 0x2D; // VK_INSERT
case "DEL" : return 0x2E; // VK_DELETE
case "KP_DEL" : return 0x2E; // VK_DELETE
case "END" : return 0x23; // VK_END
case "F1" : return 0x70; // VK_F1
case "F2" : return 0x71; // VK_F2
case "F3" : return 0x72; // VK_F3
case "F4" : return 0x73; // VK_F4
case "F5" : return 0x74; // VK_F5
case "F6" : return 0x75; // VK_F6
case "F7" : return 0x76; // VK_F7
case "F8" : return 0x77; // VK_F8
case "F9" : return 0x78; // VK_F9
case "F10" : return 0x79; // VK_F10
case "F11" : return 0x7A; // VK_F11
case "F12" : return 0x7B; // VK_F12
case "F13" : return 0x7C; // VK_F13
case "F14" : return 0x7D; // VK_F14
case "F15" : return 0x7E; // VK_F15
case "F16" : return 0x7F; // VK_F16
case "F17" : return 0x80; // VK_F17
case "F18" : return 0x81; // VK_F18
case "F19" : return 0x82; // VK_F19
case "F20" : return 0x83; // VK_F20
case "F21" : return 0x84; // VK_F21
case "F22" : return 0x85; // VK_F22
case "F23" : return 0x86; // VK_F23
case "F24" : return 0x87; // VK_F24
case "ENTER" : return 0x0D; // VK_RETURN
case "KP_ENTER" : return 0x0D; // VK_RETURN
case "TAB" : return 0x09; // VK_TAB
case "MENU" : return 0x5D; // VK_APPS
case "CANCEL" : return 0x03; // VK_CANCEL
case "BS" : return 0x08; // VK_BACK
case "KP_DEC" : return 0x6E; // VK_DECIMAL
case "ESC" : return 0x1B; // VK_ESCAPE
case "KP0" : return 0x60; // VK_NUMPAD0
case "KP1" : return 0x61; // VK_NUMPAD1
case "KP2" : return 0x62; // VK_NUMPAD2
case "KP3" : return 0x63; // VK_NUMPAD3
case "KP4" : return 0x64; // VK_NUMPAD4
case "KP5" : return 0x65; // VK_NUMPAD5
case "KP6" : return 0x66; // VK_NUMPAD6
case "KP7" : return 0x67; // VK_NUMPAD7
case "KP8" : return 0x68; // VK_NUMPAD8
case "KP9" : return 0x69; // VK_NUMPAD9
case "FAVORITES" : return 0xAB; // VK_BROWSER_FAVORITES
case "SEARCH" : return 0xAA; // VK_BROWSER_SEARCH
case "MAIL" : return 0xB4; // VK_LAUNCH_MAIL
case "VOLUME_UP" : return 0xAF; // VK_VOLUME_UP
case "VOLUME_DOWN": return 0xAE; // VK_VOLUME_DOWN
case "MUTE" : return 0xAD; // VK_VOLUME_MUTE
case "SPACE" : return 0x20; // VK_SPACE
case "IDEOGRAPHIC_SPACE": return 0x20; // VK_SPACE
default: return 0;
}
}
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
static extern short VkKeyScanEx(char ch, IntPtr dwhkl);
[DllImport("user32.dll")]
static extern IntPtr GetKeyboardLayout(uint idThread);
[DllImport("user32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
static extern bool RegisterHotKey(IntPtr hWnd, int id, KeyModifiers fsModifiers, int vk);
[Flags]
enum KeyModifiers
{
None = 0,
Alt = 1,
Ctrl = 2,
Shift = 4,
Win = 8
}
}
}

View File

@@ -118,31 +118,6 @@ namespace mpvnet
public class mpvHelp public class mpvHelp
{ {
public static string WM_APPCOMMAND_to_mpv_key(int value)
{
switch (value)
{
case 5: return "SEARCH"; // BROWSER_SEARCH
case 6: return "FAVORITES"; // BROWSER_FAVORITES
case 7: return "HOMEPAGE"; // BROWSER_HOME
case 15: return "MAIL"; // LAUNCH_MAIL
case 33: return "PRINT"; // PRINT
case 11: return "NEXT"; // MEDIA_NEXTTRACK
case 12: return "PREV"; // MEDIA_PREVIOUSTRACK
case 13: return "STOP"; // MEDIA_STOP
case 14: return "PLAYPAUSE"; // MEDIA_PLAY_PAUSE
case 46: return "PLAY"; // MEDIA_PLAY
case 47: return "PAUSE"; // MEDIA_PAUSE
case 48: return "RECORD"; // MEDIA_RECORD
case 49: return "FORWARD"; // MEDIA_FAST_FORWARD
case 50: return "REWIND"; // MEDIA_REWIND
case 51: return "CHANNEL_UP"; // MEDIA_CHANNEL_UP
case 52: return "CHANNEL_DOWN"; // MEDIA_CHANNEL_DOWN
}
return null;
}
public static string GetProfiles() public static string GetProfiles()
{ {
string code = @" string code = @"

View File

@@ -48,6 +48,34 @@ namespace mpvnet
int IComparer<string>.Compare(string x, string y) => IComparerOfString_Compare(x, y); int IComparer<string>.Compare(string x, string y) => IComparerOfString_Compare(x, y);
} }
public class Input
{
public static string WM_APPCOMMAND_to_mpv_key(int value)
{
switch (value)
{
case 5: return "SEARCH"; // BROWSER_SEARCH
case 6: return "FAVORITES"; // BROWSER_FAVORITES
case 7: return "HOMEPAGE"; // BROWSER_HOME
case 15: return "MAIL"; // LAUNCH_MAIL
case 33: return "PRINT"; // PRINT
case 11: return "NEXT"; // MEDIA_NEXTTRACK
case 12: return "PREV"; // MEDIA_PREVIOUSTRACK
case 13: return "STOP"; // MEDIA_STOP
case 14: return "PLAYPAUSE"; // MEDIA_PLAY_PAUSE
case 46: return "PLAY"; // MEDIA_PLAY
case 47: return "PAUSE"; // MEDIA_PAUSE
case 48: return "RECORD"; // MEDIA_RECORD
case 49: return "FORWARD"; // MEDIA_FAST_FORWARD
case 50: return "REWIND"; // MEDIA_REWIND
case 51: return "CHANNEL_UP"; // MEDIA_CHANNEL_UP
case 52: return "CHANNEL_DOWN"; // MEDIA_CHANNEL_DOWN
}
return null;
}
}
public class FileAssociation public class FileAssociation
{ {
static string ExePath = Application.ExecutablePath; static string ExePath = Application.ExecutablePath;

View File

@@ -5,11 +5,6 @@ using System.Runtime.InteropServices;
public class WinAPI public class WinAPI
{ {
public const int VK_MEDIA_NEXT_TRACK = 0xB0;
public const int VK_MEDIA_PREV_TRACK = 0xB1;
public const int VK_MEDIA_STOP = 0xB2;
public const int VK_MEDIA_PLAY_PAUSE = 0xB3;
[DllImport("kernel32.dll")] [DllImport("kernel32.dll")]
public static extern bool AttachConsole(int dwProcessId); public static extern bool AttachConsole(int dwProcessId);
@@ -19,9 +14,6 @@ public class WinAPI
[DllImport("kernel32.dll")] [DllImport("kernel32.dll")]
public static extern IntPtr LoadLibrary(string path); public static extern IntPtr LoadLibrary(string path);
[DllImport("user32")]
public static extern bool RegisterHotKey(IntPtr hWnd, int id, uint fsModifiers, uint vk);
[DllImport("user32.dll", CharSet = CharSet.Unicode)] [DllImport("user32.dll", CharSet = CharSet.Unicode)]
public static extern IntPtr FindWindowEx( public static extern IntPtr FindWindowEx(
IntPtr parentHandle, IntPtr childAfter, string lclassName, string windowTitle); IntPtr parentHandle, IntPtr childAfter, string lclassName, string windowTitle);

View File

@@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Build and Revision Numbers // You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below: // by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")] // [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("5.4.8.7")] [assembly: AssemblyVersion("5.4.8.8")]
[assembly: AssemblyFileVersion("5.4.8.7")] [assembly: AssemblyFileVersion("5.4.8.8")]

View File

@@ -8,8 +8,6 @@ $7z = 'C:\Program Files\7-Zip\7z.exe'
$cloudDirectories = 'C:\Users\frank\OneDrive\Public\mpv.net\', $cloudDirectories = 'C:\Users\frank\OneDrive\Public\mpv.net\',
'C:\Users\frank\Dropbox\Public\mpv.net\' 'C:\Users\frank\Dropbox\Public\mpv.net\'
# cd $PSScriptRoot
function UploadBeta($sourceFile) function UploadBeta($sourceFile)
{ {
foreach ($cloudDirectory in $cloudDirectories) foreach ($cloudDirectory in $cloudDirectories)

View File

@@ -524,15 +524,6 @@ help = "For single files automatically load the entire directory into the playli
options = [{ name = "yes" }, options = [{ name = "yes" },
{ name = "no" }] { name = "no" }]
[[settings]]
name = "global-media-keys"
file = "mpvnet"
default = "no"
filter = "Input"
help = "Enable global media keys next track, previous track, play/pause, stop. (mpv.net specific setting)"
options = [{ name = "yes" },
{ name = "no" }]
[[settings]] [[settings]]
name = "input-ar-delay" name = "input-ar-delay"
file = "mpv" file = "mpv"

View File

@@ -1,6 +1,5 @@
 
using System; using System;
using System.Diagnostics;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Text; using System.Text;
using System.Windows; using System.Windows;
@@ -54,7 +53,7 @@ namespace mpvnet
string ret = ToUnicode(vk, scanCode, keys); string ret = ToUnicode(vk, scanCode, keys);
if (ret.Length == 1 && (int)ret[0] < 32) if (ret.Length == 1 && ret[0] < 32)
return ""; return "";
if (ret == "" && (keys[VK_MENU] & 0x80) != 0) if (ret == "" && (keys[VK_MENU] & 0x80) != 0)
@@ -187,7 +186,7 @@ namespace mpvnet
OnKeyDown((uint)m.WParam.ToInt64()); OnKeyDown((uint)m.WParam.ToInt64());
else if (m.Msg == WM_APPCOMMAND) else if (m.Msg == WM_APPCOMMAND)
{ {
string value = mpvHelp.WM_APPCOMMAND_to_mpv_key((int)(m.LParam.ToInt64() >> 16 & ~0xf000)); string value = Input.WM_APPCOMMAND_to_mpv_key((int)(m.LParam.ToInt64() >> 16 & ~0xf000));
if (value != null) if (value != null)
SetKey(value); SetKey(value);

View File

@@ -48,14 +48,6 @@ namespace mpvnet
ConsoleHelp.Padding = 60; ConsoleHelp.Padding = 60;
core.Init(); core.Init();
if (App.GlobalMediaKeys)
{
RegisterGlobalKey(VK_MEDIA_NEXT_TRACK);
RegisterGlobalKey(VK_MEDIA_PREV_TRACK);
RegisterGlobalKey(VK_MEDIA_PLAY_PAUSE);
RegisterGlobalKey(VK_MEDIA_STOP);
}
core.Shutdown += Shutdown; core.Shutdown += Shutdown;
core.VideoSizeChanged += VideoSizeChanged; core.VideoSizeChanged += VideoSizeChanged;
core.ScaleWindow += ScaleWindow; core.ScaleWindow += ScaleWindow;
@@ -601,7 +593,7 @@ namespace mpvnet
break; break;
case 0x319: // WM_APPCOMMAND case 0x319: // WM_APPCOMMAND
{ {
string value = mpvHelp.WM_APPCOMMAND_to_mpv_key((int)(m.LParam.ToInt64() >> 16 & ~0xf000)); string value = Input.WM_APPCOMMAND_to_mpv_key((int)(m.LParam.ToInt64() >> 16 & ~0xf000));
if (value != null) if (value != null)
{ {
@@ -613,21 +605,7 @@ namespace mpvnet
} }
break; break;
case 0x0312: // WM_HOTKEY case 0x0312: // WM_HOTKEY
switch (m.WParam.ToInt64()) GlobalHotkey.Execute(m.WParam.ToInt32());
{
case VK_MEDIA_NEXT_TRACK:
core.command("keypress NEXT");
break;
case VK_MEDIA_PREV_TRACK:
core.command("keypress PREV");
break;
case VK_MEDIA_PLAY_PAUSE:
core.command("keypress PLAYPAUSE");
break;
case VK_MEDIA_STOP:
core.command("keypress STOP");
break;
}
break; break;
case 0x0200: // WM_MOUSEMOVE case 0x0200: // WM_MOUSEMOVE
if (Environment.TickCount - LastCycleFullscreen > 500) if (Environment.TickCount - LastCycleFullscreen > 500)
@@ -743,8 +721,6 @@ namespace mpvnet
Taskbar.SetValue(core.get_property_number("time-pos"), core.Duration.TotalSeconds); Taskbar.SetValue(core.get_property_number("time-pos"), core.Duration.TotalSeconds);
} }
void RegisterGlobalKey(int key) => RegisterHotKey(Handle, key, 0, (uint)key);
void PropChangeOnTop(bool value) => BeginInvoke(new Action(() => TopMost = value)); void PropChangeOnTop(bool value) => BeginInvoke(new Action(() => TopMost = value));
void PropChangeAid(string value) => core.Aid = value; void PropChangeAid(string value) => core.Aid = value;
@@ -852,6 +828,7 @@ namespace mpvnet
MinimumSize = new Size(FontHeight * 9, FontHeight * 9); MinimumSize = new Size(FontHeight * 9, FontHeight * 9);
UpdateCheck.DailyCheck(); UpdateCheck.DailyCheck();
core.LoadScripts(); core.LoadScripts();
GlobalHotkey.RegisterGlobalHotkeys(Handle);
App.RunTask(() => App.Extension = new Extension()); App.RunTask(() => App.Extension = new Extension());
CSharpScriptHost.ExecuteScriptsInFolder(core.ConfigFolder + "scripts-cs"); CSharpScriptHost.ExecuteScriptsInFolder(core.ConfigFolder + "scripts-cs");
ShownTickCount = Environment.TickCount; ShownTickCount = Environment.TickCount;

View File

@@ -111,6 +111,7 @@
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>
</Page> </Page>
<Compile Include="Misc\Help.cs" /> <Compile Include="Misc\Help.cs" />
<Compile Include="Misc\GlobalHotkey.cs" />
<Compile Include="Misc\UpdateCheck.cs" /> <Compile Include="Misc\UpdateCheck.cs" />
<Compile Include="Misc\Theme.cs" /> <Compile Include="Misc\Theme.cs" />
<Compile Include="Misc\PowerShell.cs" /> <Compile Include="Misc\PowerShell.cs" />