Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c8fe3a4c43 | ||
|
|
19c2502c31 | ||
|
|
56dae4babd | ||
|
|
bc20d7527c | ||
|
|
3d325d4fe5 | ||
|
|
ba0141cfb1 | ||
|
|
d32c7b4056 | ||
|
|
63f064ba1c |
18
Changelog.md
18
Changelog.md
@@ -1,3 +1,21 @@
|
|||||||
|
### 4.4
|
||||||
|
|
||||||
|
- clipboard-monitoring was replaced by url-whitelist:
|
||||||
|
Keyword whitelist to monitor the clipboard for URLs to play.
|
||||||
|
Default: tube vimeo ard zdf
|
||||||
|
- some settings like colors didn't work because enclosing quotes were missing
|
||||||
|
- when single process queue is used the folder is no longer loaded
|
||||||
|
- the playlist is never cleared whenever the control key is down but
|
||||||
|
files and URLs are appended instead
|
||||||
|
- powershell script hosting bugs were fixed and a new powershell example script
|
||||||
|
was added to the [scripting wiki page](https://github.com/stax76/mpv.net/wiki/Scripting#powershell)
|
||||||
|
- the menu entry for the command palette was renamed to 'Show All Commands' and
|
||||||
|
the default key binding was changed to F1 which is also the default in VS Code
|
||||||
|
- the default key binding of the Everything media search was changed to F3
|
||||||
|
- support for the mpv property 'border' was added to the config editor
|
||||||
|
to show/hide the window decoration (titlebar, border). A toggle menu item and
|
||||||
|
key binding (b) was added as well ([Default Binding](https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/inputConf.txt#L135))
|
||||||
|
|
||||||
### 4.3.1
|
### 4.3.1
|
||||||
|
|
||||||
- there was a old bug setting the screen property
|
- there was a old bug setting the screen property
|
||||||
|
|||||||
10
Manual.md
10
Manual.md
@@ -93,9 +93,9 @@
|
|||||||
|
|
||||||
## About mpv.net
|
## About mpv.net
|
||||||
|
|
||||||
mpv.net is a media player for Windows. Similar like VLC mpv.net is not based on DirectShow like MPC, mpv.net is based on libmpv which in return is based on ffmpeg.
|
mpv.net is a modern media player for Windows. mpv is similar to VLC not based on DirectShow like MPC, mpv.net is based on libmpv which in return is based on ffmpeg.
|
||||||
|
|
||||||
libmpv provides the majority of the features of the mpv media player, a fork of mplayer. mpv focuses on the usage of the command line interface, mpv.net retains the ability to be used from the command line and adds a simple and easy to use GUI on top of it.
|
libmpv provides the majority of the features of the mpv media player, a fork of mplayer. mpv focuses on the usage of the command line interface, mpv.net retains the ability to be used from the command line and adds a modern GUI on top of it.
|
||||||
|
|
||||||
mpv.net is meant to be a small single person project, it's designed to be mpv compatible, can use the same settings as mpv and offers almost all mpv features because they are all contained in libmpv, this means the official [mpv manual](https://mpv.io/manual/master/) fully applies to mpv.net.
|
mpv.net is meant to be a small single person project, it's designed to be mpv compatible, can use the same settings as mpv and offers almost all mpv features because they are all contained in libmpv, this means the official [mpv manual](https://mpv.io/manual/master/) fully applies to mpv.net.
|
||||||
|
|
||||||
@@ -141,11 +141,15 @@ Another way to open files is the command line, it is used by the Windows File Ex
|
|||||||
|
|
||||||
A third way is to drag and drop files on the main window.
|
A third way is to drag and drop files on the main window.
|
||||||
|
|
||||||
|
Whenever the control key is pressed when files are opened, the playlist is not cleared but the files are appended to the playlist.
|
||||||
|
|
||||||
### Open > Open URL
|
### Open > Open URL
|
||||||
|
|
||||||
The Open URL menu entry can be used to open URLs for example from YouTube.
|
The Open URL menu entry can be used to open URLs for example from YouTube.
|
||||||
|
|
||||||
mpv.net monitors the Windows clipboard and ask if URLs should be played in case it finds a URL in the clipboard.
|
mpv.net monitors the Windows clipboard and ask if URLs should be played in case it finds a URL in the clipboard. This feature uses a keyword whitelist that can be configured in the config editor.
|
||||||
|
|
||||||
|
Whenever the control key is pressed when URLs are opened, the playlist is not cleared but the URLs are appended to the playlist.
|
||||||
|
|
||||||
### Open > Show media search
|
### Open > Show media search
|
||||||
|
|
||||||
|
|||||||
@@ -192,6 +192,8 @@ Third party components:
|
|||||||
|
|
||||||
[frank.skare.de@gmail.com](mailto:frank.skare.de@gmail.com?Subject=mpv.net%20support)
|
[frank.skare.de@gmail.com](mailto:frank.skare.de@gmail.com?Subject=mpv.net%20support)
|
||||||
|
|
||||||
|
Please click on the star at the top of the page and like mpv.net at [alternativeto.net](https://alternativeto.net/software/mpv-net/).
|
||||||
|
|
||||||
### Links
|
### Links
|
||||||
|
|
||||||
mpv manual: <https://mpv.io/manual/master/>
|
mpv manual: <https://mpv.io/manual/master/>
|
||||||
|
|||||||
@@ -46,9 +46,11 @@ namespace RatingAddon
|
|||||||
|
|
||||||
void mpv_ClientMessage(string[] args)
|
void mpv_ClientMessage(string[] args)
|
||||||
{
|
{
|
||||||
int rating;
|
if (args == null ||
|
||||||
|
args.Length != 2 ||
|
||||||
|
args[0] != "rate-file" ||
|
||||||
|
!int.TryParse(args[1], out int rating))
|
||||||
|
|
||||||
if (args?.Length != 2 || args[0] != "rate-file" || ! int.TryParse(args[1], out rating))
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Dic[mp.get_property_string("path")] = rating;
|
Dic[mp.get_property_string("path")] = rating;
|
||||||
|
|||||||
@@ -45,11 +45,11 @@ namespace DynamicGUI
|
|||||||
optionSetting.Options.Add(opt);
|
optionSetting.Options.Add(opt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (setting["default"].IsString)
|
else
|
||||||
{
|
{
|
||||||
StringSetting stringSetting = new StringSetting();
|
StringSetting stringSetting = new StringSetting();
|
||||||
baseSetting = stringSetting;
|
baseSetting = stringSetting;
|
||||||
stringSetting.Default = setting["default"];
|
stringSetting.Default = setting.HasKey("default") ? setting["default"].ToString() : "";
|
||||||
}
|
}
|
||||||
|
|
||||||
baseSetting.Name = setting["name"];
|
baseSetting.Name = setting["name"];
|
||||||
|
|||||||
@@ -64,7 +64,8 @@ namespace DynamicGUI
|
|||||||
{
|
{
|
||||||
d.FullOpen = true;
|
d.FullOpen = true;
|
||||||
try {
|
try {
|
||||||
d.Color = System.Drawing.ColorTranslator.FromHtml(ValueTextBox.Text);
|
Color col = GetColor(ValueTextBox.Text);
|
||||||
|
d.Color = System.Drawing.Color.FromArgb(col.A, col.R, col.G, col.B);
|
||||||
} catch { }
|
} catch { }
|
||||||
if (d.ShowDialog() == WinForms.DialogResult.OK)
|
if (d.ShowDialog() == WinForms.DialogResult.OK)
|
||||||
ValueTextBox.Text = System.Drawing.ColorTranslator.ToHtml(d.Color);
|
ValueTextBox.Text = System.Drawing.ColorTranslator.ToHtml(d.Color);
|
||||||
@@ -75,29 +76,31 @@ namespace DynamicGUI
|
|||||||
|
|
||||||
private void ValueTextBox_TextChanged(object sender, TextChangedEventArgs e) => Update();
|
private void ValueTextBox_TextChanged(object sender, TextChangedEventArgs e) => Update();
|
||||||
|
|
||||||
|
Color GetColor(string value)
|
||||||
|
{
|
||||||
|
if (value.Contains("/"))
|
||||||
|
{
|
||||||
|
string[] a = value.Split('/');
|
||||||
|
|
||||||
|
if (a.Length == 3)
|
||||||
|
return Color.FromRgb(ToByte(a[0]), ToByte(a[1]), ToByte(a[2]));
|
||||||
|
else if (a.Length == 4)
|
||||||
|
return Color.FromArgb(ToByte(a[3]), ToByte(a[0]), ToByte(a[1]), ToByte(a[2]));
|
||||||
|
}
|
||||||
|
|
||||||
|
return (Color)ColorConverter.ConvertFromString(value);
|
||||||
|
|
||||||
|
Byte ToByte(string val) => Convert.ToByte(Convert.ToSingle(val, CultureInfo.InvariantCulture) * 255);
|
||||||
|
}
|
||||||
|
|
||||||
public void Update()
|
public void Update()
|
||||||
{
|
{
|
||||||
if (StringSetting.Type == "color")
|
if (StringSetting.Type == "color")
|
||||||
{
|
{
|
||||||
Color c = Colors.Transparent;
|
Color c = Colors.Transparent;
|
||||||
if (ValueTextBox.Text != "")
|
if (ValueTextBox.Text != "") try { c = GetColor(ValueTextBox.Text); } catch {}
|
||||||
{
|
|
||||||
try {
|
|
||||||
if (ValueTextBox.Text.Contains("/"))
|
|
||||||
{
|
|
||||||
string[] a = ValueTextBox.Text.Split('/');
|
|
||||||
if (a.Length == 3)
|
|
||||||
c = Color.FromRgb(ToByte(a[0]), ToByte(a[1]), ToByte(a[2]));
|
|
||||||
else if (a.Length == 4)
|
|
||||||
c = Color.FromArgb(ToByte(a[3]), ToByte(a[0]), ToByte(a[1]), ToByte(a[2]));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
c = (Color)ColorConverter.ConvertFromString(ValueTextBox.Text);
|
|
||||||
} catch {}
|
|
||||||
}
|
|
||||||
ValueTextBox.Background = new SolidColorBrush(c);
|
ValueTextBox.Background = new SolidColorBrush(c);
|
||||||
}
|
}
|
||||||
Byte ToByte(string val) => Convert.ToByte(Convert.ToSingle(val, CultureInfo.InvariantCulture) * 255);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -32,10 +32,15 @@ namespace mpvnet
|
|||||||
{
|
{
|
||||||
ParameterInfo[] parameters = i.GetParameters();
|
ParameterInfo[] parameters = i.GetParameters();
|
||||||
|
|
||||||
if (parameters == null || parameters.Length != 1 || parameters[0].ParameterType != typeof(string[]))
|
if (parameters == null ||
|
||||||
|
parameters.Length != 1 ||
|
||||||
|
parameters[0].ParameterType != typeof(string[]))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
Command cmd = new Command() { Name = i.Name.Replace("_","-"), Action = (Action<string[]>)i.CreateDelegate(typeof(Action<string[]>)) };
|
Command cmd = new Command() {
|
||||||
|
Name = i.Name.Replace("_", "-"),
|
||||||
|
Action = (Action<string[]>)i.CreateDelegate(typeof(Action<string[]>)) };
|
||||||
|
|
||||||
commands.Add(cmd);
|
commands.Add(cmd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -45,10 +50,30 @@ namespace mpvnet
|
|||||||
|
|
||||||
public static void open_files(string[] args)
|
public static void open_files(string[] args)
|
||||||
{
|
{
|
||||||
|
bool append = Control.ModifierKeys.HasFlag(Keys.Control);
|
||||||
|
bool loadFolder = true;
|
||||||
|
|
||||||
|
foreach (string arg in args)
|
||||||
|
{
|
||||||
|
if (arg == "append") append = true;
|
||||||
|
if (arg == "no-folder") loadFolder = false;
|
||||||
|
}
|
||||||
|
|
||||||
MainForm.Instance.Invoke(new Action(() => {
|
MainForm.Instance.Invoke(new Action(() => {
|
||||||
using (var d = new OpenFileDialog() { Multiselect = true })
|
using (var d = new OpenFileDialog() { Multiselect = true })
|
||||||
if (d.ShowDialog() == DialogResult.OK)
|
if (d.ShowDialog() == DialogResult.OK)
|
||||||
mp.Load(d.FileNames);
|
mp.Load(d.FileNames, loadFolder, append);
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
// deprecated in 2019
|
||||||
|
public static void add_files_to_playlist(string[] args)
|
||||||
|
{
|
||||||
|
MainForm.Instance.Invoke(new Action(() => {
|
||||||
|
using (var d = new OpenFileDialog() { Multiselect = true })
|
||||||
|
if (d.ShowDialog() == DialogResult.OK)
|
||||||
|
foreach (string file in d.FileNames)
|
||||||
|
mp.commandv("loadfile", file, "append");
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -183,9 +208,9 @@ namespace mpvnet
|
|||||||
public static void execute_mpv_command(string[] args)
|
public static void execute_mpv_command(string[] args)
|
||||||
{
|
{
|
||||||
MainForm.Instance.Invoke(new Action(() => {
|
MainForm.Instance.Invoke(new Action(() => {
|
||||||
string command = VB.Interaction.InputBox("Enter a mpv command to be executed.", "Execute Command", RegistryHelp.GetString(App.RegPath, "RecentExecutedCommand"));
|
string command = VB.Interaction.InputBox("Enter a mpv command to be executed.", "Execute Command", RegHelp.GetString(App.RegPath, "RecentExecutedCommand"));
|
||||||
if (string.IsNullOrEmpty(command)) return;
|
if (string.IsNullOrEmpty(command)) return;
|
||||||
RegistryHelp.SetObject(App.RegPath, "RecentExecutedCommand", command);
|
RegHelp.SetObject(App.RegPath, "RecentExecutedCommand", command);
|
||||||
mp.command_string(command, false);
|
mp.command_string(command, false);
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
@@ -195,7 +220,7 @@ namespace mpvnet
|
|||||||
MainForm.Instance.Invoke(new Action(() => {
|
MainForm.Instance.Invoke(new Action(() => {
|
||||||
string command = VB.Interaction.InputBox("Enter URL to be opened.");
|
string command = VB.Interaction.InputBox("Enter URL to be opened.");
|
||||||
if (string.IsNullOrEmpty(command)) return;
|
if (string.IsNullOrEmpty(command)) return;
|
||||||
mp.Load(command);
|
mp.Load(new [] { command }, false, Control.ModifierKeys.HasFlag(Keys.Control));
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -228,16 +253,6 @@ namespace mpvnet
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void add_files_to_playlist(string[] args)
|
|
||||||
{
|
|
||||||
MainForm.Instance.Invoke(new Action(() => {
|
|
||||||
using (var d = new OpenFileDialog() { Multiselect = true })
|
|
||||||
if (d.ShowDialog() == DialogResult.OK)
|
|
||||||
foreach(string file in d.FileNames)
|
|
||||||
mp.commandv("loadfile", file, "append");
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void cycle_audio(string[] args)
|
public static void cycle_audio(string[] args)
|
||||||
{
|
{
|
||||||
string filePath = mp.get_property_string("path", false);
|
string filePath = mp.get_property_string("path", false);
|
||||||
|
|||||||
@@ -13,22 +13,20 @@ using System.Runtime.Serialization;
|
|||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
|
|
||||||
using Microsoft.Win32;
|
using Microsoft.Win32;
|
||||||
using VB = Microsoft.VisualBasic;
|
|
||||||
|
|
||||||
namespace mpvnet
|
namespace mpvnet
|
||||||
{
|
{
|
||||||
public class App
|
public class App
|
||||||
{
|
{
|
||||||
public static string ConfFilePath { get; } = mp.ConfFolder + "\\mpvnet.conf";
|
public static string ConfFilePath { get; } = mp.ConfFolder + "\\mpvnet.conf";
|
||||||
public static string RegPath { get; } = "HKCU\\Software\\" + Application.ProductName;
|
public static string RegPath { get; } = @"HKCU\Software\" + Application.ProductName;
|
||||||
public static string ClipboardMonitoring { get; set; } = "yes";
|
public static string DarkMode { get; set; } = "always";
|
||||||
|
public static string ProcessInstance { get; set; } = "single";
|
||||||
|
|
||||||
public static string[] VideoTypes { get; } = "mkv mp4 mpg avi mov webm vob wmv flv avs 264 h264 asf webm mpeg mpv y4m avc hevc 265 h265 m2v m2ts vpy mts m4v".Split(' ');
|
public static string[] VideoTypes { get; } = "mkv mp4 mpg avi mov webm vob wmv flv avs 264 h264 asf webm mpeg mpv y4m avc hevc 265 h265 m2v m2ts vpy mts m4v".Split(' ');
|
||||||
public static string[] AudioTypes { get; } = "mp3 mp2 ac3 ogg opus flac wav w64 m4a dts dtsma dtshr dtshd eac3 thd thd+ac3 mka aac mpa".Split(' ');
|
public static string[] AudioTypes { get; } = "mp3 mp2 ac3 ogg opus flac wav w64 m4a dts dtsma dtshr dtshd eac3 thd thd+ac3 mka aac mpa".Split(' ');
|
||||||
public static string[] SubtitleTypes { get; } = "srt ass idx sup ttxt ssa smi".Split(' ');
|
public static string[] SubtitleTypes { get; } = "srt ass idx sup ttxt ssa smi".Split(' ');
|
||||||
|
public static string[] UrlWhitelist { get; set; } = { "tube", "vimeo", "ard", "zdf" };
|
||||||
public static string DarkMode { get; set; } = "always";
|
|
||||||
public static string ProcessInstance { get; set; } = "single";
|
|
||||||
|
|
||||||
public static bool DebugMode { get; set; } = false;
|
public static bool DebugMode { get; set; } = false;
|
||||||
|
|
||||||
@@ -85,10 +83,12 @@ namespace mpvnet
|
|||||||
{
|
{
|
||||||
switch (name)
|
switch (name)
|
||||||
{
|
{
|
||||||
case "clipboard-monitoring": ClipboardMonitoring = value; break;
|
|
||||||
case "process-instance": ProcessInstance = value; break;
|
case "process-instance": ProcessInstance = value; break;
|
||||||
case "dark-mode": DarkMode = value; break;
|
case "dark-mode": DarkMode = value; break;
|
||||||
case "debug-mode": DebugMode = value == "yes"; break;
|
case "debug-mode": DebugMode = value == "yes"; break;
|
||||||
|
case "url-whitelist":
|
||||||
|
UrlWhitelist = value.Split(' ', ',', ';');
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -171,49 +171,49 @@ namespace mpvnet
|
|||||||
{
|
{
|
||||||
Types = types;
|
Types = types;
|
||||||
|
|
||||||
RegistryHelp.SetObject(@"HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\" + ExeFilename, null, ExePath);
|
RegHelp.SetObject(@"HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\" + ExeFilename, null, ExePath);
|
||||||
RegistryHelp.SetObject($"HKCR\\Applications\\{ExeFilename}", "FriendlyAppName", "mpv.net media player");
|
RegHelp.SetObject($"HKCR\\Applications\\{ExeFilename}", "FriendlyAppName", "mpv.net media player");
|
||||||
RegistryHelp.SetObject($"HKCR\\Applications\\{ExeFilename}\\shell\\open\\command", null, $"\"{ExePath}\" \"%1\"");
|
RegHelp.SetObject($"HKCR\\Applications\\{ExeFilename}\\shell\\open\\command", null, $"\"{ExePath}\" \"%1\"");
|
||||||
RegistryHelp.SetObject(@"HKLM\SOFTWARE\Clients\Media\mpv\Capabilities", "ApplicationDescription", "mpv.net media player");
|
RegHelp.SetObject(@"HKLM\SOFTWARE\Clients\Media\mpv\Capabilities", "ApplicationDescription", "mpv.net media player");
|
||||||
RegistryHelp.SetObject(@"HKLM\SOFTWARE\Clients\Media\mpv\Capabilities", "ApplicationName", "mpv.net");
|
RegHelp.SetObject(@"HKLM\SOFTWARE\Clients\Media\mpv\Capabilities", "ApplicationName", "mpv.net");
|
||||||
RegistryHelp.SetObject($"HKCR\\SystemFileAssociations\\video\\OpenWithList\\{ExeFilename}", null, "");
|
RegHelp.SetObject($"HKCR\\SystemFileAssociations\\video\\OpenWithList\\{ExeFilename}", null, "");
|
||||||
RegistryHelp.SetObject($"HKCR\\SystemFileAssociations\\audio\\OpenWithList\\{ExeFilename}", null, "");
|
RegHelp.SetObject($"HKCR\\SystemFileAssociations\\audio\\OpenWithList\\{ExeFilename}", null, "");
|
||||||
|
|
||||||
foreach (string ext in Types)
|
foreach (string ext in Types)
|
||||||
{
|
{
|
||||||
RegistryHelp.SetObject($"HKCR\\Applications\\{ExeFilename}\\SupportedTypes", "." + ext, "");
|
RegHelp.SetObject($"HKCR\\Applications\\{ExeFilename}\\SupportedTypes", "." + ext, "");
|
||||||
RegistryHelp.SetObject($"HKCR\\" + "." + ext, null, ExeFilenameNoExt + "." + ext);
|
RegHelp.SetObject($"HKCR\\" + "." + ext, null, ExeFilenameNoExt + "." + ext);
|
||||||
RegistryHelp.SetObject($"HKCR\\" + "." + ext + "\\OpenWithProgIDs", ExeFilenameNoExt + "." + ext, "");
|
RegHelp.SetObject($"HKCR\\" + "." + ext + "\\OpenWithProgIDs", ExeFilenameNoExt + "." + ext, "");
|
||||||
if (App.VideoTypes.Contains(ext))
|
if (App.VideoTypes.Contains(ext))
|
||||||
RegistryHelp.SetObject($"HKCR\\" + "." + ext, "PerceivedType", "video");
|
RegHelp.SetObject($"HKCR\\" + "." + ext, "PerceivedType", "video");
|
||||||
if (App.AudioTypes.Contains(ext))
|
if (App.AudioTypes.Contains(ext))
|
||||||
RegistryHelp.SetObject($"HKCR\\" + "." + ext, "PerceivedType", "audio");
|
RegHelp.SetObject($"HKCR\\" + "." + ext, "PerceivedType", "audio");
|
||||||
RegistryHelp.SetObject($"HKCR\\" + ExeFilenameNoExt + "." + ext + "\\shell\\open", null, "Play with " + Application.ProductName);
|
RegHelp.SetObject($"HKCR\\" + ExeFilenameNoExt + "." + ext + "\\shell\\open", null, "Play with " + Application.ProductName);
|
||||||
RegistryHelp.SetObject($"HKCR\\" + ExeFilenameNoExt + "." + ext + "\\shell\\open\\command", null, $"\"{ExePath}\" \"%1\"");
|
RegHelp.SetObject($"HKCR\\" + ExeFilenameNoExt + "." + ext + "\\shell\\open\\command", null, $"\"{ExePath}\" \"%1\"");
|
||||||
RegistryHelp.SetObject(@"HKLM\SOFTWARE\Clients\Media\mpv.net\Capabilities\FileAssociations", "." + ext, ExeFilenameNoExt + "." + ext);
|
RegHelp.SetObject(@"HKLM\SOFTWARE\Clients\Media\mpv.net\Capabilities\FileAssociations", "." + ext, ExeFilenameNoExt + "." + ext);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Unregister()
|
public static void Unregister()
|
||||||
{
|
{
|
||||||
RegistryHelp.RemoveKey(@"HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\" + ExeFilename);
|
RegHelp.RemoveKey(@"HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\" + ExeFilename);
|
||||||
RegistryHelp.RemoveKey($"HKCR\\Applications\\{ExeFilename}");
|
RegHelp.RemoveKey($"HKCR\\Applications\\{ExeFilename}");
|
||||||
RegistryHelp.RemoveKey(@"HKLM\SOFTWARE\Clients\Media\mpv.net");
|
RegHelp.RemoveKey(@"HKLM\SOFTWARE\Clients\Media\mpv.net");
|
||||||
RegistryHelp.RemoveKey($"HKCR\\SystemFileAssociations\\video\\OpenWithList\\{ExeFilename}");
|
RegHelp.RemoveKey($"HKCR\\SystemFileAssociations\\video\\OpenWithList\\{ExeFilename}");
|
||||||
RegistryHelp.RemoveKey($"HKCR\\SystemFileAssociations\\audio\\OpenWithList\\{ExeFilename}");
|
RegHelp.RemoveKey($"HKCR\\SystemFileAssociations\\audio\\OpenWithList\\{ExeFilename}");
|
||||||
|
|
||||||
foreach (string id in Registry.ClassesRoot.GetSubKeyNames())
|
foreach (string id in Registry.ClassesRoot.GetSubKeyNames())
|
||||||
{
|
{
|
||||||
if (id.StartsWith(ExeFilenameNoExt + "."))
|
if (id.StartsWith(ExeFilenameNoExt + "."))
|
||||||
Registry.ClassesRoot.DeleteSubKeyTree(id);
|
Registry.ClassesRoot.DeleteSubKeyTree(id);
|
||||||
|
|
||||||
RegistryHelp.RemoveValue($"HKCR\\Software\\Classes\\" + id + "\\OpenWithProgIDs", ExeFilenameNoExt + id);
|
RegHelp.RemoveValue($"HKCR\\Software\\Classes\\" + id + "\\OpenWithProgIDs", ExeFilenameNoExt + id);
|
||||||
RegistryHelp.RemoveValue($"HKLM\\Software\\Classes\\" + id + "\\OpenWithProgIDs", ExeFilenameNoExt + id);
|
RegHelp.RemoveValue($"HKLM\\Software\\Classes\\" + id + "\\OpenWithProgIDs", ExeFilenameNoExt + id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class RegistryHelp
|
public class RegHelp
|
||||||
{
|
{
|
||||||
public static void SetObject(string path, string name, object value)
|
public static void SetObject(string path, string name, object value)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -37,9 +37,9 @@ namespace mpvnet
|
|||||||
files.Add(arg);
|
files.Add(arg);
|
||||||
|
|
||||||
if (files.Count > 0)
|
if (files.Count > 0)
|
||||||
RegistryHelp.SetObject(App.RegPath, "ShellFiles", files.ToArray());
|
RegHelp.SetObject(App.RegPath, "ShellFiles", files.ToArray());
|
||||||
|
|
||||||
RegistryHelp.SetObject(App.RegPath, "ProcessInstanceMode", App.ProcessInstance);
|
RegHelp.SetObject(App.RegPath, "ProcessInstanceMode", App.ProcessInstance);
|
||||||
|
|
||||||
foreach(Process process in Process.GetProcessesByName("mpvnet"))
|
foreach(Process process in Process.GetProcessesByName("mpvnet"))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -27,9 +27,6 @@ namespace mpvnet
|
|||||||
[DllImport("user32.dll", SetLastError = true)]
|
[DllImport("user32.dll", SetLastError = true)]
|
||||||
public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, int uFlags);
|
public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, int uFlags);
|
||||||
|
|
||||||
[DllImport("user32.dll")]
|
|
||||||
public static extern bool EnableWindow(IntPtr hWnd, bool bEnable);
|
|
||||||
|
|
||||||
[DllImport("user32.dll", EntryPoint = "GetWindowLong")]
|
[DllImport("user32.dll", EntryPoint = "GetWindowLong")]
|
||||||
private static extern IntPtr GetWindowLong32(IntPtr hWnd, int nIndex);
|
private static extern IntPtr GetWindowLong32(IntPtr hWnd, int nIndex);
|
||||||
|
|
||||||
|
|||||||
@@ -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("4.3.1.0")]
|
[assembly: AssemblyVersion("4.4.0.0")]
|
||||||
[assembly: AssemblyFileVersion("4.3.1.0")]
|
[assembly: AssemblyFileVersion("4.4.0.0")]
|
||||||
|
|||||||
47
mpv.net/Properties/Resources.Designer.cs
generated
47
mpv.net/Properties/Resources.Designer.cs
generated
@@ -84,31 +84,9 @@ namespace mpvnet.Properties {
|
|||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Looks up a localized string similar to
|
/// Looks up a localized string similar to
|
||||||
/// # This file defines the input (keys and mouse) bindings of mpv and mpv.net
|
///# manual: https://mpv.io/manual/master/
|
||||||
/// # and it also defines the context menu of mpv.net. mpv.net has an input
|
|
||||||
/// # editor and an config editor as alternatives to editing conf text files.
|
|
||||||
/// # The input and config editor can be found in mpv.net's context menu at:
|
|
||||||
///
|
///
|
||||||
/// # Settings > Show Config Editor
|
///# defaults: https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/mpvConf.txt
|
||||||
/// # Settings > Show Input Editor
|
|
||||||
///
|
|
||||||
/// # The defaults of this file can be found at:
|
|
||||||
///
|
|
||||||
/// # https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/inputConf.txt
|
|
||||||
///
|
|
||||||
/// # t [rest of string was truncated]";.
|
|
||||||
/// </summary>
|
|
||||||
internal static string inputConfHeader {
|
|
||||||
get {
|
|
||||||
return ResourceManager.GetString("inputConfHeader", resourceCulture);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Looks up a localized string similar to
|
|
||||||
///# mpv manual: https://mpv.io/manual/master/
|
|
||||||
///
|
|
||||||
///# mpv.net mpv.conf defaults: https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/mpvConf.txt
|
|
||||||
///
|
///
|
||||||
///input-ar-delay = 500
|
///input-ar-delay = 500
|
||||||
///input-ar-rate = 20
|
///input-ar-rate = 20
|
||||||
@@ -116,10 +94,9 @@ namespace mpvnet.Properties {
|
|||||||
///hwdec = yes
|
///hwdec = yes
|
||||||
///keep-open = yes
|
///keep-open = yes
|
||||||
///keep-open-pause = no
|
///keep-open-pause = no
|
||||||
///osd-playing-msg = ${filename}
|
///osd-playing-msg = '${filename}'
|
||||||
///screenshot-directory = ~~desktop/
|
///screenshot-directory = '~~desktop/'
|
||||||
///input-default-bindings = no
|
///input-default-bindings = no.
|
||||||
///.
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal static string mpvConf {
|
internal static string mpvConf {
|
||||||
get {
|
get {
|
||||||
@@ -164,12 +141,16 @@ namespace mpvnet.Properties {
|
|||||||
/// { name = "never" }]
|
/// { name = "never" }]
|
||||||
///
|
///
|
||||||
///[[settings]]
|
///[[settings]]
|
||||||
///name = "clipboard-monitoring"
|
///name = "url-whitelist"
|
||||||
///default = "yes"
|
|
||||||
///filter = "mpv.net"
|
///filter = "mpv.net"
|
||||||
///help = "Monitors the clipboard for URLs to play."
|
///type = "string"
|
||||||
///options = [{ name = "yes" },
|
///help = "Whitelist to monitor the clipboard for URLs to play.\n\nDefault: tube vimeo ard zdf"
|
||||||
/// { name = "no" }].
|
///
|
||||||
|
///[[settings]]
|
||||||
|
///name = "process-instance"
|
||||||
|
///default = "single"
|
||||||
|
///filter = "mpv.net"
|
||||||
|
///help = "Defines [rest of string was truncated]";.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal static string mpvNetConfToml {
|
internal static string mpvNetConfToml {
|
||||||
get {
|
get {
|
||||||
|
|||||||
@@ -121,9 +121,6 @@
|
|||||||
<data name="inputConf" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
<data name="inputConf" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||||
<value>..\Resources\inputConf.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252</value>
|
<value>..\Resources\inputConf.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="inputConfHeader" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
|
||||||
<value>..\Resources\inputConfHeader.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
|
|
||||||
</data>
|
|
||||||
<data name="mpvConf" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
<data name="mpvConf" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||||
<value>..\Resources\mpvConf.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
|
<value>..\Resources\mpvConf.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
|
||||||
</data>
|
</data>
|
||||||
|
|||||||
@@ -30,8 +30,8 @@
|
|||||||
Alt+a script-message mpv.net load-audio #menu: Open > Load external audio files...
|
Alt+a script-message mpv.net load-audio #menu: Open > Load external audio files...
|
||||||
Alt+s script-message mpv.net load-sub #menu: Open > Load external subtitle files...
|
Alt+s script-message mpv.net load-sub #menu: Open > Load external subtitle files...
|
||||||
_ ignore #menu: Open > -
|
_ ignore #menu: Open > -
|
||||||
_ script-message mpv.net add-files-to-playlist #menu: Open > Add files to playlist...
|
_ script-message mpv.net open-files append #menu: Open > Add files to playlist...
|
||||||
Ctrl+S script-message mpv.net show-media-search #menu: Open > Show media search...
|
F3 script-message mpv.net show-media-search #menu: Open > Show media search...
|
||||||
_ ignore #menu: Open > -
|
_ ignore #menu: Open > -
|
||||||
_ ignore #menu: Open > Recent
|
_ ignore #menu: Open > Recent
|
||||||
|
|
||||||
@@ -132,6 +132,7 @@
|
|||||||
|
|
||||||
Ctrl+t set ontop yes #menu: View > On Top > Enable
|
Ctrl+t set ontop yes #menu: View > On Top > Enable
|
||||||
Ctrl+T set ontop no #menu: View > On Top > Disable
|
Ctrl+T set ontop no #menu: View > On Top > Disable
|
||||||
|
b cycle border #menu: View > Toggle Border
|
||||||
i script-message mpv.net show-info #menu: View > File Info
|
i script-message mpv.net show-info #menu: View > File Info
|
||||||
t script-binding stats/display-stats #menu: View > Show Statistics
|
t script-binding stats/display-stats #menu: View > Show Statistics
|
||||||
T script-binding stats/display-stats-toggle #menu: View > Toggle Statistics
|
T script-binding stats/display-stats-toggle #menu: View > Toggle Statistics
|
||||||
@@ -143,11 +144,11 @@
|
|||||||
Ctrl+i script-message mpv.net show-input-editor #menu: Settings > Show Input Editor
|
Ctrl+i script-message mpv.net show-input-editor #menu: Settings > Show Input Editor
|
||||||
Ctrl+f script-message mpv.net open-conf-folder #menu: Settings > Open Config Folder
|
Ctrl+f script-message mpv.net open-conf-folder #menu: Settings > Open Config Folder
|
||||||
|
|
||||||
Ctrl+P script-message mpv.net show-command-palette #menu: Tools > Command Palette
|
F1 script-message mpv.net show-command-palette #menu: Tools > Show All Commands
|
||||||
h script-message mpv.net show-history #menu: Tools > Show History
|
h script-message mpv.net show-history #menu: Tools > Show History
|
||||||
l ab-loop #menu: Tools > Set/clear A-B loop points
|
l ab-loop #menu: Tools > Set/clear A-B loop points
|
||||||
L cycle-values loop-file "inf" "no" #menu: Tools > Toggle infinite file looping
|
L cycle-values loop-file "inf" "no" #menu: Tools > Toggle infinite file looping
|
||||||
Ctrl+h cycle-values hwdec "auto" "no" #menu: Tools > Cycle Hardware Decoding
|
Ctrl+h cycle-values hwdec "auto" "no" #menu: Tools > Toggle Hardware Decoding
|
||||||
_ script-message mpv.net execute-mpv-command #menu: Tools > Execute mpv command...
|
_ script-message mpv.net execute-mpv-command #menu: Tools > Execute mpv command...
|
||||||
_ script-message mpv.net manage-file-associations #menu: Tools > Manage File Associations...
|
_ script-message mpv.net manage-file-associations #menu: Tools > Manage File Associations...
|
||||||
|
|
||||||
@@ -179,5 +180,6 @@
|
|||||||
Wheel_Down add volume -10
|
Wheel_Down add volume -10
|
||||||
Prev playlist-prev
|
Prev playlist-prev
|
||||||
Next playlist-next
|
Next playlist-next
|
||||||
|
Ctrl+Wheel_Up no-osd seek 7
|
||||||
|
Ctrl+Wheel_Down no-osd seek -7
|
||||||
MBTN_LEFT_DBL cycle fullscreen
|
MBTN_LEFT_DBL cycle fullscreen
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
|
|
||||||
# This file defines the input (keys and mouse) bindings of mpv and mpv.net
|
|
||||||
# and it also defines the context menu of mpv.net. mpv.net has an input
|
|
||||||
# editor and an config editor as alternatives to editing conf text files.
|
|
||||||
# The input and config editor can be found in mpv.net's context menu at:
|
|
||||||
|
|
||||||
# Settings > Show Config Editor
|
|
||||||
# Settings > Show Input Editor
|
|
||||||
|
|
||||||
# The defaults of this file can be found at:
|
|
||||||
|
|
||||||
# https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/inputConf.txt
|
|
||||||
|
|
||||||
# the defaults of mpv can be found at:
|
|
||||||
|
|
||||||
# https://github.com/mpv-player/mpv/blob/master/etc/inputConf
|
|
||||||
|
|
||||||
# mpv.net's defaults of mpv.conf contain: 'input-default-bindings = no'
|
|
||||||
# which disables mpv's input defaults. Every line in this file begins with a
|
|
||||||
# space character to make it easier to do a text search, so if you want to know
|
|
||||||
# if 'o' has already a binding you can make a text search on ' o '.
|
|
||||||
|
|
||||||
# mpv input commands: https://github.com/stax76/mpv.net/wiki/mpv-input-commands
|
|
||||||
|
|
||||||
# mpv input keys: https://github.com/stax76/mpv.net/wiki/mpv-input-keys
|
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
# mpv manual: https://mpv.io/manual/master/
|
# manual: https://mpv.io/manual/master/
|
||||||
|
|
||||||
# mpv.net mpv.conf defaults: https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/mpvConf.txt
|
# defaults: https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/mpvConf.txt
|
||||||
|
|
||||||
input-ar-delay = 500
|
input-ar-delay = 500
|
||||||
input-ar-rate = 20
|
input-ar-rate = 20
|
||||||
@@ -9,6 +9,6 @@ volume = 50
|
|||||||
hwdec = yes
|
hwdec = yes
|
||||||
keep-open = yes
|
keep-open = yes
|
||||||
keep-open-pause = no
|
keep-open-pause = no
|
||||||
osd-playing-msg = ${filename}
|
osd-playing-msg = '${filename}'
|
||||||
screenshot-directory = ~~desktop/
|
screenshot-directory = '~~desktop/'
|
||||||
input-default-bindings = no
|
input-default-bindings = no
|
||||||
@@ -147,8 +147,8 @@ help = "Set the startup volume. 0 means silence, 100 means no volume reduction o
|
|||||||
|
|
||||||
[[settings]]
|
[[settings]]
|
||||||
name = "alang"
|
name = "alang"
|
||||||
default = ""
|
|
||||||
filter = "Audio"
|
filter = "Audio"
|
||||||
|
type = "string"
|
||||||
help = "Specify a priority list of audio languages to use. Different container formats employ different language codes. DVDs use ISO 639-1 two-letter language codes, Matroska, MPEG-TS and NUT use ISO 639-2 three-letter language codes, while OGM uses a free-form identifier. See also aid.\n\nExamples\n\nmpv dvd://1 alang=hu,en chooses the Hungarian language track on a DVD and falls back on English if Hungarian is not available.\n\nmpv alang=jpn example.mkv plays a Matroska file with Japanese audio."
|
help = "Specify a priority list of audio languages to use. Different container formats employ different language codes. DVDs use ISO 639-1 two-letter language codes, Matroska, MPEG-TS and NUT use ISO 639-2 three-letter language codes, while OGM uses a free-form identifier. See also aid.\n\nExamples\n\nmpv dvd://1 alang=hu,en chooses the Hungarian language track on a DVD and falls back on English if Hungarian is not available.\n\nmpv alang=jpn example.mkv plays a Matroska file with Japanese audio."
|
||||||
|
|
||||||
[[settings]]
|
[[settings]]
|
||||||
@@ -163,8 +163,8 @@ options = [{ name = "no", help = "Don't automatically load external audio fil
|
|||||||
|
|
||||||
[[settings]]
|
[[settings]]
|
||||||
name = "slang"
|
name = "slang"
|
||||||
default = ""
|
|
||||||
filter = "Subtitle"
|
filter = "Subtitle"
|
||||||
|
type = "string"
|
||||||
help = "Specify a priority list of subtitle languages to use. Different container formats employ different language codes. DVDs use ISO 639-1 two letter language codes, Matroska uses ISO 639-2 three letter language codes while OGM uses a free-form identifier. See also sid."
|
help = "Specify a priority list of subtitle languages to use. Different container formats employ different language codes. DVDs use ISO 639-1 two letter language codes, Matroska uses ISO 639-2 three letter language codes while OGM uses a free-form identifier. See also sid."
|
||||||
|
|
||||||
[[settings]]
|
[[settings]]
|
||||||
@@ -179,57 +179,33 @@ options = [{ name = "no", help = "Don't automatically load external subtitle
|
|||||||
|
|
||||||
[[settings]]
|
[[settings]]
|
||||||
name = "sub-font"
|
name = "sub-font"
|
||||||
default = ""
|
|
||||||
filter = "Subtitle"
|
filter = "Subtitle"
|
||||||
|
type = "string"
|
||||||
help = "Specify font to use for subtitles that do not themselves specify a particular font. The default is sans-serif."
|
help = "Specify font to use for subtitles that do not themselves specify a particular font. The default is sans-serif."
|
||||||
|
|
||||||
[[settings]]
|
[[settings]]
|
||||||
name = "sub-font-size"
|
name = "sub-font-size"
|
||||||
default = ""
|
|
||||||
filter = "Subtitle"
|
filter = "Subtitle"
|
||||||
help = "Specify the sub font size. The unit is the size in scaled pixels at a window height of 720. The actual pixel size is scaled with the window height: if the window height is larger or smaller than 720, the actual size of the text increases or decreases as well. Default: 55"
|
help = "Specify the sub font size. The unit is the size in scaled pixels at a window height of 720. The actual pixel size is scaled with the window height: if the window height is larger or smaller than 720, the actual size of the text increases or decreases as well. Default: 55"
|
||||||
|
|
||||||
[[settings]]
|
[[settings]]
|
||||||
name = "sub-color"
|
name = "sub-color"
|
||||||
default = ""
|
|
||||||
type = "color"
|
type = "color"
|
||||||
filter = "Subtitle"
|
filter = "Subtitle"
|
||||||
help = "Specify the color used for unstyled text subtitles.\n\nThe color is specified in the form r/g/b, where each color component is specified as number in the range 0.0 to 1.0. It's also possible to specify the transparency by using r/g/b/a, where the alpha value 0 means fully transparent, and 1.0 means opaque. If the alpha component is not given, the color is 100% opaque.\n\nPassing a single number to the option sets the sub to gray, and the form gray/a lets you specify alpha additionally.\n\nExamples\n\n1.0/0.0/0.0 set sub to opaque red\n1.0/0.0/0.0/0.75 set sub to opaque red with 75% alpha\n0.5/0.75 set sub to 50% gray with 75% alpha\n\nAlternatively, the color can be specified as a RGB hex triplet in the form #RRGGBB, where each 2-digit group expresses a color value in the range 0 (00) to 255 (FF). For example, #FF0000 is red. This is similar to web colors. Alpha is given with #AARRGGBB.\n\nExamples\n\n#FF0000 set sub to opaque red\n#C0808080 set sub to 50% gray with 75% alpha"
|
help = "Specify the color used for unstyled text subtitles.\n\nThe color is specified in the form r/g/b, where each color component is specified as number in the range 0.0 to 1.0. It's also possible to specify the transparency by using r/g/b/a, where the alpha value 0 means fully transparent, and 1.0 means opaque. If the alpha component is not given, the color is 100% opaque.\n\nPassing a single number to the option sets the sub to gray, and the form gray/a lets you specify alpha additionally.\n\nExamples\n\n1.0/0.0/0.0 set sub to opaque red\n1.0/0.0/0.0/0.75 set sub to opaque red with 75% alpha\n0.5/0.75 set sub to 50% gray with 75% alpha\n\nAlternatively, the color can be specified as a RGB hex triplet in the form #RRGGBB, where each 2-digit group expresses a color value in the range 0 (00) to 255 (FF). For example, #FF0000 is red. This is similar to web colors. Alpha is given with #AARRGGBB.\n\nExamples\n\n#FF0000 set sub to opaque red\n#C0808080 set sub to 50% gray with 75% alpha"
|
||||||
|
|
||||||
[[settings]]
|
[[settings]]
|
||||||
name = "sub-border-color"
|
name = "sub-border-color"
|
||||||
default = ""
|
|
||||||
type = "color"
|
type = "color"
|
||||||
filter = "Subtitle"
|
filter = "Subtitle"
|
||||||
help = "See sub-color. Color used for the sub font border. Ignored when sub-back-color is specified (or more exactly: when that option is not set to completely transparent)."
|
help = "See sub-color. Color used for the sub font border. Ignored when sub-back-color is specified (or more exactly: when that option is not set to completely transparent)."
|
||||||
|
|
||||||
[[settings]]
|
[[settings]]
|
||||||
name = "sub-back-color"
|
name = "sub-back-color"
|
||||||
default = ""
|
|
||||||
type = "color"
|
type = "color"
|
||||||
filter = "Subtitle"
|
filter = "Subtitle"
|
||||||
help = "See sub-color. Color used for sub text background. You can use sub-shadow-offset to change its size relative to the text."
|
help = "See sub-color. Color used for sub text background. You can use sub-shadow-offset to change its size relative to the text."
|
||||||
|
|
||||||
[[settings]]
|
|
||||||
name = "screen"
|
|
||||||
default = ""
|
|
||||||
filter = "Screen"
|
|
||||||
help = "<0-32> In multi-monitor configurations (i.e. a single desktop that spans across multiple displays), this option tells mpv which screen to display the video on."
|
|
||||||
|
|
||||||
[[settings]]
|
|
||||||
name = "osd-playing-msg"
|
|
||||||
default = ""
|
|
||||||
width = 300
|
|
||||||
filter = "Screen"
|
|
||||||
help = "Show a message on OSD when playback starts. The string is expanded for properties, e.g. osd-playing-msg='file: ${filename}' will show the message file: followed by a space and the currently played filename. For more information visit:"
|
|
||||||
helpurl = "https://mpv.io/manual/master/#property-expansion"
|
|
||||||
|
|
||||||
[[settings]]
|
|
||||||
name = "osd-font-size"
|
|
||||||
default = "55"
|
|
||||||
filter = "Screen"
|
|
||||||
help = "Specify the OSD font size. See sub-font-size for details. Default: 55"
|
|
||||||
|
|
||||||
[[settings]]
|
[[settings]]
|
||||||
name = "fullscreen"
|
name = "fullscreen"
|
||||||
default = "no"
|
default = "no"
|
||||||
@@ -238,9 +214,35 @@ help = "Start the player in fullscreen mode."
|
|||||||
options = [{ name = "yes" },
|
options = [{ name = "yes" },
|
||||||
{ name = "no" }]
|
{ name = "no" }]
|
||||||
|
|
||||||
|
[[settings]]
|
||||||
|
name = "border"
|
||||||
|
default = "yes"
|
||||||
|
filter = "Screen"
|
||||||
|
help = "Show window with decoration (titlebar, border)."
|
||||||
|
options = [{ name = "yes" },
|
||||||
|
{ name = "no" }]
|
||||||
|
|
||||||
|
[[settings]]
|
||||||
|
name = "screen"
|
||||||
|
filter = "Screen"
|
||||||
|
help = "<0-32> In multi-monitor configurations (i.e. a single desktop that spans across multiple displays), this option tells mpv which screen to display the video on."
|
||||||
|
|
||||||
|
[[settings]]
|
||||||
|
name = "osd-playing-msg"
|
||||||
|
width = 300
|
||||||
|
filter = "Screen"
|
||||||
|
type = "string"
|
||||||
|
help = "Show a message on OSD when playback starts. The string is expanded for properties, e.g. osd-playing-msg='file: ${filename}' will show the message file: followed by a space and the currently played filename. For more information visit:"
|
||||||
|
helpurl = "https://mpv.io/manual/master/#property-expansion"
|
||||||
|
|
||||||
|
[[settings]]
|
||||||
|
name = "osd-font-size"
|
||||||
|
default = "55"
|
||||||
|
filter = "Screen"
|
||||||
|
help = "Specify the OSD font size. See sub-font-size for details. Default: 55"
|
||||||
|
|
||||||
[[settings]]
|
[[settings]]
|
||||||
name = "screenshot-directory"
|
name = "screenshot-directory"
|
||||||
default = ""
|
|
||||||
width = 500
|
width = 500
|
||||||
type = "folder"
|
type = "folder"
|
||||||
filter = "Screen"
|
filter = "Screen"
|
||||||
@@ -271,7 +273,6 @@ options = [{ name = "yes", help = "Don't terminate if the current file is the
|
|||||||
|
|
||||||
[[settings]]
|
[[settings]]
|
||||||
name = "loop-file"
|
name = "loop-file"
|
||||||
default = ""
|
|
||||||
filter = "Playback"
|
filter = "Playback"
|
||||||
help = "Loop a single file N times. inf means forever, no means normal playback.\n\nThe difference to loop-playlist is that this doesn't loop the playlist, just the file itself. If the playlist contains only a single file, the difference between the two option is that this option performs a seek on loop, instead of reloading the file. loop is an alias for this option."
|
help = "Loop a single file N times. inf means forever, no means normal playback.\n\nThe difference to loop-playlist is that this doesn't loop the playlist, just the file itself. If the playlist contains only a single file, the difference between the two option is that this option performs a seek on loop, instead of reloading the file. loop is an alias for this option."
|
||||||
|
|
||||||
@@ -285,13 +286,11 @@ options = [{ name = "yes" },
|
|||||||
|
|
||||||
[[settings]]
|
[[settings]]
|
||||||
name = "input-ar-delay"
|
name = "input-ar-delay"
|
||||||
default = ""
|
|
||||||
filter = "Input"
|
filter = "Input"
|
||||||
help = "Delay in milliseconds before we start to autorepeat a key (0 to disable)."
|
help = "Delay in milliseconds before we start to autorepeat a key (0 to disable)."
|
||||||
|
|
||||||
[[settings]]
|
[[settings]]
|
||||||
name = "input-ar-rate"
|
name = "input-ar-rate"
|
||||||
default = ""
|
|
||||||
filter = "Input"
|
filter = "Input"
|
||||||
help = "Number of key presses to generate per second on autorepeat."
|
help = "Number of key presses to generate per second on autorepeat."
|
||||||
|
|
||||||
@@ -315,6 +314,5 @@ options = [{ name = "yes" },
|
|||||||
|
|
||||||
[[settings]]
|
[[settings]]
|
||||||
name = "loop-playlist"
|
name = "loop-playlist"
|
||||||
default = ""
|
|
||||||
filter = "Playback"
|
filter = "Playback"
|
||||||
help = "<N|inf|force|no> Loops playback N times. A value of 1 plays it one time (default), 2 two times, etc. inf means forever. no is the same as 1 and disables looping. If several files are specified on command line, the entire playlist is looped. The force mode is like inf, but does not skip playlist entries which have been marked as failing. This means the player might waste CPU time trying to loop a file that doesn't exist. But it might be useful for playing webradios under very bad network conditions."
|
help = "<N|inf|force|no> Loops playback N times. A value of 1 plays it one time (default), 2 two times, etc. inf means forever. no is the same as 1 and disables looping. If several files are specified on command line, the entire playlist is looped. The force mode is like inf, but does not skip playlist entries which have been marked as failing. This means the player might waste CPU time trying to loop a file that doesn't exist. But it might be useful for playing webradios under very bad network conditions."
|
||||||
@@ -8,12 +8,10 @@ options = [{ name = "always" },
|
|||||||
{ name = "never" }]
|
{ name = "never" }]
|
||||||
|
|
||||||
[[settings]]
|
[[settings]]
|
||||||
name = "clipboard-monitoring"
|
name = "url-whitelist"
|
||||||
default = "yes"
|
|
||||||
filter = "mpv.net"
|
filter = "mpv.net"
|
||||||
help = "Monitors the clipboard for URLs to play."
|
type = "string"
|
||||||
options = [{ name = "yes" },
|
help = "Whitelist to monitor the clipboard for URLs to play.\n\nDefault: tube vimeo ard zdf"
|
||||||
{ name = "no" }]
|
|
||||||
|
|
||||||
[[settings]]
|
[[settings]]
|
||||||
name = "process-instance"
|
name = "process-instance"
|
||||||
|
|||||||
@@ -14,26 +14,27 @@ namespace mpvnet
|
|||||||
using (Runspace runspace = RunspaceFactory.CreateRunspace())
|
using (Runspace runspace = RunspaceFactory.CreateRunspace())
|
||||||
{
|
{
|
||||||
runspace.ApartmentState = ApartmentState.STA;
|
runspace.ApartmentState = ApartmentState.STA;
|
||||||
runspace.ThreadOptions = PSThreadOptions.UseCurrentThread;
|
|
||||||
runspace.Open();
|
runspace.Open();
|
||||||
|
|
||||||
using (Pipeline pipeline = runspace.CreatePipeline())
|
using (Pipeline pipeline = runspace.CreatePipeline())
|
||||||
{
|
{
|
||||||
pipeline.Commands.AddScript(
|
pipeline.Commands.AddScript(
|
||||||
@"Using namespace mpvnet;
|
"Using namespace mpvnet\n" +
|
||||||
Using namespace System;
|
"Using namespace System\n" +
|
||||||
[System.Reflection.Assembly]::LoadWithPartialName(""mpvnet"")");
|
"[System.Reflection.Assembly]::LoadWithPartialName(\"mpvnet\")\n");
|
||||||
|
|
||||||
pipeline.Commands.AddScript(code);
|
pipeline.Commands.AddScript(code);
|
||||||
|
|
||||||
|
if (parameters != null)
|
||||||
|
foreach (var i in parameters)
|
||||||
|
pipeline.Commands[1].Parameters.Add(null, i);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var ret = pipeline.Invoke(parameters);
|
var ret = pipeline.Invoke();
|
||||||
|
if (ret.Count > 0) return ret[0];
|
||||||
if (ret.Count > 0)
|
|
||||||
return ret[0];
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -46,12 +47,12 @@ Using namespace System;
|
|||||||
throw new Exception();
|
throw new Exception();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex2)
|
catch (Exception e2)
|
||||||
{
|
{
|
||||||
Msg.ShowError("PowerShell Setup Problem\n\nEnsure you have at least PowerShell 5.1 installed.", ex2.ToString());
|
Msg.ShowError("PowerShell Setup Problem\n\nEnsure you have at least PowerShell 5.1 installed.", e2.ToString());
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
Msg.ShowException(ex);
|
Msg.ShowException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -70,17 +71,11 @@ Using namespace System;
|
|||||||
eventObject.FilePath = filePath;
|
eventObject.FilePath = filePath;
|
||||||
|
|
||||||
if (eventInfo.EventHandlerType == typeof(Action))
|
if (eventInfo.EventHandlerType == typeof(Action))
|
||||||
{
|
|
||||||
mi = eventObject.GetType().GetMethod(nameof(PowerShellEventObject.Invoke));
|
mi = eventObject.GetType().GetMethod(nameof(PowerShellEventObject.Invoke));
|
||||||
}
|
|
||||||
else if (eventInfo.EventHandlerType == typeof(Action<EndFileEventMode>))
|
else if (eventInfo.EventHandlerType == typeof(Action<EndFileEventMode>))
|
||||||
{
|
|
||||||
mi = eventObject.GetType().GetMethod(nameof(PowerShellEventObject.InvokeEndFileEventMode));
|
mi = eventObject.GetType().GetMethod(nameof(PowerShellEventObject.InvokeEndFileEventMode));
|
||||||
}
|
|
||||||
else if (eventInfo.EventHandlerType == typeof(Action<string[]>))
|
else if (eventInfo.EventHandlerType == typeof(Action<string[]>))
|
||||||
{
|
|
||||||
mi = eventObject.GetType().GetMethod(nameof(PowerShellEventObject.InvokeStrings));
|
mi = eventObject.GetType().GetMethod(nameof(PowerShellEventObject.InvokeStrings));
|
||||||
}
|
|
||||||
else
|
else
|
||||||
throw new Exception();
|
throw new Exception();
|
||||||
|
|
||||||
@@ -91,10 +86,7 @@ Using namespace System;
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Task.Run(() =>
|
Task.Run(() => PowerShellScript.Execute(File.ReadAllText(filePath), null));
|
||||||
{
|
|
||||||
PowerShellScript.Execute(File.ReadAllText(filePath), new string[] {});
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -104,24 +96,16 @@ Using namespace System;
|
|||||||
public Delegate Delegate { get; set; }
|
public Delegate Delegate { get; set; }
|
||||||
public string FilePath { get; set; }
|
public string FilePath { get; set; }
|
||||||
|
|
||||||
public void Invoke()
|
public void Invoke() => Task.Run(() => { PowerShellScript.Execute(File.ReadAllText(FilePath), null); });
|
||||||
{
|
|
||||||
Task.Run(() => { PowerShellScript.Execute(File.ReadAllText(FilePath), new string[] { }); });
|
|
||||||
}
|
|
||||||
|
|
||||||
public void InvokeEndFileEventMode(EndFileEventMode arg)
|
public void InvokeEndFileEventMode(EndFileEventMode arg)
|
||||||
{
|
{
|
||||||
Task.Run(() =>
|
Task.Run(() => PowerShellScript.Execute(File.ReadAllText(FilePath), new [] { arg.ToString() }));
|
||||||
{
|
|
||||||
PowerShellScript.Execute(File.ReadAllText(FilePath), new string[] { arg.ToString() });
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void InvokeStrings(string[] args)
|
public void InvokeStrings(string[] args)
|
||||||
{
|
{
|
||||||
Task.Run(() => {
|
Task.Run(() => PowerShellScript.Execute(File.ReadAllText(FilePath), args));
|
||||||
PowerShellScript.Execute(File.ReadAllText(FilePath), args);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -28,7 +28,7 @@ namespace mpvnet
|
|||||||
SearchControl.SearchTextBox.TextChanged += SearchTextBox_TextChanged;
|
SearchControl.SearchTextBox.TextChanged += SearchTextBox_TextChanged;
|
||||||
LoadSettings(SettingsDefinitions, Conf);
|
LoadSettings(SettingsDefinitions, Conf);
|
||||||
LoadSettings(NetSettingsDefinitions, NetConf);
|
LoadSettings(NetSettingsDefinitions, NetConf);
|
||||||
SearchControl.Text = RegistryHelp.GetString(@"HKCU\Software\mpv.net", "config editor search");
|
SearchControl.Text = RegHelp.GetString(App.RegPath, "config editor search");
|
||||||
|
|
||||||
if (App.IsDarkMode)
|
if (App.IsDarkMode)
|
||||||
{
|
{
|
||||||
@@ -49,7 +49,7 @@ namespace mpvnet
|
|||||||
private void LoadSettings(List<SettingBase> settingsDefinitions,
|
private void LoadSettings(List<SettingBase> settingsDefinitions,
|
||||||
Dictionary<string, string> confSettings)
|
Dictionary<string, string> confSettings)
|
||||||
{
|
{
|
||||||
foreach (var setting in settingsDefinitions)
|
foreach (SettingBase setting in settingsDefinitions)
|
||||||
{
|
{
|
||||||
if (!FilterStrings.Contains(setting.Filter))
|
if (!FilterStrings.Contains(setting.Filter))
|
||||||
FilterStrings.Add(setting.Filter);
|
FilterStrings.Add(setting.Filter);
|
||||||
@@ -58,7 +58,7 @@ namespace mpvnet
|
|||||||
{
|
{
|
||||||
if (setting.Name == pair.Key)
|
if (setting.Name == pair.Key)
|
||||||
{
|
{
|
||||||
setting.Value = pair.Value;
|
setting.Value = pair.Value.Trim('\'', '"');
|
||||||
setting.StartValue = pair.Value;
|
setting.StartValue = pair.Value;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -132,7 +132,7 @@ namespace mpvnet
|
|||||||
{
|
{
|
||||||
base.OnClosed(e);
|
base.OnClosed(e);
|
||||||
WriteToDisk();
|
WriteToDisk();
|
||||||
RegistryHelp.SetObject(@"HKCU\Software\mpv.net", "config editor search", SearchControl.Text);
|
RegHelp.SetObject(App.RegPath, "config editor search", SearchControl.Text);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WriteToDisk()
|
void WriteToDisk()
|
||||||
@@ -165,17 +165,22 @@ namespace mpvnet
|
|||||||
foreach (var i in Comments[filePath])
|
foreach (var i in Comments[filePath])
|
||||||
content += $"#{i.Key} = {i.Value}\r\n";
|
content += $"#{i.Key} = {i.Value}\r\n";
|
||||||
|
|
||||||
foreach (var setting in settings)
|
foreach (SettingBase setting in settings)
|
||||||
{
|
{
|
||||||
if ((setting.Value ?? "") != setting.Default)
|
if ((setting.Value ?? "") != setting.Default)
|
||||||
confSettings[setting.Name] = setting.Value;
|
if (setting.Type == "string" ||
|
||||||
|
setting.Type == "folder" ||
|
||||||
|
setting.Type == "color")
|
||||||
|
|
||||||
|
confSettings[setting.Name] = "'" + setting.Value + "'";
|
||||||
|
else
|
||||||
|
confSettings[setting.Name] = setting.Value;
|
||||||
|
|
||||||
if (confSettings.ContainsKey(setting.Name) &&
|
if (confSettings.ContainsKey(setting.Name) &&
|
||||||
(setting.Value ?? "") == setting.Default ||
|
(setting.Value ?? "") == setting.Default ||
|
||||||
(setting.Value ?? "") == "")
|
(setting.Value ?? "") == "")
|
||||||
{
|
|
||||||
confSettings.Remove(setting.Name);
|
confSettings.Remove(setting.Name);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var i in confSettings)
|
foreach (var i in confSettings)
|
||||||
|
|||||||
@@ -95,12 +95,8 @@ namespace mpvnet
|
|||||||
ListView.ScrollIntoView(ListView.SelectedItem);
|
ListView.ScrollIntoView(ListView.SelectedItem);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Key.Escape:
|
case Key.Escape: Close(); break;
|
||||||
Close();
|
case Key.Enter: Execute(); break;
|
||||||
break;
|
|
||||||
case Key.Enter:
|
|
||||||
Execute();
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -113,14 +109,11 @@ namespace mpvnet
|
|||||||
void Execute()
|
void Execute()
|
||||||
{
|
{
|
||||||
if (ListView.SelectedItem != null)
|
if (ListView.SelectedItem != null)
|
||||||
mp.Load(ListView.SelectedItem as string);
|
mp.Load(new[] { ListView.SelectedItem as string }, true, Keyboard.Modifiers == ModifierKeys.Control);
|
||||||
Keyboard.Focus(FilterTextBox);
|
Keyboard.Focus(FilterTextBox);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ListView_MouseUp(object sender, MouseButtonEventArgs e)
|
private void ListView_MouseUp(object sender, MouseButtonEventArgs e) => Execute();
|
||||||
{
|
|
||||||
Execute();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void FilterTextBox_TextChanged(object sender, TextChangedEventArgs e)
|
private void FilterTextBox_TextChanged(object sender, TextChangedEventArgs e)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -102,7 +102,15 @@ namespace mpvnet
|
|||||||
|
|
||||||
string GetInputConfContent()
|
string GetInputConfContent()
|
||||||
{
|
{
|
||||||
string text = Properties.Resources.inputConfHeader + "\r\n";
|
string text = null;
|
||||||
|
|
||||||
|
foreach (string line in Properties.Resources.inputConf.Split(new[] { "\r\n" }, StringSplitOptions.None))
|
||||||
|
{
|
||||||
|
string test = line.Trim();
|
||||||
|
if (test == "" || test.StartsWith("#")) text += test + "\r\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
text = "\r\n" + text.Trim() + "\r\n\r\n";
|
||||||
|
|
||||||
foreach (CommandItem item in CommandItem.Items)
|
foreach (CommandItem item in CommandItem.Items)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ using System.Linq;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Diagnostics;
|
|
||||||
|
|
||||||
namespace mpvnet
|
namespace mpvnet
|
||||||
{
|
{
|
||||||
@@ -40,7 +39,7 @@ namespace mpvnet
|
|||||||
MinimumSize = new Size(FontHeight * 16, FontHeight * 9);
|
MinimumSize = new Size(FontHeight * 16, FontHeight * 9);
|
||||||
Text += " " + Application.ProductVersion;
|
Text += " " + Application.ProductVersion;
|
||||||
|
|
||||||
object recent = RegistryHelp.GetObject(App.RegPath, "Recent");
|
object recent = RegHelp.GetObject(App.RegPath, "Recent");
|
||||||
|
|
||||||
if (recent is string[] r)
|
if (recent is string[] r)
|
||||||
RecentFiles = new List<string>(r);
|
RecentFiles = new List<string>(r);
|
||||||
@@ -51,7 +50,7 @@ namespace mpvnet
|
|||||||
App.ProcessCommandLineEarly();
|
App.ProcessCommandLineEarly();
|
||||||
if (mp.Screen == -1) mp.Screen = Array.IndexOf(Screen.AllScreens, Screen.PrimaryScreen);
|
if (mp.Screen == -1) mp.Screen = Array.IndexOf(Screen.AllScreens, Screen.PrimaryScreen);
|
||||||
SetScreen(mp.Screen);
|
SetScreen(mp.Screen);
|
||||||
ChangeFullscreen(mp.Fullscreen);
|
CycleFullscreen(mp.Fullscreen);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@@ -59,6 +58,24 @@ namespace mpvnet
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public MenuItem FindMenuItem(string text) => FindMenuItem(text, ContextMenu.Items);
|
||||||
|
|
||||||
|
void Idle() => BeginInvoke(new Action(() => { Text = "mpv.net " + Application.ProductVersion; }));
|
||||||
|
|
||||||
|
void CM_Popup(object sender, EventArgs e) => CursorHelp.Show();
|
||||||
|
|
||||||
|
void VideoSizeChanged() => BeginInvoke(new Action(() => SetFormPosAndSizeKeepHeight()));
|
||||||
|
|
||||||
|
void Shutdown() => BeginInvoke(new Action(() => Close()));
|
||||||
|
|
||||||
|
void PropChangeFullscreen(bool value) => BeginInvoke(new Action(() => CycleFullscreen(value)));
|
||||||
|
|
||||||
|
void ContextMenu_Opened(object sender, EventArgs e) => CursorHelp.Show();
|
||||||
|
|
||||||
|
bool IsFullscreen => WindowState == FormWindowState.Maximized;
|
||||||
|
|
||||||
|
bool IsMouseInOSC() => PointToClient(Control.MousePosition).Y > ClientSize.Height * 0.9;
|
||||||
|
|
||||||
void ContextMenu_Opening(object sender, CancelEventArgs e)
|
void ContextMenu_Opening(object sender, CancelEventArgs e)
|
||||||
{
|
{
|
||||||
lock (mp.MediaTracks)
|
lock (mp.MediaTracks)
|
||||||
@@ -148,10 +165,8 @@ namespace mpvnet
|
|||||||
if (recent != null)
|
if (recent != null)
|
||||||
{
|
{
|
||||||
recent.DropDownItems.Clear();
|
recent.DropDownItems.Clear();
|
||||||
|
|
||||||
foreach (string path in RecentFiles)
|
foreach (string path in RecentFiles)
|
||||||
MenuItem.Add(recent.DropDownItems, path, () => mp.Load(path));
|
MenuItem.Add(recent.DropDownItems, path, () => mp.Load(new[] { path }, true, Control.ModifierKeys.HasFlag(Keys.Control)));
|
||||||
|
|
||||||
recent.DropDownItems.Add(new ToolStripSeparator());
|
recent.DropDownItems.Add(new ToolStripSeparator());
|
||||||
MenuItem mi = new MenuItem("Clear List");
|
MenuItem mi = new MenuItem("Clear List");
|
||||||
mi.Action = () => RecentFiles.Clear();
|
mi.Action = () => RecentFiles.Clear();
|
||||||
@@ -159,8 +174,6 @@ namespace mpvnet
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public MenuItem FindMenuItem(string text) => FindMenuItem(text, ContextMenu.Items);
|
|
||||||
|
|
||||||
MenuItem FindMenuItem(string text, ToolStripItemCollection items)
|
MenuItem FindMenuItem(string text, ToolStripItemCollection items)
|
||||||
{
|
{
|
||||||
foreach (var item in items)
|
foreach (var item in items)
|
||||||
@@ -209,7 +222,7 @@ namespace mpvnet
|
|||||||
Native.SetWindowPos(Handle, IntPtr.Zero /* HWND_TOP */, left, top, rect.Width, rect.Height, 4 /* SWP_NOZORDER */);
|
Native.SetWindowPos(Handle, IntPtr.Zero /* HWND_TOP */, left, top, rect.Width, rect.Height, 4 /* SWP_NOZORDER */);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetFormPositionAndSizeKeepHeight()
|
void SetFormPosAndSizeKeepHeight()
|
||||||
{
|
{
|
||||||
if (IsFullscreen || mp.VideoSize.Width == 0) return;
|
if (IsFullscreen || mp.VideoSize.Width == 0) return;
|
||||||
Screen screen = Screen.FromControl(this);
|
Screen screen = Screen.FromControl(this);
|
||||||
@@ -242,8 +255,7 @@ namespace mpvnet
|
|||||||
|
|
||||||
foreach (CommandItem item in items)
|
foreach (CommandItem item in items)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(item.Path))
|
if (string.IsNullOrEmpty(item.Path)) continue;
|
||||||
continue;
|
|
||||||
string path = item.Path.Replace("&", "&&");
|
string path = item.Path.Replace("&", "&&");
|
||||||
MenuItem menuItem = ContextMenu.Add(path, () => {
|
MenuItem menuItem = ContextMenu.Add(path, () => {
|
||||||
try {
|
try {
|
||||||
@@ -252,14 +264,11 @@ namespace mpvnet
|
|||||||
Msg.ShowException(ex);
|
Msg.ShowException(ex);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
if (menuItem != null)
|
if (menuItem != null) menuItem.ShortcutKeyDisplayString = item.Input + " ";
|
||||||
menuItem.ShortcutKeyDisplayString = item.Input + " ";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ContextMenu_Opened(object sender, EventArgs e) => CursorHelp.Show();
|
private void FileLoaded()
|
||||||
|
|
||||||
private void Mp_FileLoaded()
|
|
||||||
{
|
{
|
||||||
string path = mp.get_property_string("path");
|
string path = mp.get_property_string("path");
|
||||||
BeginInvoke(new Action(() => {
|
BeginInvoke(new Action(() => {
|
||||||
@@ -273,10 +282,6 @@ namespace mpvnet
|
|||||||
if (RecentFiles.Count > 15) RecentFiles.RemoveAt(15);
|
if (RecentFiles.Count > 15) RecentFiles.RemoveAt(15);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mp_Idle() => BeginInvoke(new Action(() => { Text = "mpv.net " + Application.ProductVersion; }));
|
|
||||||
|
|
||||||
void CM_Popup(object sender, EventArgs e) => CursorHelp.Show();
|
|
||||||
|
|
||||||
void Application_ThreadException(object sender, ThreadExceptionEventArgs e)
|
void Application_ThreadException(object sender, ThreadExceptionEventArgs e)
|
||||||
{
|
{
|
||||||
Msg.ShowException(e.Exception);
|
Msg.ShowException(e.Exception);
|
||||||
@@ -286,29 +291,12 @@ namespace mpvnet
|
|||||||
{
|
{
|
||||||
Msg.ShowError(e.ExceptionObject.ToString());
|
Msg.ShowError(e.ExceptionObject.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
void mp_VideoSizeChanged()
|
public void CycleFullscreen(bool enabled)
|
||||||
{
|
{
|
||||||
BeginInvoke(new Action(() => SetFormPositionAndSizeKeepHeight()));
|
if (enabled)
|
||||||
}
|
|
||||||
|
|
||||||
void mp_Shutdown()
|
|
||||||
{
|
|
||||||
BeginInvoke(new Action(() => Close()));
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool IsFullscreen => WindowState == FormWindowState.Maximized;
|
|
||||||
|
|
||||||
void mpPropChangeFullscreen(bool value)
|
|
||||||
{
|
|
||||||
BeginInvoke(new Action(() => ChangeFullscreen(value)));
|
|
||||||
}
|
|
||||||
|
|
||||||
void ChangeFullscreen(bool value)
|
|
||||||
{
|
|
||||||
if (value)
|
|
||||||
{
|
{
|
||||||
if (FormBorderStyle != FormBorderStyle.None)
|
if (WindowState != FormWindowState.Maximized)
|
||||||
{
|
{
|
||||||
FormBorderStyle = FormBorderStyle.None;
|
FormBorderStyle = FormBorderStyle.None;
|
||||||
WindowState = FormWindowState.Maximized;
|
WindowState = FormWindowState.Maximized;
|
||||||
@@ -317,14 +305,19 @@ namespace mpvnet
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
WindowState = FormWindowState.Normal;
|
WindowState = FormWindowState.Normal;
|
||||||
FormBorderStyle = FormBorderStyle.Sizable;
|
|
||||||
SetFormPositionAndSizeKeepHeight();
|
if (mp.Border)
|
||||||
|
FormBorderStyle = FormBorderStyle.Sizable;
|
||||||
|
else
|
||||||
|
FormBorderStyle = FormBorderStyle.None;
|
||||||
|
|
||||||
|
SetFormPosAndSizeKeepHeight();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void WndProc(ref Message m)
|
protected override void WndProc(ref Message m)
|
||||||
{
|
{
|
||||||
//Debug.WriteLine(m);
|
//System.Diagnostics.Debug.WriteLine(m);
|
||||||
|
|
||||||
switch (m.Msg)
|
switch (m.Msg)
|
||||||
{
|
{
|
||||||
@@ -343,6 +336,9 @@ namespace mpvnet
|
|||||||
mp.command_string($"mouse {pos.X} {pos.Y}");
|
mp.command_string($"mouse {pos.X} {pos.Y}");
|
||||||
if (CursorHelp.IsPosDifferent(LastCursorPosChanged)) CursorHelp.Show();
|
if (CursorHelp.IsPosDifferent(LastCursorPosChanged)) CursorHelp.Show();
|
||||||
break;
|
break;
|
||||||
|
case 0x2a3: // WM_MOUSELEAVE
|
||||||
|
mp.command_string("mouse 1 1"); // osc won't always auto hide
|
||||||
|
break;
|
||||||
case 0x319: // WM_APPCOMMAND
|
case 0x319: // WM_APPCOMMAND
|
||||||
if (mp.WindowHandle != IntPtr.Zero)
|
if (mp.WindowHandle != IntPtr.Zero)
|
||||||
Native.PostMessage(mp.WindowHandle, m.Msg, m.WParam, m.LParam);
|
Native.PostMessage(mp.WindowHandle, m.Msg, m.WParam, m.LParam);
|
||||||
@@ -377,14 +373,14 @@ namespace mpvnet
|
|||||||
|
|
||||||
if (m.Msg == SingleProcess.Message)
|
if (m.Msg == SingleProcess.Message)
|
||||||
{
|
{
|
||||||
object filesObject = RegistryHelp.GetObject(App.RegPath, "ShellFiles");
|
object filesObject = RegHelp.GetObject(App.RegPath, "ShellFiles");
|
||||||
|
|
||||||
if (filesObject is string[] files)
|
if (filesObject is string[] files)
|
||||||
{
|
{
|
||||||
switch (RegistryHelp.GetString(App.RegPath, "ProcessInstanceMode"))
|
switch (RegHelp.GetString(App.RegPath, "ProcessInstanceMode"))
|
||||||
{
|
{
|
||||||
case "single":
|
case "single":
|
||||||
mp.Load(files);
|
mp.Load(files, true, Control.ModifierKeys.HasFlag(Keys.Control));
|
||||||
break;
|
break;
|
||||||
case "queue":
|
case "queue":
|
||||||
foreach (string file in files)
|
foreach (string file in files)
|
||||||
@@ -393,7 +389,7 @@ namespace mpvnet
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RegistryHelp.RemoveValue(App.RegPath, "ShellFiles");
|
RegHelp.RemoveValue(App.RegPath, "ShellFiles");
|
||||||
Activate();
|
Activate();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -412,9 +408,100 @@ namespace mpvnet
|
|||||||
{
|
{
|
||||||
base.OnDragDrop(e);
|
base.OnDragDrop(e);
|
||||||
if (e.Data.GetDataPresent(DataFormats.FileDrop))
|
if (e.Data.GetDataPresent(DataFormats.FileDrop))
|
||||||
mp.Load(e.Data.GetData(DataFormats.FileDrop) as String[]);
|
mp.Load(e.Data.GetData(DataFormats.FileDrop) as String[], true, Control.ModifierKeys.HasFlag(Keys.Control));
|
||||||
if (e.Data.GetDataPresent(DataFormats.Text))
|
if (e.Data.GetDataPresent(DataFormats.Text))
|
||||||
mp.Load(e.Data.GetData(DataFormats.Text).ToString());
|
mp.Load(new[] { e.Data.GetData(DataFormats.Text).ToString() }, true, Control.ModifierKeys.HasFlag(Keys.Control));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Timer_Tick(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (CursorHelp.IsPosDifferent(LastCursorPosChanged))
|
||||||
|
{
|
||||||
|
LastCursorPosChanged = Control.MousePosition;
|
||||||
|
LastCursorChangedTickCount = Environment.TickCount;
|
||||||
|
}
|
||||||
|
else if (Environment.TickCount - LastCursorChangedTickCount > 1500 &&
|
||||||
|
!IsMouseInOSC() && ClientRectangle.Contains(PointToClient(MousePosition)) &&
|
||||||
|
Form.ActiveForm == this && !ContextMenu.Visible)
|
||||||
|
|
||||||
|
CursorHelp.Hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PropChangeOnTop(bool value) => BeginInvoke(new Action(() => TopMost = value));
|
||||||
|
|
||||||
|
void PropChangeAid(string value) => mp.Aid = value;
|
||||||
|
|
||||||
|
void PropChangeSid(string value) => mp.Sid = value;
|
||||||
|
|
||||||
|
void PropChangeVid(string value) => mp.Vid = value;
|
||||||
|
|
||||||
|
void PropChangeEdition(int value) => mp.Edition = value;
|
||||||
|
|
||||||
|
void PropChangeBorder(bool enabled) {
|
||||||
|
mp.Border = enabled;
|
||||||
|
|
||||||
|
BeginInvoke(new Action(() => {
|
||||||
|
if (!IsFullscreen)
|
||||||
|
{
|
||||||
|
if (mp.Border && FormBorderStyle == FormBorderStyle.None)
|
||||||
|
FormBorderStyle = FormBorderStyle.Sizable;
|
||||||
|
if (!mp.Border && FormBorderStyle == FormBorderStyle.Sizable)
|
||||||
|
FormBorderStyle = FormBorderStyle.None;
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnLoad(EventArgs e)
|
||||||
|
{
|
||||||
|
base.OnLoad(e);
|
||||||
|
mp.Init();
|
||||||
|
mp.observe_property_bool("fullscreen", PropChangeFullscreen);
|
||||||
|
mp.observe_property_bool("ontop", PropChangeOnTop);
|
||||||
|
mp.observe_property_bool("border", PropChangeBorder);
|
||||||
|
mp.observe_property_string("sid", PropChangeSid);
|
||||||
|
mp.observe_property_string("aid", PropChangeAid);
|
||||||
|
mp.observe_property_string("vid", PropChangeVid);
|
||||||
|
mp.observe_property_int("edition", PropChangeEdition);
|
||||||
|
mp.Shutdown += Shutdown;
|
||||||
|
mp.VideoSizeChanged += VideoSizeChanged;
|
||||||
|
mp.FileLoaded += FileLoaded;
|
||||||
|
mp.Idle += Idle;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnShown(EventArgs e)
|
||||||
|
{
|
||||||
|
base.OnShown(e);
|
||||||
|
if (App.IsDarkMode) ToolStripRendererEx.ColorTheme = Color.Black;
|
||||||
|
ContextMenu = new ContextMenuStripEx(components);
|
||||||
|
ContextMenu.Opened += ContextMenu_Opened;
|
||||||
|
ContextMenu.Opening += ContextMenu_Opening;
|
||||||
|
BuildMenu();
|
||||||
|
ContextMenuStrip = ContextMenu;
|
||||||
|
IgnoreDpiChanged = false;
|
||||||
|
CheckUrlInClipboard();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnActivated(EventArgs e)
|
||||||
|
{
|
||||||
|
base.OnActivated(e);
|
||||||
|
CheckUrlInClipboard();
|
||||||
|
Message m = new Message() { Msg = 0x0202 }; // WM_LBUTTONUP
|
||||||
|
Native.SendMessage(Handle, m.Msg, m.WParam, m.LParam);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnResize(EventArgs e)
|
||||||
|
{
|
||||||
|
base.OnResize(e);
|
||||||
|
if (mp.IsLogoVisible) mp.ShowLogo();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnFormClosed(FormClosedEventArgs e)
|
||||||
|
{
|
||||||
|
base.OnFormClosed(e);
|
||||||
|
RegHelp.SetObject(App.RegPath, "Recent", RecentFiles.ToArray());
|
||||||
|
App.Exit();
|
||||||
|
mp.commandv("quit");
|
||||||
|
mp.AutoResetEvent.WaitOne(3000);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnMouseDown(MouseEventArgs e)
|
protected override void OnMouseDown(MouseEventArgs e)
|
||||||
@@ -434,100 +521,27 @@ namespace mpvnet
|
|||||||
mp.commandv("quit");
|
mp.commandv("quit");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsMouseInOSC() => PointToClient(Control.MousePosition).Y > ClientSize.Height * 0.9;
|
|
||||||
|
|
||||||
void Timer_Tick(object sender, EventArgs e)
|
|
||||||
{
|
|
||||||
if (CursorHelp.IsPosDifferent(LastCursorPosChanged))
|
|
||||||
{
|
|
||||||
LastCursorPosChanged = Control.MousePosition;
|
|
||||||
LastCursorChangedTickCount = Environment.TickCount;
|
|
||||||
}
|
|
||||||
else if (Environment.TickCount - LastCursorChangedTickCount > 1500 &&
|
|
||||||
!IsMouseInOSC() && ClientRectangle.Contains(PointToClient(MousePosition)) &&
|
|
||||||
Form.ActiveForm == this && !ContextMenu.Visible)
|
|
||||||
{
|
|
||||||
CursorHelp.Hide();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnLoad(EventArgs e)
|
|
||||||
{
|
|
||||||
base.OnLoad(e);
|
|
||||||
mp.Init();
|
|
||||||
mp.observe_property_bool("fullscreen", mpPropChangeFullscreen);
|
|
||||||
mp.observe_property_bool("ontop", mpPropChangeOnTop);
|
|
||||||
mp.observe_property_string("sid", mpPropChangeSid);
|
|
||||||
mp.observe_property_string("aid", mpPropChangeAid);
|
|
||||||
mp.observe_property_string("vid", mpPropChangeVid);
|
|
||||||
mp.observe_property_int("edition", mpPropChangeEdition);
|
|
||||||
mp.Shutdown += mp_Shutdown;
|
|
||||||
mp.VideoSizeChanged += mp_VideoSizeChanged;
|
|
||||||
mp.FileLoaded += Mp_FileLoaded;
|
|
||||||
mp.Idle += Mp_Idle;
|
|
||||||
}
|
|
||||||
|
|
||||||
void mpPropChangeOnTop(bool value) => BeginInvoke(new Action(() => TopMost = value));
|
|
||||||
|
|
||||||
void mpPropChangeAid(string value) => mp.Aid = value;
|
|
||||||
|
|
||||||
void mpPropChangeSid(string value) => mp.Sid = value;
|
|
||||||
|
|
||||||
void mpPropChangeVid(string value) => mp.Vid = value;
|
|
||||||
|
|
||||||
void mpPropChangeEdition(int value) => mp.Edition = value;
|
|
||||||
|
|
||||||
protected override void OnShown(EventArgs e)
|
|
||||||
{
|
|
||||||
base.OnShown(e);
|
|
||||||
if (App.IsDarkMode) ToolStripRendererEx.ColorTheme = Color.Black;
|
|
||||||
ContextMenu = new ContextMenuStripEx(components);
|
|
||||||
ContextMenu.Opened += ContextMenu_Opened;
|
|
||||||
ContextMenu.Opening += ContextMenu_Opening;
|
|
||||||
BuildMenu();
|
|
||||||
ContextMenuStrip = ContextMenu;
|
|
||||||
IgnoreDpiChanged = false;
|
|
||||||
CheckURLinClipboard();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnResize(EventArgs e)
|
|
||||||
{
|
|
||||||
base.OnResize(e);
|
|
||||||
if (mp.IsLogoVisible) mp.ShowLogo();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnFormClosed(FormClosedEventArgs e)
|
|
||||||
{
|
|
||||||
base.OnFormClosed(e);
|
|
||||||
RegistryHelp.SetObject(App.RegPath, "Recent", RecentFiles.ToArray());
|
|
||||||
App.Exit();
|
|
||||||
mp.commandv("quit");
|
|
||||||
mp.AutoResetEvent.WaitOne(3000);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnLostFocus(EventArgs e)
|
protected override void OnLostFocus(EventArgs e)
|
||||||
{
|
{
|
||||||
base.OnLostFocus(e);
|
base.OnLostFocus(e);
|
||||||
CursorHelp.Show();
|
CursorHelp.Show();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnActivated(EventArgs e)
|
void CheckUrlInClipboard()
|
||||||
{
|
{
|
||||||
base.OnActivated(e);
|
|
||||||
CheckURLinClipboard();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CheckURLinClipboard()
|
|
||||||
{
|
|
||||||
if (App.ClipboardMonitoring != "yes") return;
|
|
||||||
string clipboard = Clipboard.GetText();
|
string clipboard = Clipboard.GetText();
|
||||||
|
|
||||||
if (clipboard.StartsWith("http") && RegistryHelp.GetString(App.RegPath, "LastURL") != clipboard && Visible)
|
foreach (string url in App.UrlWhitelist)
|
||||||
{
|
{
|
||||||
RegistryHelp.SetObject(App.RegPath, "LastURL", clipboard);
|
if (clipboard.Contains("://") && !clipboard.Contains("\n") &&
|
||||||
|
clipboard.Contains(url.ToLower()) &&
|
||||||
|
RegHelp.GetString(App.RegPath, "LastURL") != clipboard && Visible)
|
||||||
|
{
|
||||||
|
RegHelp.SetObject(App.RegPath, "LastURL", clipboard);
|
||||||
|
|
||||||
if (Msg.ShowQuestion("Play URL?", clipboard) == MsgResult.OK)
|
if (Msg.ShowQuestion("Play URL?", clipboard) == MsgResult.OK)
|
||||||
mp.Load(clipboard);
|
mp.Load(new[] { clipboard }, true, Control.ModifierKeys.HasFlag(Keys.Control));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -260,7 +260,6 @@
|
|||||||
<None Include="App.config" />
|
<None Include="App.config" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Content Include="Resources\inputConfHeader.txt" />
|
|
||||||
<Content Include="Resources\inputConf.txt" />
|
<Content Include="Resources\inputConf.txt" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -65,17 +65,36 @@ namespace mpvnet
|
|||||||
public static List<MediaTrack> MediaTracks { get; set; } = new List<MediaTrack>();
|
public static List<MediaTrack> MediaTracks { get; set; } = new List<MediaTrack>();
|
||||||
public static List<KeyValuePair<string, double>> Chapters { get; set; } = new List<KeyValuePair<string, double>>();
|
public static List<KeyValuePair<string, double>> Chapters { get; set; } = new List<KeyValuePair<string, double>>();
|
||||||
|
|
||||||
public static string InputConfPath { get; } = ConfFolder + "\\input.conf";
|
public static string InputConfPath { get; } = ConfFolder + "\\input.conf";
|
||||||
public static string ConfPath { get; } = ConfFolder + "\\mpv.conf";
|
public static string ConfPath { get; } = ConfFolder + "\\mpv.conf";
|
||||||
|
|
||||||
public static bool Fullscreen { get; set; }
|
|
||||||
public static float Autofit { get; set; } = 0.50f;
|
|
||||||
public static int Screen { get; set; } = -1;
|
|
||||||
public static string Sid { get; set; } = "";
|
public static string Sid { get; set; } = "";
|
||||||
public static string Aid { get; set; } = "";
|
public static string Aid { get; set; } = "";
|
||||||
public static string Vid { get; set; } = "";
|
public static string Vid { get; set; } = "";
|
||||||
|
|
||||||
|
public static bool Fullscreen { get; set; }
|
||||||
|
public static bool Border { get; set; } = true;
|
||||||
|
|
||||||
|
public static int Screen { get; set; } = -1;
|
||||||
public static int Edition { get; set; }
|
public static int Edition { get; set; }
|
||||||
|
|
||||||
|
public static float Autofit { get; set; } = 0.50f;
|
||||||
|
|
||||||
|
public static void ProcessProperty(string name, string value)
|
||||||
|
{
|
||||||
|
switch (name)
|
||||||
|
{
|
||||||
|
case "autofit":
|
||||||
|
if (value.Length == 3 && value.EndsWith("%"))
|
||||||
|
if (int.TryParse(value.Substring(0, 2), out int result))
|
||||||
|
Autofit = result / 100f;
|
||||||
|
break;
|
||||||
|
case "fs":
|
||||||
|
case "fullscreen": Fullscreen = value == "yes"; break;
|
||||||
|
case "border": Border = value == "yes"; break;
|
||||||
|
case "screen": Screen = Convert.ToInt32(value); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static string _ConfFolder;
|
static string _ConfFolder;
|
||||||
|
|
||||||
public static string ConfFolder {
|
public static string ConfFolder {
|
||||||
@@ -146,7 +165,6 @@ namespace mpvnet
|
|||||||
string dummy = ConfFolder;
|
string dummy = ConfFolder;
|
||||||
LoadLibrary("mpv-1.dll");
|
LoadLibrary("mpv-1.dll");
|
||||||
Handle = mpv_create();
|
Handle = mpv_create();
|
||||||
set_property_string("input-default-bindings", "yes");
|
|
||||||
set_property_string("osc", "yes");
|
set_property_string("osc", "yes");
|
||||||
set_property_string("config", "yes");
|
set_property_string("config", "yes");
|
||||||
set_property_string("wid", MainForm.Hwnd.ToString());
|
set_property_string("wid", MainForm.Hwnd.ToString());
|
||||||
@@ -167,7 +185,7 @@ namespace mpvnet
|
|||||||
|
|
||||||
foreach (var scriptPath in startupScripts)
|
foreach (var scriptPath in startupScripts)
|
||||||
if (jsLua.Contains(Path.GetExtension(scriptPath).ToLower()))
|
if (jsLua.Contains(Path.GetExtension(scriptPath).ToLower()))
|
||||||
mp.commandv("load-script", $"{scriptPath}");
|
commandv("load-script", $"{scriptPath}");
|
||||||
|
|
||||||
foreach (var scriptPath in startupScripts)
|
foreach (var scriptPath in startupScripts)
|
||||||
if (Path.GetExtension(scriptPath) == ".py")
|
if (Path.GetExtension(scriptPath) == ".py")
|
||||||
@@ -177,8 +195,8 @@ namespace mpvnet
|
|||||||
if (Path.GetExtension(scriptPath) == ".ps1")
|
if (Path.GetExtension(scriptPath) == ".ps1")
|
||||||
PowerShellScript.Init(scriptPath);
|
PowerShellScript.Init(scriptPath);
|
||||||
|
|
||||||
if (Directory.Exists(mp.ConfFolder + "Scripts"))
|
if (Directory.Exists(ConfFolder + "Scripts"))
|
||||||
foreach (var scriptPath in Directory.GetFiles(mp.ConfFolder + "Scripts"))
|
foreach (var scriptPath in Directory.GetFiles(ConfFolder + "Scripts"))
|
||||||
if (Path.GetExtension(scriptPath) == ".py")
|
if (Path.GetExtension(scriptPath) == ".py")
|
||||||
PythonScripts.Add(new PythonScript(File.ReadAllText(scriptPath)));
|
PythonScripts.Add(new PythonScript(File.ReadAllText(scriptPath)));
|
||||||
else if (Path.GetExtension(scriptPath) == ".ps1")
|
else if (Path.GetExtension(scriptPath) == ".ps1")
|
||||||
@@ -193,10 +211,7 @@ namespace mpvnet
|
|||||||
mpv_event evt = (mpv_event)Marshal.PtrToStructure(ptr, typeof(mpv_event));
|
mpv_event evt = (mpv_event)Marshal.PtrToStructure(ptr, typeof(mpv_event));
|
||||||
|
|
||||||
if (WindowHandle == IntPtr.Zero)
|
if (WindowHandle == IntPtr.Zero)
|
||||||
{
|
|
||||||
WindowHandle = FindWindowEx(MainForm.Hwnd, IntPtr.Zero, "mpv", null);
|
WindowHandle = FindWindowEx(MainForm.Hwnd, IntPtr.Zero, "mpv", null);
|
||||||
//Native.EnableWindow(WindowHandle, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
//Debug.WriteLine(evt.event_id.ToString());
|
//Debug.WriteLine(evt.event_id.ToString());
|
||||||
|
|
||||||
@@ -232,7 +247,7 @@ namespace mpvnet
|
|||||||
case mpv_event_id.MPV_EVENT_FILE_LOADED:
|
case mpv_event_id.MPV_EVENT_FILE_LOADED:
|
||||||
HideLogo();
|
HideLogo();
|
||||||
FileLoaded?.Invoke();
|
FileLoaded?.Invoke();
|
||||||
WriteHistory(mp.get_property_string("path"));
|
WriteHistory(get_property_string("path"));
|
||||||
break;
|
break;
|
||||||
case mpv_event_id.MPV_EVENT_TRACKS_CHANGED:
|
case mpv_event_id.MPV_EVENT_TRACKS_CHANGED:
|
||||||
TracksChanged?.Invoke();
|
TracksChanged?.Invoke();
|
||||||
@@ -242,8 +257,7 @@ namespace mpvnet
|
|||||||
break;
|
break;
|
||||||
case mpv_event_id.MPV_EVENT_IDLE:
|
case mpv_event_id.MPV_EVENT_IDLE:
|
||||||
Idle?.Invoke();
|
Idle?.Invoke();
|
||||||
if (mp.get_property_int("playlist-count") == 0)
|
if (get_property_int("playlist-count") == 0) ShowLogo();
|
||||||
ShowLogo();
|
|
||||||
break;
|
break;
|
||||||
case mpv_event_id.MPV_EVENT_PAUSE:
|
case mpv_event_id.MPV_EVENT_PAUSE:
|
||||||
Pause?.Invoke();
|
Pause?.Invoke();
|
||||||
@@ -271,10 +285,6 @@ namespace mpvnet
|
|||||||
{
|
{
|
||||||
found = true;
|
found = true;
|
||||||
i.Action.Invoke(args.Skip(2).ToArray());
|
i.Action.Invoke(args.Skip(2).ToArray());
|
||||||
MainForm.Instance.BeginInvoke(new Action(() => {
|
|
||||||
Message m = new Message() { Msg = 0x0202 }; // WM_LBUTTONUP
|
|
||||||
Native.SendMessage(MainForm.Instance.Handle, m.Msg, m.WParam, m.LParam);
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!found)
|
if (!found)
|
||||||
@@ -350,7 +360,7 @@ namespace mpvnet
|
|||||||
{
|
{
|
||||||
if (IsLogoVisible)
|
if (IsLogoVisible)
|
||||||
{
|
{
|
||||||
mp.commandv("overlay-remove", "0");
|
commandv("overlay-remove", "0");
|
||||||
IsLogoVisible = false;
|
IsLogoVisible = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -369,17 +379,11 @@ namespace mpvnet
|
|||||||
MethodInfo mi;
|
MethodInfo mi;
|
||||||
|
|
||||||
if (eventInfo.EventHandlerType == typeof(Action))
|
if (eventInfo.EventHandlerType == typeof(Action))
|
||||||
{
|
|
||||||
mi = eventObject.GetType().GetMethod(nameof(PythonEventObject.Invoke));
|
mi = eventObject.GetType().GetMethod(nameof(PythonEventObject.Invoke));
|
||||||
}
|
|
||||||
else if (eventInfo.EventHandlerType == typeof(Action<EndFileEventMode>))
|
else if (eventInfo.EventHandlerType == typeof(Action<EndFileEventMode>))
|
||||||
{
|
|
||||||
mi = eventObject.GetType().GetMethod(nameof(PythonEventObject.InvokeEndFileEventMode));
|
mi = eventObject.GetType().GetMethod(nameof(PythonEventObject.InvokeEndFileEventMode));
|
||||||
}
|
|
||||||
else if (eventInfo.EventHandlerType == typeof(Action<string[]>))
|
else if (eventInfo.EventHandlerType == typeof(Action<string[]>))
|
||||||
{
|
|
||||||
mi = eventObject.GetType().GetMethod(nameof(PythonEventObject.InvokeStrings));
|
mi = eventObject.GetType().GetMethod(nameof(PythonEventObject.InvokeStrings));
|
||||||
}
|
|
||||||
else
|
else
|
||||||
throw new Exception();
|
throw new Exception();
|
||||||
|
|
||||||
@@ -401,28 +405,19 @@ namespace mpvnet
|
|||||||
|
|
||||||
public static void commandv(params string[] args)
|
public static void commandv(params string[] args)
|
||||||
{
|
{
|
||||||
if (Handle == IntPtr.Zero)
|
if (Handle == IntPtr.Zero) return;
|
||||||
return;
|
|
||||||
|
|
||||||
IntPtr mainPtr = AllocateUtf8IntPtrArrayWithSentinel(args, out IntPtr[] byteArrayPointers);
|
IntPtr mainPtr = AllocateUtf8IntPtrArrayWithSentinel(args, out IntPtr[] byteArrayPointers);
|
||||||
int err = mpv_command(Handle, mainPtr);
|
int err = mpv_command(Handle, mainPtr);
|
||||||
|
if (err < 0) throw new Exception($"{(mpv_error)err}");
|
||||||
if (err < 0)
|
|
||||||
throw new Exception($"{(mpv_error)err}");
|
|
||||||
|
|
||||||
foreach (var ptr in byteArrayPointers)
|
foreach (var ptr in byteArrayPointers)
|
||||||
Marshal.FreeHGlobal(ptr);
|
Marshal.FreeHGlobal(ptr);
|
||||||
|
|
||||||
Marshal.FreeHGlobal(mainPtr);
|
Marshal.FreeHGlobal(mainPtr);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void command_string(string command, bool throwException = false)
|
public static void command_string(string command, bool throwException = false)
|
||||||
{
|
{
|
||||||
if (Handle == IntPtr.Zero)
|
if (Handle == IntPtr.Zero) return;
|
||||||
return;
|
|
||||||
|
|
||||||
int err = mpv_command_string(Handle, command);
|
int err = mpv_command_string(Handle, command);
|
||||||
|
|
||||||
if (err < 0 && throwException)
|
if (err < 0 && throwException)
|
||||||
throw new Exception($"{(mpv_error)err}\r\n\r\n" + command);
|
throw new Exception($"{(mpv_error)err}\r\n\r\n" + command);
|
||||||
}
|
}
|
||||||
@@ -431,7 +426,6 @@ namespace mpvnet
|
|||||||
{
|
{
|
||||||
byte[] bytes = GetUtf8Bytes(value);
|
byte[] bytes = GetUtf8Bytes(value);
|
||||||
int err = mpv_set_property(Handle, GetUtf8Bytes(name), mpv_format.MPV_FORMAT_STRING, ref bytes);
|
int err = mpv_set_property(Handle, GetUtf8Bytes(name), mpv_format.MPV_FORMAT_STRING, ref bytes);
|
||||||
|
|
||||||
if (err < 0 && throwOnException)
|
if (err < 0 && throwOnException)
|
||||||
throw new Exception($"{name}: {(mpv_error)err}");
|
throw new Exception($"{name}: {(mpv_error)err}");
|
||||||
}
|
}
|
||||||
@@ -441,18 +435,14 @@ namespace mpvnet
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
int err = mpv_get_property(Handle, GetUtf8Bytes(name), mpv_format.MPV_FORMAT_STRING, out IntPtr lpBuffer);
|
int err = mpv_get_property(Handle, GetUtf8Bytes(name), mpv_format.MPV_FORMAT_STRING, out IntPtr lpBuffer);
|
||||||
|
if (err < 0 && throwOnException) throw new Exception($"{name}: {(mpv_error)err}");
|
||||||
if (err < 0 && throwOnException)
|
|
||||||
throw new Exception($"{name}: {(mpv_error)err}");
|
|
||||||
|
|
||||||
string ret = StringFromNativeUtf8(lpBuffer);
|
string ret = StringFromNativeUtf8(lpBuffer);
|
||||||
mpv_free(lpBuffer);
|
mpv_free(lpBuffer);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
if (throwOnException) throw ex;
|
if (throwOnException) throw e;
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -538,11 +528,11 @@ namespace mpvnet
|
|||||||
{
|
{
|
||||||
files.Add(i);
|
files.Add(i);
|
||||||
if (i.StartsWith("http"))
|
if (i.StartsWith("http"))
|
||||||
RegistryHelp.SetObject(App.RegPath, "LastURL", i);
|
RegHelp.SetObject(App.RegPath, "LastURL", i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mp.Load(files.ToArray());
|
Load(files.ToArray(), App.ProcessInstance != "queue", Control.ModifierKeys.HasFlag(Keys.Control));
|
||||||
|
|
||||||
foreach (string i in args)
|
foreach (string i in args)
|
||||||
{
|
{
|
||||||
@@ -552,35 +542,37 @@ namespace mpvnet
|
|||||||
{
|
{
|
||||||
string left = i.Substring(2, i.IndexOf("=") - 2);
|
string left = i.Substring(2, i.IndexOf("=") - 2);
|
||||||
string right = i.Substring(left.Length + 3);
|
string right = i.Substring(left.Length + 3);
|
||||||
mp.set_property_string(left, right);
|
set_property_string(left, right);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
mp.set_property_string(i.Substring(2), "yes");
|
set_property_string(i.Substring(2), "yes");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Load(params string[] files)
|
public static void Load(string[] files, bool loadFolder, bool append)
|
||||||
{
|
{
|
||||||
if (files is null || files.Length == 0) return;
|
if (files is null || files.Length == 0) return;
|
||||||
HideLogo();
|
HideLogo();
|
||||||
|
|
||||||
for (int i = 0; i < files.Length; i++)
|
for (int i = 0; i < files.Length; i++)
|
||||||
if (App.SubtitleTypes.Contains(Path.GetExtension(files[i]).TrimStart('.').ToLower()))
|
if (App.SubtitleTypes.Contains(Path.GetExtension(files[i]).TrimStart('.').ToLower()))
|
||||||
mp.commandv("sub-add", files[i]);
|
commandv("sub-add", files[i]);
|
||||||
else
|
else
|
||||||
if (i == 0)
|
if (i == 0 && !append)
|
||||||
mp.commandv("loadfile", files[i]);
|
commandv("loadfile", files[i]);
|
||||||
else
|
else
|
||||||
mp.commandv("loadfile", files[i], "append");
|
commandv("loadfile", files[i], "append");
|
||||||
|
|
||||||
Task.Run(() => LoadFolder()); // user reported race condition
|
if (string.IsNullOrEmpty(get_property_string("path")))
|
||||||
|
set_property_int("playlist-pos", 0);
|
||||||
|
if (loadFolder && !append) Task.Run(() => LoadFolder()); // user reported race condition
|
||||||
}
|
}
|
||||||
|
|
||||||
static void LoadFolder()
|
public static void LoadFolder()
|
||||||
{
|
{
|
||||||
Thread.Sleep(50); // user reported race condition
|
Thread.Sleep(50); // user reported race condition
|
||||||
string path = mp.get_property_string("path");
|
string path = get_property_string("path");
|
||||||
if (!File.Exists(path) || get_property_int("playlist-count") != 1) return;
|
if (!File.Exists(path) || get_property_int("playlist-count") != 1) return;
|
||||||
List<string> files = Directory.GetFiles(Path.GetDirectoryName(path)).ToList();
|
List<string> files = Directory.GetFiles(Path.GetDirectoryName(path)).ToList();
|
||||||
files = files.Where((file) =>
|
files = files.Where((file) =>
|
||||||
@@ -644,7 +636,7 @@ namespace mpvnet
|
|||||||
|
|
||||||
if (File.Exists(LastHistoryPath) && totalMinutes > 1)
|
if (File.Exists(LastHistoryPath) && totalMinutes > 1)
|
||||||
{
|
{
|
||||||
string historyFilepath = mp.ConfFolder + "history.txt";
|
string historyFilepath = ConfFolder + "history.txt";
|
||||||
|
|
||||||
File.AppendAllText(historyFilepath, DateTime.Now.ToString().Substring(0, 16) +
|
File.AppendAllText(historyFilepath, DateTime.Now.ToString().Substring(0, 16) +
|
||||||
" " + totalMinutes.ToString().PadLeft(3) + " " +
|
" " + totalMinutes.ToString().PadLeft(3) + " " +
|
||||||
@@ -671,39 +663,20 @@ namespace mpvnet
|
|||||||
Rectangle r = new Rectangle(cr.Width / 2 - iconWidth / 2, cr.Height / 2 - iconWidth / 2, iconWidth, iconWidth);
|
Rectangle r = new Rectangle(cr.Width / 2 - iconWidth / 2, cr.Height / 2 - iconWidth / 2, iconWidth, iconWidth);
|
||||||
g.DrawImage(Properties.Resources.mpvnet, r);
|
g.DrawImage(Properties.Resources.mpvnet, r);
|
||||||
BitmapData bd = b.LockBits(cr, ImageLockMode.ReadOnly, PixelFormat.Format32bppPArgb);
|
BitmapData bd = b.LockBits(cr, ImageLockMode.ReadOnly, PixelFormat.Format32bppPArgb);
|
||||||
mp.commandv("overlay-add", "0", "0", "0", "&" + bd.Scan0.ToInt64().ToString(), "0", "bgra", bd.Width.ToString(), bd.Height.ToString(), bd.Stride.ToString());
|
commandv("overlay-add", "0", "0", "0", "&" + bd.Scan0.ToInt64().ToString(), "0", "bgra", bd.Width.ToString(), bd.Height.ToString(), bd.Stride.ToString());
|
||||||
b.UnlockBits(bd);
|
b.UnlockBits(bd);
|
||||||
IsLogoVisible = true;
|
IsLogoVisible = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void ProcessProperty(string name, string value)
|
|
||||||
{
|
|
||||||
switch (name)
|
|
||||||
{
|
|
||||||
case "autofit":
|
|
||||||
if (value.Length == 3 && value.EndsWith("%"))
|
|
||||||
if (int.TryParse(value.Substring(0, 2), out int result))
|
|
||||||
mp.Autofit = result / 100f;
|
|
||||||
break;
|
|
||||||
case "fs":
|
|
||||||
case "fullscreen":
|
|
||||||
mp.Fullscreen = value == "yes";
|
|
||||||
break;
|
|
||||||
case "screen":
|
|
||||||
mp.Screen = Convert.ToInt32(value);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ReadMetaData()
|
static void ReadMetaData()
|
||||||
{
|
{
|
||||||
lock (MediaTracks)
|
lock (MediaTracks)
|
||||||
{
|
{
|
||||||
MediaTracks.Clear();
|
MediaTracks.Clear();
|
||||||
|
|
||||||
using (MediaInfo mi = new MediaInfo(mp.get_property_string("path")))
|
using (MediaInfo mi = new MediaInfo(get_property_string("path")))
|
||||||
{
|
{
|
||||||
int count = mi.GetCount(MediaInfoStreamKind.Video);
|
int count = mi.GetCount(MediaInfoStreamKind.Video);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user