readme update
This commit is contained in:
@@ -2,6 +2,8 @@
|
|||||||
###
|
###
|
||||||
|
|
||||||
- fix: update routine did only work when mpv.net was located in 'Program Files'
|
- fix: update routine did only work when mpv.net was located in 'Program Files'
|
||||||
|
- fix: errors were just ignored and only seen printed in the terminal in case mpv.net
|
||||||
|
was started from the terminal, now for every error a message box is shown
|
||||||
|
|
||||||
### 5.4.4.0
|
### 5.4.4.0
|
||||||
|
|
||||||
|
|||||||
77
README.md
77
README.md
@@ -50,7 +50,7 @@ Table of contents
|
|||||||
- [Links](#links)
|
- [Links](#links)
|
||||||
- [Changelog](#changelog)
|
- [Changelog](#changelog)
|
||||||
|
|
||||||
### Features
|
## Features
|
||||||
|
|
||||||
- Very high degree of mpv compatibility, almost all mpv features are available
|
- Very high degree of mpv compatibility, almost all mpv features are available
|
||||||
- Great usability due to everything in the application being searchable
|
- Great usability due to everything in the application being searchable
|
||||||
@@ -88,7 +88,7 @@ Table of contents
|
|||||||
- Update check and update routine ([Manual](Manual.md#help--check-for-updates))
|
- Update check and update routine ([Manual](Manual.md#help--check-for-updates))
|
||||||
- [Manual](#manual)
|
- [Manual](#manual)
|
||||||
|
|
||||||
### Screenshots
|
## Screenshots
|
||||||
|
|
||||||
#### Main Window Screenshot
|
#### Main Window Screenshot
|
||||||
|
|
||||||
@@ -131,7 +131,7 @@ Media search feature powered by [Everything](https://www.voidtools.com) to find
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
### Installation
|
## Installation
|
||||||
|
|
||||||
mpv.net requires minimum .NET Framework 4.8 and Windows 7. For optimal results a modern graphics card is recommended.
|
mpv.net requires minimum .NET Framework 4.8 and Windows 7. For optimal results a modern graphics card is recommended.
|
||||||
|
|
||||||
@@ -150,11 +150,11 @@ Alternatively, Chocolatey can also be used:
|
|||||||
|
|
||||||
`choco install mpvnet.install`
|
`choco install mpvnet.install`
|
||||||
|
|
||||||
### Manual
|
## Manual
|
||||||
|
|
||||||
[Manual](Manual.md)
|
[Manual](Manual.md)
|
||||||
|
|
||||||
### Context Menu
|
## Context Menu
|
||||||
|
|
||||||
The context menu can be customized via input.conf file located in the config directory:
|
The context menu can be customized via input.conf file located in the config directory:
|
||||||
|
|
||||||
@@ -168,7 +168,7 @@ if it's missing mpv.net generates it with the following defaults:
|
|||||||
|
|
||||||
input.conf defines mpv's key and mouse bindings and mpv.net uses comments to define the context menu.
|
input.conf defines mpv's key and mouse bindings and mpv.net uses comments to define the context menu.
|
||||||
|
|
||||||
### Settings
|
## Settings
|
||||||
|
|
||||||
When mpv.net finds no config folder on startup it will ask for a location.
|
When mpv.net finds no config folder on startup it will ask for a location.
|
||||||
|
|
||||||
@@ -196,47 +196,27 @@ mpv.net supports almost all mpv settings and features,
|
|||||||
|
|
||||||
The config folder can be opened from the context menu.
|
The config folder can be opened from the context menu.
|
||||||
|
|
||||||
### Scripting
|
## Scripting
|
||||||
|
|
||||||
[Scripting wiki page](https://github.com/stax76/mpv.net/wiki/Scripting)
|
[Scripting wiki page](https://github.com/stax76/mpv.net/wiki/Scripting)
|
||||||
|
|
||||||
### Extensions
|
## Extensions
|
||||||
|
|
||||||
[Extensions wiki page](https://github.com/stax76/mpv.net/wiki/Extensions)
|
[Extensions wiki page](https://github.com/stax76/mpv.net/wiki/Extensions)
|
||||||
|
|
||||||
### Architecture
|
## Architecture
|
||||||
|
|
||||||
Coding mpv.net was great fun because libmpv is such a awesome
|
mpv.net is written in C# and runs on the .NET Framework
|
||||||
library with a very clever design, I'm having a great experience
|
|
||||||
with libmpv.
|
|
||||||
|
|
||||||
The player does not contain any feature that was more work than 1-2 days or
|
|
||||||
was difficult to build, the hard parts are totally covered by libmpv.
|
|
||||||
|
|
||||||
mpv.net is written in C# 7 and runs on .NET 4.8, I've not yet decided
|
|
||||||
if I will port it to C# 8 and .NET 5 once available.
|
|
||||||
|
|
||||||
The Extension implementation is based on the [Managed Extensibility Framework](https://docs.microsoft.com/en-us/dotnet/framework/mef/).
|
The Extension implementation is based on the [Managed Extensibility Framework](https://docs.microsoft.com/en-us/dotnet/framework/mef/).
|
||||||
|
|
||||||
There are no specific extension or scripting interfaces but instead everyting
|
|
||||||
is accessible for .NET compatible languages (C#, VB.NET, F#, Python, PowerShell),
|
|
||||||
this decision was made to keep the code simple and lightweight.
|
|
||||||
|
|
||||||
Python scripting is implemented with IronPython which uses Python 2.7.
|
Python scripting is implemented with IronPython which uses Python 2.7.
|
||||||
|
|
||||||
The main window is WinForms based and uses less than 800 lines of code,
|
The main window is WinForms based, WinForms allows better libmpv integration compared to WPF, all other windows are WPF based.
|
||||||
all other windows are WPF based and use even less code.
|
|
||||||
|
|
||||||
The config editor adds it's controls dynamically and uses [TOML](https://en.wikipedia.org/wiki/TOML) to define it's
|
The config editor adds it's controls dynamically and uses [TOML](https://en.wikipedia.org/wiki/TOML) to define it's
|
||||||
content, there are only two simple types, StringSetting and OptionSetting.
|
content, there are only two simple types, StringSetting and OptionSetting.
|
||||||
|
|
||||||
mpv.net was started 2017 and consists of about 7000 lines of code and markup.
|
|
||||||
|
|
||||||
IDE, Editor: Visual Studio, Visual Studio Code.
|
|
||||||
|
|
||||||
Due to mpv.net being my first WPF app and mpv.net never meant to be a large
|
|
||||||
application best practices and design pattern are not always applied.
|
|
||||||
|
|
||||||
Third party components:
|
Third party components:
|
||||||
|
|
||||||
- [libmpv, the heard and soul of mpv.net](https://mpv.io/)
|
- [libmpv, the heard and soul of mpv.net](https://mpv.io/)
|
||||||
@@ -246,7 +226,7 @@ Third party components:
|
|||||||
- [CS-Script, scripting with C#](http://www.csscript.net/)
|
- [CS-Script, scripting with C#](http://www.csscript.net/)
|
||||||
- [Everything, a blazing fast file search service](https://www.voidtools.com)
|
- [Everything, a blazing fast file search service](https://www.voidtools.com)
|
||||||
|
|
||||||
### Support
|
## Support
|
||||||
|
|
||||||
[Support thread in Doom9 forum](https://forum.doom9.org/showthread.php?t=174841)
|
[Support thread in Doom9 forum](https://forum.doom9.org/showthread.php?t=174841)
|
||||||
|
|
||||||
@@ -262,21 +242,26 @@ If you want to support the development of mpv.net or express your appreciation y
|
|||||||
|
|
||||||
<https://www.paypal.me/stax76>
|
<https://www.paypal.me/stax76>
|
||||||
|
|
||||||
### Links
|
## Links
|
||||||
|
|
||||||
- mpv.net wiki: <https://github.com/stax76/mpv.net/wiki>
|
#### mpv.net
|
||||||
- mpv.net default key bindings: <https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/inputConf.txt>
|
|
||||||
- mpv.net download: <https://github.com/stax76/mpv.net/releases>
|
|
||||||
- mpv.net bugs and requests: <https://github.com/stax76/mpv.net/issues>
|
|
||||||
- mpv website: <https://mpv.io/>
|
|
||||||
- mpv manual: <https://mpv.io/manual/master/>
|
|
||||||
- mpv wiki: <https://github.com/mpv-player/mpv/wiki>
|
|
||||||
- mpv apps: <https://github.com/mpv-player/mpv/wiki/Applications-using-mpv>
|
|
||||||
- mpv user scripts: <https://github.com/mpv-player/mpv/wiki/User-Scripts>
|
|
||||||
- mpv default key bindings: <https://github.com/mpv-player/mpv/blob/master/etc/input.conf>
|
|
||||||
- mpv download: <https://mpv.io/installation/>
|
|
||||||
- mpv bugs and requests: <https://mpv.io/bug-reports/>
|
|
||||||
|
|
||||||
### Changelog
|
- wiki: <https://github.com/stax76/mpv.net/wiki>
|
||||||
|
- default key bindings: <https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/inputConf.txt>
|
||||||
|
- download: <https://github.com/stax76/mpv.net/releases>
|
||||||
|
- bugs and requests: <https://github.com/stax76/mpv.net/issues>
|
||||||
|
|
||||||
|
#### mpv
|
||||||
|
|
||||||
|
- website: <https://mpv.io/>
|
||||||
|
- manual: <https://mpv.io/manual/master/>
|
||||||
|
- wiki: <https://github.com/mpv-player/mpv/wiki>
|
||||||
|
- apps: <https://github.com/mpv-player/mpv/wiki/Applications-using-mpv>
|
||||||
|
- user scripts: <https://github.com/mpv-player/mpv/wiki/User-Scripts>
|
||||||
|
- default key bindings: <https://github.com/mpv-player/mpv/blob/master/etc/input.conf>
|
||||||
|
- download: <https://mpv.io/installation/>
|
||||||
|
- bugs and requests: <https://mpv.io/bug-reports/>
|
||||||
|
|
||||||
|
## Changelog
|
||||||
|
|
||||||
[Changelog](Changelog.md)
|
[Changelog](Changelog.md)
|
||||||
|
|||||||
@@ -83,8 +83,11 @@ namespace mpvnet
|
|||||||
|
|
||||||
mp.Shutdown += Shutdown;
|
mp.Shutdown += Shutdown;
|
||||||
mp.Initialized += Initialized;
|
mp.Initialized += Initialized;
|
||||||
|
mp.LogMessage += LogMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void LogMessage(string msg) => Msg.ShowError(msg);
|
||||||
|
|
||||||
private static void Initialized()
|
private static void Initialized()
|
||||||
{
|
{
|
||||||
if (RememberVolume)
|
if (RememberVolume)
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ namespace mpvnet
|
|||||||
|
|
||||||
MainForm.Instance.BeginInvoke(new Action(() => {
|
MainForm.Instance.BeginInvoke(new Action(() => {
|
||||||
Message m = new Message() { Msg = 0x0202 }; // WM_LBUTTONUP
|
Message m = new Message() { Msg = 0x0202 }; // WM_LBUTTONUP
|
||||||
Native.SendMessage(MainForm.Instance.Handle, m.Msg, m.WParam, m.LParam);
|
WinAPI.SendMessage(MainForm.Instance.Handle, m.Msg, m.WParam, m.LParam);
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -229,11 +229,15 @@ namespace mpvnet
|
|||||||
using (var d = new OpenFileDialog())
|
using (var d = new OpenFileDialog())
|
||||||
{
|
{
|
||||||
string path = mp.get_property_string("path");
|
string path = mp.get_property_string("path");
|
||||||
if (File.Exists(path)) d.InitialDirectory = Path.GetDirectoryName(path);
|
|
||||||
|
if (File.Exists(path))
|
||||||
|
d.InitialDirectory = Path.GetDirectoryName(path);
|
||||||
|
|
||||||
d.Multiselect = true;
|
d.Multiselect = true;
|
||||||
|
|
||||||
if (d.ShowDialog() == DialogResult.OK)
|
if (d.ShowDialog() == DialogResult.OK)
|
||||||
foreach (string i in d.FileNames)
|
foreach (string filename in d.FileNames)
|
||||||
mp.commandv("sub-add", i);
|
mp.commandv("sub-add", filename);
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ namespace mpvnet
|
|||||||
Application.SetCompatibleTextRenderingDefault(false);
|
Application.SetCompatibleTextRenderingDefault(false);
|
||||||
|
|
||||||
if (App.IsStartedFromTerminal)
|
if (App.IsStartedFromTerminal)
|
||||||
Native.AttachConsole(-1 /*ATTACH_PARENT_PROCESS*/);
|
WinAPI.AttachConsole(-1 /*ATTACH_PARENT_PROCESS*/);
|
||||||
|
|
||||||
if (mp.ConfigFolder == "")
|
if (mp.ConfigFolder == "")
|
||||||
return;
|
return;
|
||||||
@@ -61,15 +61,15 @@ namespace mpvnet
|
|||||||
{
|
{
|
||||||
if (proc.MainWindowHandle != IntPtr.Zero)
|
if (proc.MainWindowHandle != IntPtr.Zero)
|
||||||
{
|
{
|
||||||
Native.AllowSetForegroundWindow(proc.Id);
|
WinAPI.AllowSetForegroundWindow(proc.Id);
|
||||||
var data = new Native.COPYDATASTRUCT();
|
var data = new WinAPI.COPYDATASTRUCT();
|
||||||
data.lpData = string.Join("\n", files.ToArray());
|
data.lpData = string.Join("\n", files.ToArray());
|
||||||
data.cbData = data.lpData.Length * 2 + 1;
|
data.cbData = data.lpData.Length * 2 + 1;
|
||||||
Native.SendMessage(proc.MainWindowHandle, 0x004A /*WM_COPYDATA*/, IntPtr.Zero, ref data);
|
WinAPI.SendMessage(proc.MainWindowHandle, 0x004A /*WM_COPYDATA*/, IntPtr.Zero, ref data);
|
||||||
mutex.Dispose();
|
mutex.Dispose();
|
||||||
|
|
||||||
if (App.IsStartedFromTerminal)
|
if (App.IsStartedFromTerminal)
|
||||||
Native.FreeConsole();
|
WinAPI.FreeConsole();
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -85,7 +85,7 @@ namespace mpvnet
|
|||||||
Application.Run(new MainForm());
|
Application.Run(new MainForm());
|
||||||
|
|
||||||
if (App.IsStartedFromTerminal)
|
if (App.IsStartedFromTerminal)
|
||||||
Native.FreeConsole();
|
WinAPI.FreeConsole();
|
||||||
|
|
||||||
mutex.Dispose();
|
mutex.Dispose();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,15 +33,16 @@ namespace mpvnet
|
|||||||
Version onlineVersion = Version.Parse(match.Groups[1].Value);
|
Version onlineVersion = Version.Parse(match.Groups[1].Value);
|
||||||
Version currentVersion = Assembly.GetEntryAssembly().GetName().Version;
|
Version currentVersion = Assembly.GetEntryAssembly().GetName().Version;
|
||||||
|
|
||||||
if (onlineVersion == currentVersion)
|
if (onlineVersion <= currentVersion)
|
||||||
{
|
{
|
||||||
if (showUpToDateMessage)
|
if (showUpToDateMessage)
|
||||||
Msg.Show($"{Application.ProductName} is up to date.");
|
Msg.Show($"{Application.ProductName} is up to date.");
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (RegistryHelp.GetString(RegistryHelp.ApplicationKey, "UpdateCheckVersion")
|
if ((RegistryHelp.GetString(RegistryHelp.ApplicationKey, "UpdateCheckVersion")
|
||||||
!= onlineVersion.ToString() && Msg.ShowQuestion(
|
!= onlineVersion.ToString() || showUpToDateMessage) && Msg.ShowQuestion(
|
||||||
$"New version {onlineVersion} is available, update now?") == MsgResult.OK)
|
$"New version {onlineVersion} is available, update now?") == MsgResult.OK)
|
||||||
{
|
{
|
||||||
string arch = IntPtr.Size == 8 ? "64" : "86";
|
string arch = IntPtr.Size == 8 ? "64" : "86";
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ public class MediaInfo : IDisposable
|
|||||||
{
|
{
|
||||||
if (!Loaded)
|
if (!Loaded)
|
||||||
{
|
{
|
||||||
if (Native.LoadLibrary("MediaInfo.dll") == IntPtr.Zero)
|
if (WinAPI.LoadLibrary("MediaInfo.dll") == IntPtr.Zero)
|
||||||
throw new Exception("Failed to load MediaInfo.dll.");
|
throw new Exception("Failed to load MediaInfo.dll.");
|
||||||
|
|
||||||
Loaded = true;
|
Loaded = true;
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
using System;
|
|
||||||
|
using System;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
public class Native
|
public class WinAPI
|
||||||
{
|
{
|
||||||
[DllImport("kernel32.dll")]
|
[DllImport("kernel32.dll")]
|
||||||
public static extern bool AttachConsole(int dwProcessId);
|
public static extern bool AttachConsole(int dwProcessId);
|
||||||
|
|||||||
@@ -20,9 +20,9 @@ namespace mpvnet
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void SubtractWindowBorders(IntPtr hwnd, ref Native.RECT rc)
|
public static void SubtractWindowBorders(IntPtr hwnd, ref WinAPI.RECT rc)
|
||||||
{
|
{
|
||||||
var b = new Native.RECT(0, 0, 0, 0);
|
var b = new WinAPI.RECT(0, 0, 0, 0);
|
||||||
AddWindowBorders(hwnd, ref b);
|
AddWindowBorders(hwnd, ref b);
|
||||||
rc.Left -= b.Left;
|
rc.Left -= b.Left;
|
||||||
rc.Top -= b.Top;
|
rc.Top -= b.Top;
|
||||||
@@ -30,9 +30,9 @@ namespace mpvnet
|
|||||||
rc.Bottom -= b.Bottom;
|
rc.Bottom -= b.Bottom;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void AddWindowBorders(IntPtr hwnd, ref Native.RECT rc)
|
public static void AddWindowBorders(IntPtr hwnd, ref WinAPI.RECT rc)
|
||||||
{
|
{
|
||||||
Native.AdjustWindowRect(ref rc, (uint)Native.GetWindowLong(hwnd, -16 /* GWL_STYLE */), false);
|
WinAPI.AdjustWindowRect(ref rc, (uint)WinAPI.GetWindowLong(hwnd, -16 /* GWL_STYLE */), false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
|
||||||
|
using System;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
public class Taskbar
|
public class Taskbar
|
||||||
@@ -9,9 +10,8 @@ public class Taskbar
|
|||||||
|
|
||||||
public Taskbar(IntPtr handle) => Handle = handle;
|
public Taskbar(IntPtr handle) => Handle = handle;
|
||||||
|
|
||||||
[ComImportAttribute]
|
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
||||||
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
|
[Guid("EA1AFB91-9E28-4B86-90E9-9E9F8A5EEFAF")]
|
||||||
[GuidAttribute("ea1afb91-9e28-4b86-90e9-9e9f8a5eefaf")]
|
|
||||||
private interface ITaskbarList3
|
private interface ITaskbarList3
|
||||||
{
|
{
|
||||||
// ITaskbarList
|
// ITaskbarList
|
||||||
@@ -27,9 +27,9 @@ public class Taskbar
|
|||||||
[PreserveSig] void SetProgressState(IntPtr hwnd, TaskbarStates state);
|
[PreserveSig] void SetProgressState(IntPtr hwnd, TaskbarStates state);
|
||||||
}
|
}
|
||||||
|
|
||||||
[ComImportAttribute]
|
[ComImport]
|
||||||
[ClassInterfaceAttribute(ClassInterfaceType.None)]
|
[ClassInterface(ClassInterfaceType.None)]
|
||||||
[GuidAttribute("56FDF344-FD6D-11d0-958A-006097C9A090")]
|
[Guid("56FDF344-FD6D-11d0-958A-006097C9A090")]
|
||||||
private class TaskBarCommunication { }
|
private class TaskBarCommunication { }
|
||||||
|
|
||||||
public void SetState(TaskbarStates taskbarState)
|
public void SetState(TaskbarStates taskbarState)
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
|
||||||
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Management.Automation.Runspaces;
|
using System.Management.Automation.Runspaces;
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ namespace mpvnet
|
|||||||
Application.ThreadException += (sender, e) => Msg.ShowException(e.Exception);
|
Application.ThreadException += (sender, e) => Msg.ShowException(e.Exception);
|
||||||
Msg.SupportURL = "https://github.com/stax76/mpv.net#support";
|
Msg.SupportURL = "https://github.com/stax76/mpv.net#support";
|
||||||
Text = "mpv.net " + Application.ProductVersion;
|
Text = "mpv.net " + Application.ProductVersion;
|
||||||
TaskbarButtonCreatedMessage = Native.RegisterWindowMessage("TaskbarButtonCreated");
|
TaskbarButtonCreatedMessage = WinAPI.RegisterWindowMessage("TaskbarButtonCreated");
|
||||||
|
|
||||||
ContextMenu = new ContextMenuStripEx(components);
|
ContextMenu = new ContextMenuStripEx(components);
|
||||||
ContextMenu.Opened += ContextMenu_Opened;
|
ContextMenu.Opened += ContextMenu_Opened;
|
||||||
@@ -318,7 +318,7 @@ namespace mpvnet
|
|||||||
}
|
}
|
||||||
|
|
||||||
Point middlePos = new Point(Left + Width / 2, Top + Height / 2);
|
Point middlePos = new Point(Left + Width / 2, Top + Height / 2);
|
||||||
var rect = new Native.RECT(new Rectangle(screen.Bounds.X, screen.Bounds.Y, width, height));
|
var rect = new WinAPI.RECT(new Rectangle(screen.Bounds.X, screen.Bounds.Y, width, height));
|
||||||
NativeHelp.AddWindowBorders(Handle, ref rect);
|
NativeHelp.AddWindowBorders(Handle, ref rect);
|
||||||
int left = middlePos.X - rect.Width / 2;
|
int left = middlePos.X - rect.Width / 2;
|
||||||
int top = middlePos.Y - rect.Height / 2;
|
int top = middlePos.Y - rect.Height / 2;
|
||||||
@@ -341,7 +341,7 @@ namespace mpvnet
|
|||||||
if (top + rect.Height > maxBottom)
|
if (top + rect.Height > maxBottom)
|
||||||
top = maxBottom - rect.Height;
|
top = maxBottom - rect.Height;
|
||||||
|
|
||||||
Native.SetWindowPos(Handle, IntPtr.Zero /* HWND_TOP */, left, top, rect.Width, rect.Height, 4 /* SWP_NOZORDER */);
|
WinAPI.SetWindowPos(Handle, IntPtr.Zero /* HWND_TOP */, left, top, rect.Width, rect.Height, 4 /* SWP_NOZORDER */);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void CycleFullscreen(bool enabled)
|
public void CycleFullscreen(bool enabled)
|
||||||
@@ -468,7 +468,7 @@ namespace mpvnet
|
|||||||
case 0x0105: // WM_SYSKEYUP
|
case 0x0105: // WM_SYSKEYUP
|
||||||
case 0x319: // WM_APPCOMMAND
|
case 0x319: // WM_APPCOMMAND
|
||||||
if (mp.WindowHandle != IntPtr.Zero)
|
if (mp.WindowHandle != IntPtr.Zero)
|
||||||
Native.SendMessage(mp.WindowHandle, m.Msg, m.WParam, m.LParam);
|
WinAPI.SendMessage(mp.WindowHandle, m.Msg, m.WParam, m.LParam);
|
||||||
break;
|
break;
|
||||||
case 0x0200: // WM_MOUSEMOVE
|
case 0x0200: // WM_MOUSEMOVE
|
||||||
{
|
{
|
||||||
@@ -497,13 +497,13 @@ namespace mpvnet
|
|||||||
if (!WasShown)
|
if (!WasShown)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
Native.RECT rect = Marshal.PtrToStructure<Native.RECT>(m.LParam);
|
WinAPI.RECT rect = Marshal.PtrToStructure<WinAPI.RECT>(m.LParam);
|
||||||
Native.SetWindowPos(Handle, IntPtr.Zero, rect.Left, rect.Top, rect.Width, rect.Height, 0);
|
WinAPI.SetWindowPos(Handle, IntPtr.Zero, rect.Left, rect.Top, rect.Width, rect.Height, 0);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x0214: // WM_SIZING
|
case 0x0214: // WM_SIZING
|
||||||
{
|
{
|
||||||
var rc = Marshal.PtrToStructure<Native.RECT>(m.LParam);
|
var rc = Marshal.PtrToStructure<WinAPI.RECT>(m.LParam);
|
||||||
var r = rc;
|
var r = rc;
|
||||||
NativeHelp.SubtractWindowBorders(Handle, ref r);
|
NativeHelp.SubtractWindowBorders(Handle, ref r);
|
||||||
int c_w = r.Right - r.Left, c_h = r.Bottom - r.Top;
|
int c_w = r.Right - r.Left, c_h = r.Bottom - r.Top;
|
||||||
@@ -522,13 +522,13 @@ namespace mpvnet
|
|||||||
if (corner >= 0)
|
if (corner >= 0)
|
||||||
corners[corner] -= d_corners[corner];
|
corners[corner] -= d_corners[corner];
|
||||||
|
|
||||||
Marshal.StructureToPtr<Native.RECT>(new Native.RECT(corners[0], corners[1], corners[2], corners[3]), m.LParam, false);
|
Marshal.StructureToPtr<WinAPI.RECT>(new WinAPI.RECT(corners[0], corners[1], corners[2], corners[3]), m.LParam, false);
|
||||||
m.Result = new IntPtr(1);
|
m.Result = new IntPtr(1);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
case 0x004A: // WM_COPYDATA
|
case 0x004A: // WM_COPYDATA
|
||||||
{
|
{
|
||||||
var copyData = (Native.COPYDATASTRUCT)m.GetLParam(typeof(Native.COPYDATASTRUCT));
|
var copyData = (WinAPI.COPYDATASTRUCT)m.GetLParam(typeof(WinAPI.COPYDATASTRUCT));
|
||||||
string[] files = copyData.lpData.Split('\n');
|
string[] files = copyData.lpData.Split('\n');
|
||||||
string mode = files[0];
|
string mode = files[0];
|
||||||
files = files.Skip(1).ToArray();
|
files = files.Skip(1).ToArray();
|
||||||
@@ -574,6 +574,7 @@ namespace mpvnet
|
|||||||
|
|
||||||
private void ProgressTimer_Tick(object sender, EventArgs e) => UpdateProgressBar();
|
private void ProgressTimer_Tick(object sender, EventArgs e) => UpdateProgressBar();
|
||||||
|
|
||||||
|
// TODO: why is this in mainform?
|
||||||
void UpdateProgressBar()
|
void UpdateProgressBar()
|
||||||
{
|
{
|
||||||
if (mp.TaskbarProgress && Taskbar != null)
|
if (mp.TaskbarProgress && Taskbar != null)
|
||||||
@@ -696,8 +697,8 @@ namespace mpvnet
|
|||||||
e.Y < ClientSize.Height * 0.9)
|
e.Y < ClientSize.Height * 0.9)
|
||||||
{
|
{
|
||||||
var HTCAPTION = new IntPtr(2);
|
var HTCAPTION = new IntPtr(2);
|
||||||
Native.ReleaseCapture();
|
WinAPI.ReleaseCapture();
|
||||||
Native.PostMessage(Handle, 0xA1 /* WM_NCLBUTTONDOWN */, HTCAPTION, IntPtr.Zero);
|
WinAPI.PostMessage(Handle, 0xA1 /* WM_NCLBUTTONDOWN */, HTCAPTION, IntPtr.Zero);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Width - e.Location.X < 10 && e.Location.Y < 10)
|
if (Width - e.Location.X < 10 && e.Location.Y < 10)
|
||||||
|
|||||||
@@ -1,188 +1,231 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
namespace mpvnet
|
public class libmpv
|
||||||
{
|
{
|
||||||
public class libmpv
|
[DllImport("mpv-1.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
public static extern IntPtr mpv_create();
|
||||||
|
|
||||||
|
[DllImport("mpv-1.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
public static extern mpv_error mpv_initialize(IntPtr mpvHandle);
|
||||||
|
|
||||||
|
[DllImport("mpv-1.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
public static extern mpv_error mpv_command(IntPtr mpvHandle, IntPtr strings);
|
||||||
|
|
||||||
|
[DllImport("mpv-1.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
public static extern mpv_error mpv_command_string(IntPtr mpvHandle, [MarshalAs(UnmanagedType.LPUTF8Str)] string command);
|
||||||
|
|
||||||
|
[DllImport("mpv-1.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
public static extern IntPtr mpv_error_string(mpv_error error);
|
||||||
|
|
||||||
|
[DllImport("mpv-1.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
public static extern int mpv_terminate_destroy(IntPtr mpvHandle);
|
||||||
|
|
||||||
|
[DllImport("mpv-1.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
public static extern mpv_error mpv_request_log_messages(IntPtr mpvHandle, [MarshalAs(UnmanagedType.LPUTF8Str)] string min_level);
|
||||||
|
|
||||||
|
[DllImport("mpv-1.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
public static extern int mpv_set_option(IntPtr mpvHandle, byte[] name, mpv_format format, ref long data);
|
||||||
|
|
||||||
|
[DllImport("mpv-1.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
public static extern int mpv_set_option_string(IntPtr mpvHandle, byte[] name, byte[] value);
|
||||||
|
|
||||||
|
[DllImport("mpv-1.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
public static extern mpv_error mpv_get_property(IntPtr mpvHandle, byte[] name, mpv_format format, out IntPtr data);
|
||||||
|
|
||||||
|
[DllImport("mpv-1.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
public static extern mpv_error mpv_get_property(IntPtr mpvHandle, byte[] name, mpv_format format, out double data);
|
||||||
|
|
||||||
|
[DllImport("mpv-1.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
public static extern mpv_error mpv_set_property(IntPtr mpvHandle, byte[] name, mpv_format format, ref byte[] data);
|
||||||
|
|
||||||
|
[DllImport("mpv-1.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
public static extern mpv_error mpv_set_property(IntPtr mpvHandle, byte[] name, mpv_format format, ref Int64 data);
|
||||||
|
|
||||||
|
[DllImport("mpv-1.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
public static extern mpv_error mpv_observe_property(IntPtr mpvHandle, UInt64 reply_userdata, [MarshalAs(UnmanagedType.LPUTF8Str)] string name, mpv_format format);
|
||||||
|
|
||||||
|
[DllImport("mpv-1.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
public static extern int mpv_unobserve_property(IntPtr mpvHandle, UInt64 registered_reply_userdata);
|
||||||
|
|
||||||
|
[DllImport("mpv-1.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
public static extern void mpv_free(IntPtr data);
|
||||||
|
|
||||||
|
[DllImport("mpv-1.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
public static extern IntPtr mpv_wait_event(IntPtr mpvHandle, double timeout);
|
||||||
|
|
||||||
|
public enum mpv_error
|
||||||
{
|
{
|
||||||
[DllImport("mpv-1.dll", CallingConvention = CallingConvention.Cdecl)]
|
MPV_ERROR_SUCCESS = 0,
|
||||||
public static extern IntPtr mpv_create();
|
MPV_ERROR_EVENT_QUEUE_FULL = -1,
|
||||||
|
MPV_ERROR_NOMEM = -2,
|
||||||
[DllImport("mpv-1.dll", CallingConvention = CallingConvention.Cdecl)]
|
MPV_ERROR_UNINITIALIZED = -3,
|
||||||
public static extern int mpv_initialize(IntPtr mpvHandle);
|
MPV_ERROR_INVALID_PARAMETER = -4,
|
||||||
|
MPV_ERROR_OPTION_NOT_FOUND = -5,
|
||||||
[DllImport("mpv-1.dll", CallingConvention = CallingConvention.Cdecl)]
|
MPV_ERROR_OPTION_FORMAT = -6,
|
||||||
public static extern int mpv_command(IntPtr mpvHandle, IntPtr strings);
|
MPV_ERROR_OPTION_ERROR = -7,
|
||||||
|
MPV_ERROR_PROPERTY_NOT_FOUND = -8,
|
||||||
[DllImport("mpv-1.dll", CallingConvention = CallingConvention.Cdecl)]
|
MPV_ERROR_PROPERTY_FORMAT = -9,
|
||||||
public static extern int mpv_command_string(IntPtr mpvHandle, [MarshalAs(UnmanagedType.LPUTF8Str)] string command);
|
MPV_ERROR_PROPERTY_UNAVAILABLE = -10,
|
||||||
|
MPV_ERROR_PROPERTY_ERROR = -11,
|
||||||
[DllImport("mpv-1.dll", CallingConvention = CallingConvention.Cdecl)]
|
MPV_ERROR_COMMAND = -12,
|
||||||
public static extern int mpv_terminate_destroy(IntPtr mpvHandle);
|
MPV_ERROR_LOADING_FAILED = -13,
|
||||||
|
MPV_ERROR_AO_INIT_FAILED = -14,
|
||||||
[DllImport("mpv-1.dll", CallingConvention = CallingConvention.Cdecl)]
|
MPV_ERROR_VO_INIT_FAILED = -15,
|
||||||
public static extern int mpv_set_option(IntPtr mpvHandle, byte[] name, mpv_format format, ref long data);
|
MPV_ERROR_NOTHING_TO_PLAY = -16,
|
||||||
|
MPV_ERROR_UNKNOWN_FORMAT = -17,
|
||||||
[DllImport("mpv-1.dll", CallingConvention = CallingConvention.Cdecl)]
|
MPV_ERROR_UNSUPPORTED = -18,
|
||||||
public static extern int mpv_set_option_string(IntPtr mpvHandle, byte[] name, byte[] value);
|
MPV_ERROR_NOT_IMPLEMENTED = -19,
|
||||||
|
MPV_ERROR_GENERIC = -20
|
||||||
[DllImport("mpv-1.dll", CallingConvention = CallingConvention.Cdecl)]
|
|
||||||
public static extern int mpv_get_property(IntPtr mpvHandle, byte[] name, mpv_format format, out IntPtr data);
|
|
||||||
|
|
||||||
[DllImport("mpv-1.dll", CallingConvention = CallingConvention.Cdecl)]
|
|
||||||
public static extern int mpv_get_property(IntPtr mpvHandle, byte[] name, mpv_format format, ref double data);
|
|
||||||
|
|
||||||
[DllImport("mpv-1.dll", CallingConvention = CallingConvention.Cdecl)]
|
|
||||||
public static extern int mpv_set_property(IntPtr mpvHandle, byte[] name, mpv_format format, ref byte[] data);
|
|
||||||
|
|
||||||
[DllImport("mpv-1.dll", CallingConvention = CallingConvention.Cdecl)]
|
|
||||||
public static extern int mpv_set_property(IntPtr mpvHandle, byte[] name, mpv_format format, ref Int64 data);
|
|
||||||
|
|
||||||
[DllImport("mpv-1.dll", CallingConvention = CallingConvention.Cdecl)]
|
|
||||||
public static extern int mpv_observe_property(
|
|
||||||
IntPtr mpvHandle,
|
|
||||||
UInt64 reply_userdata,
|
|
||||||
[MarshalAs(UnmanagedType.LPUTF8Str)] string name,
|
|
||||||
mpv_format format);
|
|
||||||
|
|
||||||
[DllImport("mpv-1.dll", CallingConvention = CallingConvention.Cdecl)]
|
|
||||||
public static extern int mpv_unobserve_property(IntPtr mpvHandle, UInt64 registered_reply_userdata);
|
|
||||||
|
|
||||||
[DllImport("mpv-1.dll", CallingConvention = CallingConvention.Cdecl)]
|
|
||||||
public static extern void mpv_free(IntPtr data);
|
|
||||||
|
|
||||||
[DllImport("mpv-1.dll", CallingConvention = CallingConvention.Cdecl)]
|
|
||||||
public static extern IntPtr mpv_wait_event(IntPtr mpvHandle, double timeout);
|
|
||||||
|
|
||||||
public enum mpv_error
|
|
||||||
{
|
|
||||||
MPV_ERROR_SUCCESS = 0,
|
|
||||||
MPV_ERROR_EVENT_QUEUE_FULL = -1,
|
|
||||||
MPV_ERROR_NOMEM = -2,
|
|
||||||
MPV_ERROR_UNINITIALIZED = -3,
|
|
||||||
MPV_ERROR_INVALID_PARAMETER = -4,
|
|
||||||
MPV_ERROR_OPTION_NOT_FOUND = -5,
|
|
||||||
MPV_ERROR_OPTION_FORMAT = -6,
|
|
||||||
MPV_ERROR_OPTION_ERROR = -7,
|
|
||||||
MPV_ERROR_PROPERTY_NOT_FOUND = -8,
|
|
||||||
MPV_ERROR_PROPERTY_FORMAT = -9,
|
|
||||||
MPV_ERROR_PROPERTY_UNAVAILABLE = -10,
|
|
||||||
MPV_ERROR_PROPERTY_ERROR = -11,
|
|
||||||
MPV_ERROR_COMMAND = -12,
|
|
||||||
MPV_ERROR_LOADING_FAILED = -13,
|
|
||||||
MPV_ERROR_AO_INIT_FAILED = -14,
|
|
||||||
MPV_ERROR_VO_INIT_FAILED = -15,
|
|
||||||
MPV_ERROR_NOTHING_TO_PLAY = -16,
|
|
||||||
MPV_ERROR_UNKNOWN_FORMAT = -17,
|
|
||||||
MPV_ERROR_UNSUPPORTED = -18,
|
|
||||||
MPV_ERROR_NOT_IMPLEMENTED = -19,
|
|
||||||
MPV_ERROR_GENERIC = -20
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum mpv_event_id
|
|
||||||
{
|
|
||||||
MPV_EVENT_NONE = 0,
|
|
||||||
MPV_EVENT_SHUTDOWN = 1,
|
|
||||||
MPV_EVENT_LOG_MESSAGE = 2,
|
|
||||||
MPV_EVENT_GET_PROPERTY_REPLY = 3,
|
|
||||||
MPV_EVENT_SET_PROPERTY_REPLY = 4,
|
|
||||||
MPV_EVENT_COMMAND_REPLY = 5,
|
|
||||||
MPV_EVENT_START_FILE = 6,
|
|
||||||
MPV_EVENT_END_FILE = 7,
|
|
||||||
MPV_EVENT_FILE_LOADED = 8,
|
|
||||||
MPV_EVENT_TRACKS_CHANGED = 9,
|
|
||||||
MPV_EVENT_TRACK_SWITCHED = 10,
|
|
||||||
MPV_EVENT_IDLE = 11,
|
|
||||||
MPV_EVENT_PAUSE = 12,
|
|
||||||
MPV_EVENT_UNPAUSE = 13,
|
|
||||||
MPV_EVENT_TICK = 14,
|
|
||||||
MPV_EVENT_SCRIPT_INPUT_DISPATCH = 15,
|
|
||||||
MPV_EVENT_CLIENT_MESSAGE = 16,
|
|
||||||
MPV_EVENT_VIDEO_RECONFIG = 17,
|
|
||||||
MPV_EVENT_AUDIO_RECONFIG = 18,
|
|
||||||
MPV_EVENT_METADATA_UPDATE = 19,
|
|
||||||
MPV_EVENT_SEEK = 20,
|
|
||||||
MPV_EVENT_PLAYBACK_RESTART = 21,
|
|
||||||
MPV_EVENT_PROPERTY_CHANGE = 22,
|
|
||||||
MPV_EVENT_CHAPTER_CHANGE = 23,
|
|
||||||
MPV_EVENT_QUEUE_OVERFLOW = 24,
|
|
||||||
MPV_EVENT_HOOK = 25
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum mpv_format
|
|
||||||
{
|
|
||||||
MPV_FORMAT_NONE = 0,
|
|
||||||
MPV_FORMAT_STRING = 1,
|
|
||||||
MPV_FORMAT_OSD_STRING = 2,
|
|
||||||
MPV_FORMAT_FLAG = 3,
|
|
||||||
MPV_FORMAT_INT64 = 4,
|
|
||||||
MPV_FORMAT_DOUBLE = 5,
|
|
||||||
MPV_FORMAT_NODE = 6,
|
|
||||||
MPV_FORMAT_NODE_ARRAY = 7,
|
|
||||||
MPV_FORMAT_NODE_MAP = 8,
|
|
||||||
MPV_FORMAT_BYTE_ARRAY = 9
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum mpv_log_level
|
|
||||||
{
|
|
||||||
MPV_LOG_LEVEL_NONE = 0,
|
|
||||||
MPV_LOG_LEVEL_FATAL = 10,
|
|
||||||
MPV_LOG_LEVEL_ERROR = 20,
|
|
||||||
MPV_LOG_LEVEL_WARN = 30,
|
|
||||||
MPV_LOG_LEVEL_INFO = 40,
|
|
||||||
MPV_LOG_LEVEL_V = 50,
|
|
||||||
MPV_LOG_LEVEL_DEBUG = 60,
|
|
||||||
MPV_LOG_LEVEL_TRACE = 70,
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum mpv_end_file_reason
|
|
||||||
{
|
|
||||||
MPV_END_FILE_REASON_EOF = 0,
|
|
||||||
MPV_END_FILE_REASON_STOP = 2,
|
|
||||||
MPV_END_FILE_REASON_QUIT = 3,
|
|
||||||
MPV_END_FILE_REASON_ERROR = 4,
|
|
||||||
MPV_END_FILE_REASON_REDIRECT = 5
|
|
||||||
}
|
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential)]
|
|
||||||
public struct mpv_event_log_message
|
|
||||||
{
|
|
||||||
public string prefix;
|
|
||||||
public string level;
|
|
||||||
public string text;
|
|
||||||
public mpv_log_level log_level;
|
|
||||||
}
|
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential)]
|
|
||||||
public struct mpv_event
|
|
||||||
{
|
|
||||||
public mpv_event_id event_id;
|
|
||||||
public int error;
|
|
||||||
public UInt64 reply_userdata;
|
|
||||||
public IntPtr data;
|
|
||||||
}
|
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential)]
|
|
||||||
public struct mpv_event_client_message
|
|
||||||
{
|
|
||||||
public int num_args;
|
|
||||||
public IntPtr args;
|
|
||||||
}
|
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential)]
|
|
||||||
public struct mpv_event_property
|
|
||||||
{
|
|
||||||
public string name;
|
|
||||||
public mpv_format format;
|
|
||||||
public IntPtr data;
|
|
||||||
}
|
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential)]
|
|
||||||
public struct mpv_event_end_file
|
|
||||||
{
|
|
||||||
public int reason;
|
|
||||||
public int error;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public enum mpv_event_id
|
||||||
|
{
|
||||||
|
MPV_EVENT_NONE = 0,
|
||||||
|
MPV_EVENT_SHUTDOWN = 1,
|
||||||
|
MPV_EVENT_LOG_MESSAGE = 2,
|
||||||
|
MPV_EVENT_GET_PROPERTY_REPLY = 3,
|
||||||
|
MPV_EVENT_SET_PROPERTY_REPLY = 4,
|
||||||
|
MPV_EVENT_COMMAND_REPLY = 5,
|
||||||
|
MPV_EVENT_START_FILE = 6,
|
||||||
|
MPV_EVENT_END_FILE = 7,
|
||||||
|
MPV_EVENT_FILE_LOADED = 8,
|
||||||
|
MPV_EVENT_TRACKS_CHANGED = 9,
|
||||||
|
MPV_EVENT_TRACK_SWITCHED = 10,
|
||||||
|
MPV_EVENT_IDLE = 11,
|
||||||
|
MPV_EVENT_PAUSE = 12,
|
||||||
|
MPV_EVENT_UNPAUSE = 13,
|
||||||
|
MPV_EVENT_TICK = 14,
|
||||||
|
MPV_EVENT_SCRIPT_INPUT_DISPATCH = 15,
|
||||||
|
MPV_EVENT_CLIENT_MESSAGE = 16,
|
||||||
|
MPV_EVENT_VIDEO_RECONFIG = 17,
|
||||||
|
MPV_EVENT_AUDIO_RECONFIG = 18,
|
||||||
|
MPV_EVENT_METADATA_UPDATE = 19,
|
||||||
|
MPV_EVENT_SEEK = 20,
|
||||||
|
MPV_EVENT_PLAYBACK_RESTART = 21,
|
||||||
|
MPV_EVENT_PROPERTY_CHANGE = 22,
|
||||||
|
MPV_EVENT_CHAPTER_CHANGE = 23,
|
||||||
|
MPV_EVENT_QUEUE_OVERFLOW = 24,
|
||||||
|
MPV_EVENT_HOOK = 25
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum mpv_format
|
||||||
|
{
|
||||||
|
MPV_FORMAT_NONE = 0,
|
||||||
|
MPV_FORMAT_STRING = 1,
|
||||||
|
MPV_FORMAT_OSD_STRING = 2,
|
||||||
|
MPV_FORMAT_FLAG = 3,
|
||||||
|
MPV_FORMAT_INT64 = 4,
|
||||||
|
MPV_FORMAT_DOUBLE = 5,
|
||||||
|
MPV_FORMAT_NODE = 6,
|
||||||
|
MPV_FORMAT_NODE_ARRAY = 7,
|
||||||
|
MPV_FORMAT_NODE_MAP = 8,
|
||||||
|
MPV_FORMAT_BYTE_ARRAY = 9
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum mpv_log_level
|
||||||
|
{
|
||||||
|
MPV_LOG_LEVEL_NONE = 0,
|
||||||
|
MPV_LOG_LEVEL_FATAL = 10,
|
||||||
|
MPV_LOG_LEVEL_ERROR = 20,
|
||||||
|
MPV_LOG_LEVEL_WARN = 30,
|
||||||
|
MPV_LOG_LEVEL_INFO = 40,
|
||||||
|
MPV_LOG_LEVEL_V = 50,
|
||||||
|
MPV_LOG_LEVEL_DEBUG = 60,
|
||||||
|
MPV_LOG_LEVEL_TRACE = 70,
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum mpv_end_file_reason
|
||||||
|
{
|
||||||
|
MPV_END_FILE_REASON_EOF = 0,
|
||||||
|
MPV_END_FILE_REASON_STOP = 2,
|
||||||
|
MPV_END_FILE_REASON_QUIT = 3,
|
||||||
|
MPV_END_FILE_REASON_ERROR = 4,
|
||||||
|
MPV_END_FILE_REASON_REDIRECT = 5
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
public struct mpv_event_log_message
|
||||||
|
{
|
||||||
|
public string prefix;
|
||||||
|
public string level;
|
||||||
|
public string text;
|
||||||
|
public mpv_log_level log_level;
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
public struct mpv_event
|
||||||
|
{
|
||||||
|
public mpv_event_id event_id;
|
||||||
|
public int error;
|
||||||
|
public UInt64 reply_userdata;
|
||||||
|
public IntPtr data;
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
public struct mpv_event_client_message
|
||||||
|
{
|
||||||
|
public int num_args;
|
||||||
|
public IntPtr args;
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
public struct mpv_event_property
|
||||||
|
{
|
||||||
|
public string name;
|
||||||
|
public mpv_format format;
|
||||||
|
public IntPtr data;
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
public struct mpv_event_end_file
|
||||||
|
{
|
||||||
|
public int reason;
|
||||||
|
public int error;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IntPtr AllocateUtf8ArrayWithSentinel(string[] arr, out IntPtr[] byteArrayPointers)
|
||||||
|
{
|
||||||
|
int numberOfStrings = arr.Length + 1; // add extra element for extra null pointer last (sentinel)
|
||||||
|
byteArrayPointers = new IntPtr[numberOfStrings];
|
||||||
|
IntPtr rootPointer = Marshal.AllocCoTaskMem(IntPtr.Size * numberOfStrings);
|
||||||
|
|
||||||
|
for (int index = 0; index < arr.Length; index++)
|
||||||
|
{
|
||||||
|
var bytes = GetUtf8Bytes(arr[index]);
|
||||||
|
IntPtr unmanagedPointer = Marshal.AllocHGlobal(bytes.Length);
|
||||||
|
Marshal.Copy(bytes, 0, unmanagedPointer, bytes.Length);
|
||||||
|
byteArrayPointers[index] = unmanagedPointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
Marshal.Copy(byteArrayPointers, 0, rootPointer, numberOfStrings);
|
||||||
|
return rootPointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string[] ConvertFromUtf8Strings(IntPtr utf8StringArray, int stringCount)
|
||||||
|
{
|
||||||
|
IntPtr[] intPtrArray = new IntPtr[stringCount];
|
||||||
|
string[] stringArray = new string[stringCount];
|
||||||
|
Marshal.Copy(utf8StringArray, intPtrArray, 0, stringCount);
|
||||||
|
|
||||||
|
for (int i = 0; i < stringCount; i++)
|
||||||
|
stringArray[i] = ConvertFromUtf8(intPtrArray[i]);
|
||||||
|
|
||||||
|
return stringArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string ConvertFromUtf8(IntPtr nativeUtf8)
|
||||||
|
{
|
||||||
|
int len = 0;
|
||||||
|
while (Marshal.ReadByte(nativeUtf8, len) != 0) ++len;
|
||||||
|
byte[] buffer = new byte[len];
|
||||||
|
Marshal.Copy(nativeUtf8, buffer, 0, buffer.Length);
|
||||||
|
return Encoding.UTF8.GetString(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string GetError(mpv_error err) => ConvertFromUtf8(mpv_error_string(err));
|
||||||
|
|
||||||
|
public static byte[] GetUtf8Bytes(string s) => Encoding.UTF8.GetBytes(s + "\0");
|
||||||
}
|
}
|
||||||
@@ -9,15 +9,14 @@ using System.IO;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Text;
|
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
|
|
||||||
using WinForms = System.Windows.Forms;
|
using WinForms = System.Windows.Forms;
|
||||||
|
|
||||||
using static mpvnet.libmpv;
|
using static libmpv;
|
||||||
using static Native;
|
using static WinAPI;
|
||||||
|
|
||||||
namespace mpvnet
|
namespace mpvnet
|
||||||
{
|
{
|
||||||
@@ -30,7 +29,7 @@ namespace mpvnet
|
|||||||
|
|
||||||
// MPV_EVENT_NONE
|
// MPV_EVENT_NONE
|
||||||
public static event Action Shutdown; // shutdown MPV_EVENT_SHUTDOWN
|
public static event Action Shutdown; // shutdown MPV_EVENT_SHUTDOWN
|
||||||
public static event Action LogMessage; // log-message MPV_EVENT_LOG_MESSAGE
|
public static event Action <string>LogMessage; // log-message MPV_EVENT_LOG_MESSAGE
|
||||||
public static event Action GetPropertyReply; // get-property-reply MPV_EVENT_GET_PROPERTY_REPLY
|
public static event Action GetPropertyReply; // get-property-reply MPV_EVENT_GET_PROPERTY_REPLY
|
||||||
public static event Action SetPropertyReply; // set-property-reply MPV_EVENT_SET_PROPERTY_REPLY
|
public static event Action SetPropertyReply; // set-property-reply MPV_EVENT_SET_PROPERTY_REPLY
|
||||||
public static event Action CommandReply; // command-reply MPV_EVENT_COMMAND_REPLY
|
public static event Action CommandReply; // command-reply MPV_EVENT_COMMAND_REPLY
|
||||||
@@ -94,6 +93,11 @@ namespace mpvnet
|
|||||||
public static void Init()
|
public static void Init()
|
||||||
{
|
{
|
||||||
Handle = mpv_create();
|
Handle = mpv_create();
|
||||||
|
|
||||||
|
if (Handle == IntPtr.Zero)
|
||||||
|
throw new Exception("error mpv_create");
|
||||||
|
|
||||||
|
mpv_request_log_messages(Handle, "error");
|
||||||
Task.Run(() => EventLoop());
|
Task.Run(() => EventLoop());
|
||||||
|
|
||||||
if (App.IsStartedFromTerminal)
|
if (App.IsStartedFromTerminal)
|
||||||
@@ -111,7 +115,11 @@ namespace mpvnet
|
|||||||
set_property_string("config", "yes");
|
set_property_string("config", "yes");
|
||||||
|
|
||||||
ProcessCommandLine(true);
|
ProcessCommandLine(true);
|
||||||
mpv_initialize(Handle);
|
mpv_error err = mpv_initialize(Handle);
|
||||||
|
|
||||||
|
if (err < 0)
|
||||||
|
throw new Exception("mpv_initialize error\n\n" + GetError(err));
|
||||||
|
|
||||||
Initialized?.Invoke();
|
Initialized?.Invoke();
|
||||||
LoadMpvScripts();
|
LoadMpvScripts();
|
||||||
}
|
}
|
||||||
@@ -296,7 +304,10 @@ namespace mpvnet
|
|||||||
ShutdownAutoResetEvent.Set();
|
ShutdownAutoResetEvent.Set();
|
||||||
return;
|
return;
|
||||||
case mpv_event_id.MPV_EVENT_LOG_MESSAGE:
|
case mpv_event_id.MPV_EVENT_LOG_MESSAGE:
|
||||||
LogMessage?.Invoke();
|
{
|
||||||
|
var data = (mpv_event_log_message)Marshal.PtrToStructure(evt.data, typeof(mpv_event_log_message));
|
||||||
|
LogMessage?.Invoke($"[{data.prefix}] {data.text}");
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case mpv_event_id.MPV_EVENT_GET_PROPERTY_REPLY:
|
case mpv_event_id.MPV_EVENT_GET_PROPERTY_REPLY:
|
||||||
GetPropertyReply?.Invoke();
|
GetPropertyReply?.Invoke();
|
||||||
@@ -311,28 +322,33 @@ namespace mpvnet
|
|||||||
StartFile?.Invoke();
|
StartFile?.Invoke();
|
||||||
break;
|
break;
|
||||||
case mpv_event_id.MPV_EVENT_END_FILE:
|
case mpv_event_id.MPV_EVENT_END_FILE:
|
||||||
var end_fileData = (mpv_event_end_file)Marshal.PtrToStructure(evt.data, typeof(mpv_event_end_file));
|
{
|
||||||
EndFileEventMode reason = (EndFileEventMode)end_fileData.reason;
|
var data = (mpv_event_end_file)Marshal.PtrToStructure(evt.data, typeof(mpv_event_end_file));
|
||||||
EndFile?.Invoke(reason);
|
EndFileEventMode reason = (EndFileEventMode)data.reason;
|
||||||
|
EndFile?.Invoke(reason);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case mpv_event_id.MPV_EVENT_FILE_LOADED:
|
case mpv_event_id.MPV_EVENT_FILE_LOADED:
|
||||||
HideLogo();
|
|
||||||
Duration = TimeSpan.FromSeconds(get_property_number("duration"));
|
|
||||||
Size vidSize = new Size(get_property_int("width"), get_property_int("height"));
|
|
||||||
if (vidSize.Width == 0 || vidSize.Height == 0)
|
|
||||||
vidSize = new Size(1, 1);
|
|
||||||
if (VideoSize != vidSize)
|
|
||||||
{
|
{
|
||||||
VideoSize = vidSize;
|
HideLogo();
|
||||||
VideoSizeChanged?.Invoke();
|
Duration = TimeSpan.FromSeconds(get_property_number("duration"));
|
||||||
|
Size vidSize = new Size(get_property_int("width"), get_property_int("height"));
|
||||||
|
if (vidSize.Width == 0 || vidSize.Height == 0)
|
||||||
|
vidSize = new Size(1, 1);
|
||||||
|
if (VideoSize != vidSize)
|
||||||
|
{
|
||||||
|
VideoSize = vidSize;
|
||||||
|
VideoSizeChanged?.Invoke();
|
||||||
|
}
|
||||||
|
VideoSizeAutoResetEvent.Set();
|
||||||
|
Task.Run(new Action(() => ReadMetaData()));
|
||||||
|
string path = mp.get_property_string("path");
|
||||||
|
if (path.Contains("://"))
|
||||||
|
path = mp.get_property_string("media-title");
|
||||||
|
WriteHistory(path);
|
||||||
|
FileLoaded?.Invoke();
|
||||||
}
|
}
|
||||||
VideoSizeAutoResetEvent.Set();
|
|
||||||
Task.Run(new Action(() => ReadMetaData()));
|
|
||||||
string path = mp.get_property_string("path");
|
|
||||||
if (path.Contains("://"))
|
|
||||||
path = mp.get_property_string("media-title");
|
|
||||||
WriteHistory(path);
|
|
||||||
FileLoaded?.Invoke();
|
|
||||||
break;
|
break;
|
||||||
case mpv_event_id.MPV_EVENT_TRACKS_CHANGED:
|
case mpv_event_id.MPV_EVENT_TRACKS_CHANGED:
|
||||||
TracksChanged?.Invoke();
|
TracksChanged?.Invoke();
|
||||||
@@ -357,12 +373,14 @@ namespace mpvnet
|
|||||||
ScriptInputDispatch?.Invoke();
|
ScriptInputDispatch?.Invoke();
|
||||||
break;
|
break;
|
||||||
case mpv_event_id.MPV_EVENT_CLIENT_MESSAGE:
|
case mpv_event_id.MPV_EVENT_CLIENT_MESSAGE:
|
||||||
var client_messageData = (mpv_event_client_message)Marshal.PtrToStructure(evt.data, typeof(mpv_event_client_message));
|
{
|
||||||
string[] args = NativeUtf8StrArray2ManagedStrArray(client_messageData.args, client_messageData.num_args);
|
var data = (mpv_event_client_message)Marshal.PtrToStructure(evt.data, typeof(mpv_event_client_message));
|
||||||
if (args.Length > 1 && args[0] == "mpv.net")
|
string[] args = ConvertFromUtf8Strings(data.args, data.num_args);
|
||||||
Command.Execute(args[1], args.Skip(2).ToArray());
|
if (args.Length > 1 && args[0] == "mpv.net")
|
||||||
else if (args.Length > 0)
|
Command.Execute(args[1], args.Skip(2).ToArray());
|
||||||
ClientMessage?.Invoke(args);
|
else if (args.Length > 0)
|
||||||
|
ClientMessage?.Invoke(args);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case mpv_event_id.MPV_EVENT_VIDEO_RECONFIG:
|
case mpv_event_id.MPV_EVENT_VIDEO_RECONFIG:
|
||||||
VideoReconfig?.Invoke();
|
VideoReconfig?.Invoke();
|
||||||
@@ -377,35 +395,37 @@ namespace mpvnet
|
|||||||
Seek?.Invoke();
|
Seek?.Invoke();
|
||||||
break;
|
break;
|
||||||
case mpv_event_id.MPV_EVENT_PROPERTY_CHANGE:
|
case mpv_event_id.MPV_EVENT_PROPERTY_CHANGE:
|
||||||
var propData = (mpv_event_property)Marshal.PtrToStructure(evt.data, typeof(mpv_event_property));
|
{
|
||||||
|
var data = (mpv_event_property)Marshal.PtrToStructure(evt.data, typeof(mpv_event_property));
|
||||||
|
|
||||||
if (propData.format == mpv_format.MPV_FORMAT_FLAG)
|
if (data.format == mpv_format.MPV_FORMAT_FLAG)
|
||||||
{
|
{
|
||||||
lock (BoolPropChangeActions)
|
lock (BoolPropChangeActions)
|
||||||
foreach (var i in BoolPropChangeActions)
|
foreach (var i in BoolPropChangeActions)
|
||||||
if (i.Key== propData.name)
|
if (i.Key== data.name)
|
||||||
i.Value.Invoke(Marshal.PtrToStructure<int>(propData.data) == 1);
|
i.Value.Invoke(Marshal.PtrToStructure<int>(data.data) == 1);
|
||||||
}
|
}
|
||||||
else if (propData.format == mpv_format.MPV_FORMAT_STRING)
|
else if (data.format == mpv_format.MPV_FORMAT_STRING)
|
||||||
{
|
{
|
||||||
lock (StringPropChangeActions)
|
lock (StringPropChangeActions)
|
||||||
foreach (var i in StringPropChangeActions)
|
foreach (var i in StringPropChangeActions)
|
||||||
if (i.Key == propData.name)
|
if (i.Key == data.name)
|
||||||
i.Value.Invoke(StringFromNativeUtf8(Marshal.PtrToStructure<IntPtr>(propData.data)));
|
i.Value.Invoke(ConvertFromUtf8(Marshal.PtrToStructure<IntPtr>(data.data)));
|
||||||
}
|
}
|
||||||
else if(propData.format == mpv_format.MPV_FORMAT_INT64)
|
else if(data.format == mpv_format.MPV_FORMAT_INT64)
|
||||||
{
|
{
|
||||||
lock (IntPropChangeActions)
|
lock (IntPropChangeActions)
|
||||||
foreach (var i in IntPropChangeActions)
|
foreach (var i in IntPropChangeActions)
|
||||||
if (i.Key == propData.name)
|
if (i.Key == data.name)
|
||||||
i.Value.Invoke(Marshal.PtrToStructure<int>(propData.data));
|
i.Value.Invoke(Marshal.PtrToStructure<int>(data.data));
|
||||||
}
|
}
|
||||||
else if (propData.format == mpv_format.MPV_FORMAT_DOUBLE)
|
else if (data.format == mpv_format.MPV_FORMAT_DOUBLE)
|
||||||
{
|
{
|
||||||
lock (DoublePropChangeActions)
|
lock (DoublePropChangeActions)
|
||||||
foreach (var i in DoublePropChangeActions)
|
foreach (var i in DoublePropChangeActions)
|
||||||
if (i.Key == propData.name)
|
if (i.Key == data.name)
|
||||||
i.Value.Invoke(Marshal.PtrToStructure<double>(propData.data));
|
i.Value.Invoke(Marshal.PtrToStructure<double>(data.data));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case mpv_event_id.MPV_EVENT_PLAYBACK_RESTART:
|
case mpv_event_id.MPV_EVENT_PLAYBACK_RESTART:
|
||||||
@@ -475,59 +495,71 @@ namespace mpvnet
|
|||||||
|
|
||||||
public static void commandv(params string[] args)
|
public static void commandv(params string[] args)
|
||||||
{
|
{
|
||||||
if (Handle == IntPtr.Zero) return;
|
IntPtr mainPtr = AllocateUtf8ArrayWithSentinel(args, out IntPtr[] byteArrayPointers);
|
||||||
IntPtr mainPtr = AllocateUtf8IntPtrArrayWithSentinel(args, out IntPtr[] byteArrayPointers);
|
mpv_error err = mpv_command(Handle, mainPtr);
|
||||||
int err = mpv_command(Handle, mainPtr);
|
|
||||||
if (err < 0) throw new Exception($"{(mpv_error)err}");
|
foreach (IntPtr ptr in byteArrayPointers)
|
||||||
foreach (var ptr in byteArrayPointers)
|
|
||||||
Marshal.FreeHGlobal(ptr);
|
Marshal.FreeHGlobal(ptr);
|
||||||
|
|
||||||
Marshal.FreeHGlobal(mainPtr);
|
Marshal.FreeHGlobal(mainPtr);
|
||||||
|
|
||||||
|
if (err < 0)
|
||||||
|
throw new Exception("error executing command:\n\n" +
|
||||||
|
string.Join("\n", args) + "\r\n\r\n" + GetError(err));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void command(string command, bool throwException = false)
|
public static void command(string command, bool throwException = false)
|
||||||
{
|
{
|
||||||
if (Handle == IntPtr.Zero) return;
|
mpv_error err = mpv_command_string(Handle, command);
|
||||||
int err = mpv_command_string(Handle, command);
|
|
||||||
if (err < 0 && throwException) throw new Exception($"{(mpv_error)err}\n\n" + command);
|
if (err < 0 && throwException)
|
||||||
|
throw new Exception("error executing command:\n\n" + command + "\r\n\r\n" + GetError(err));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void set_property_string(string name, string value, bool throwOnException = false)
|
public static void set_property_string(string name, string value, bool throwOnException = false)
|
||||||
{
|
{
|
||||||
byte[] bytes = GetUtf8Bytes(value);
|
byte[] bytes = GetUtf8Bytes(value);
|
||||||
int err = mpv_set_property(Handle, GetUtf8Bytes(name), mpv_format.MPV_FORMAT_STRING, ref bytes);
|
mpv_error err = mpv_set_property(Handle, GetUtf8Bytes(name), mpv_format.MPV_FORMAT_STRING, ref bytes);
|
||||||
if (err < 0 && throwOnException) throw new Exception($"{name}: {(mpv_error)err}");
|
|
||||||
|
if (err < 0 && throwOnException)
|
||||||
|
throw new Exception($"error setting property: {name} = " + value + "\r\n\r\n" + GetError(err));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string get_property_string(string name, bool throwOnException = false)
|
public static string get_property_string(string name, bool throwOnException = false)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
int err = mpv_get_property(Handle, GetUtf8Bytes(name), mpv_format.MPV_FORMAT_STRING, out IntPtr lpBuffer);
|
mpv_error err = mpv_get_property(Handle, GetUtf8Bytes(name),
|
||||||
|
mpv_format.MPV_FORMAT_STRING, out IntPtr lpBuffer);
|
||||||
|
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
{
|
{
|
||||||
if (throwOnException) throw new Exception($"{name}: {(mpv_error)err}");
|
if (throwOnException)
|
||||||
|
throw new Exception($"error getting property: {name}\n\n" + GetError(err));
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
string ret = StringFromNativeUtf8(lpBuffer);
|
string ret = ConvertFromUtf8(lpBuffer);
|
||||||
mpv_free(lpBuffer);
|
mpv_free(lpBuffer);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
if (throwOnException) throw e;
|
if (throwOnException)
|
||||||
|
throw e;
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int get_property_int(string name, bool throwOnException = false)
|
public static int get_property_int(string name, bool throwOnException = false)
|
||||||
{
|
{
|
||||||
int err = mpv_get_property(Handle, GetUtf8Bytes(name), mpv_format.MPV_FORMAT_INT64, out IntPtr lpBuffer);
|
mpv_error err = mpv_get_property(Handle, GetUtf8Bytes(name),
|
||||||
|
mpv_format.MPV_FORMAT_INT64, out IntPtr lpBuffer);
|
||||||
|
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
{
|
{
|
||||||
if (throwOnException) throw new Exception($"{name}: {(mpv_error)err}");
|
if (throwOnException)
|
||||||
|
throw new Exception($"error getting property: {name}\n\n" + GetError(err));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -536,31 +568,35 @@ namespace mpvnet
|
|||||||
|
|
||||||
public static double get_property_number(string name, bool throwOnException = false)
|
public static double get_property_number(string name, bool throwOnException = false)
|
||||||
{
|
{
|
||||||
double val = 0;
|
mpv_error err = mpv_get_property(Handle, GetUtf8Bytes(name),
|
||||||
int err = mpv_get_property(Handle, GetUtf8Bytes(name), mpv_format.MPV_FORMAT_DOUBLE, ref val);
|
mpv_format.MPV_FORMAT_DOUBLE, out double value);
|
||||||
|
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
{
|
{
|
||||||
if (throwOnException) throw new Exception($"{name}: {(mpv_error)err}");
|
if (throwOnException)
|
||||||
|
throw new Exception($"error getting property: {name}\n\n" + GetError(err));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return val;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void set_property_int(string name, int value, bool throwOnException = false)
|
public static void set_property_int(string name, int value, bool throwOnException = false)
|
||||||
{
|
{
|
||||||
Int64 val = value;
|
Int64 val = value;
|
||||||
int err = mpv_set_property(Handle, GetUtf8Bytes(name), mpv_format.MPV_FORMAT_INT64, ref val);
|
mpv_error err = mpv_set_property(Handle, GetUtf8Bytes(name), mpv_format.MPV_FORMAT_INT64, ref val);
|
||||||
if (err < 0 && throwOnException) throw new Exception($"{name}: {(mpv_error)err}");
|
|
||||||
|
if (err < 0 && throwOnException)
|
||||||
|
throw new Exception($"error setting property: {name} = {value}\n\n" + GetError(err));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void observe_property_int(string name, Action<int> action)
|
public static void observe_property_int(string name, Action<int> action)
|
||||||
{
|
{
|
||||||
int err = mpv_observe_property(Handle, (ulong)action.GetHashCode(), name, mpv_format.MPV_FORMAT_INT64);
|
mpv_error err = mpv_observe_property(Handle, (ulong)action.GetHashCode(),
|
||||||
|
name, mpv_format.MPV_FORMAT_INT64);
|
||||||
|
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
throw new Exception($"{name}: {(mpv_error)err}");
|
throw new Exception($"error observing property: {name}\n\n" + GetError(err));
|
||||||
else
|
else
|
||||||
lock (IntPropChangeActions)
|
lock (IntPropChangeActions)
|
||||||
IntPropChangeActions.Add(new KeyValuePair<string, Action<int>>(name, action));
|
IntPropChangeActions.Add(new KeyValuePair<string, Action<int>>(name, action));
|
||||||
@@ -568,10 +604,11 @@ namespace mpvnet
|
|||||||
|
|
||||||
public static void observe_property_double(string name, Action<double> action)
|
public static void observe_property_double(string name, Action<double> action)
|
||||||
{
|
{
|
||||||
int err = mpv_observe_property(Handle, (ulong)action.GetHashCode(), name, mpv_format.MPV_FORMAT_DOUBLE);
|
mpv_error err = mpv_observe_property(Handle, (ulong)action.GetHashCode(),
|
||||||
|
name, mpv_format.MPV_FORMAT_DOUBLE);
|
||||||
|
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
throw new Exception($"{name}: {(mpv_error)err}");
|
throw new Exception($"error observing property: {name}\n\n" + GetError(err));
|
||||||
else
|
else
|
||||||
lock (DoublePropChangeActions)
|
lock (DoublePropChangeActions)
|
||||||
DoublePropChangeActions.Add(new KeyValuePair<string, Action<double>>(name, action));
|
DoublePropChangeActions.Add(new KeyValuePair<string, Action<double>>(name, action));
|
||||||
@@ -579,10 +616,11 @@ namespace mpvnet
|
|||||||
|
|
||||||
public static void observe_property_bool(string name, Action<bool> action)
|
public static void observe_property_bool(string name, Action<bool> action)
|
||||||
{
|
{
|
||||||
int err = mpv_observe_property(Handle, (ulong)action.GetHashCode(), name, mpv_format.MPV_FORMAT_FLAG);
|
mpv_error err = mpv_observe_property(Handle, (ulong)action.GetHashCode(),
|
||||||
|
name, mpv_format.MPV_FORMAT_FLAG);
|
||||||
|
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
throw new Exception($"{name}: {(mpv_error)err}");
|
throw new Exception($"error observing property: {name}\n\n" + GetError(err));
|
||||||
else
|
else
|
||||||
lock (BoolPropChangeActions)
|
lock (BoolPropChangeActions)
|
||||||
BoolPropChangeActions.Add(new KeyValuePair<string, Action<bool>>(name, action));
|
BoolPropChangeActions.Add(new KeyValuePair<string, Action<bool>>(name, action));
|
||||||
@@ -590,10 +628,11 @@ namespace mpvnet
|
|||||||
|
|
||||||
public static void observe_property_string(string name, Action<string> action)
|
public static void observe_property_string(string name, Action<string> action)
|
||||||
{
|
{
|
||||||
int err = mpv_observe_property(Handle, (ulong)action.GetHashCode(), name, mpv_format.MPV_FORMAT_STRING);
|
mpv_error err = mpv_observe_property(Handle, (ulong)action.GetHashCode(),
|
||||||
|
name, mpv_format.MPV_FORMAT_STRING);
|
||||||
|
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
throw new Exception($"{name}: {(mpv_error)err}");
|
throw new Exception($"error observing property: {name}\n\n" + GetError(err));
|
||||||
else
|
else
|
||||||
lock (StringPropChangeActions)
|
lock (StringPropChangeActions)
|
||||||
StringPropChangeActions.Add(new KeyValuePair<string, Action<string>>(name, action));
|
StringPropChangeActions.Add(new KeyValuePair<string, Action<string>>(name, action));
|
||||||
@@ -615,12 +654,14 @@ namespace mpvnet
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (!arg.Contains("=")) arg += "=yes";
|
if (!arg.Contains("="))
|
||||||
|
arg += "=yes";
|
||||||
|
|
||||||
string left = arg.Substring(2, arg.IndexOf("=") - 2);
|
string left = arg.Substring(2, arg.IndexOf("=") - 2);
|
||||||
string right = arg.Substring(left.Length + 3);
|
string right = arg.Substring(left.Length + 3);
|
||||||
|
|
||||||
if (left == "script") left = "scripts";
|
if (left == "script")
|
||||||
|
left = "scripts";
|
||||||
|
|
||||||
if (preInit && preInitProperties.Contains(left))
|
if (preInit && preInitProperties.Contains(left))
|
||||||
{
|
{
|
||||||
@@ -741,47 +782,6 @@ namespace mpvnet
|
|||||||
commandv("playlist-move", "0", (index + 1).ToString());
|
commandv("playlist-move", "0", (index + 1).ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IntPtr AllocateUtf8IntPtrArrayWithSentinel(string[] arr, out IntPtr[] byteArrayPointers)
|
|
||||||
{
|
|
||||||
int numberOfStrings = arr.Length + 1; // add extra element for extra null pointer last (sentinel)
|
|
||||||
byteArrayPointers = new IntPtr[numberOfStrings];
|
|
||||||
IntPtr rootPointer = Marshal.AllocCoTaskMem(IntPtr.Size * numberOfStrings);
|
|
||||||
|
|
||||||
for (int index = 0; index < arr.Length; index++)
|
|
||||||
{
|
|
||||||
var bytes = GetUtf8Bytes(arr[index]);
|
|
||||||
IntPtr unmanagedPointer = Marshal.AllocHGlobal(bytes.Length);
|
|
||||||
Marshal.Copy(bytes, 0, unmanagedPointer, bytes.Length);
|
|
||||||
byteArrayPointers[index] = unmanagedPointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
Marshal.Copy(byteArrayPointers, 0, rootPointer, numberOfStrings);
|
|
||||||
return rootPointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string[] NativeUtf8StrArray2ManagedStrArray(IntPtr unmanagedStringArray, int StringCount)
|
|
||||||
{
|
|
||||||
IntPtr[] intPtrArray = new IntPtr[StringCount];
|
|
||||||
string[] stringArray = new string[StringCount];
|
|
||||||
Marshal.Copy(unmanagedStringArray, intPtrArray, 0, StringCount);
|
|
||||||
|
|
||||||
for (int i = 0; i < StringCount; i++)
|
|
||||||
stringArray[i] = StringFromNativeUtf8(intPtrArray[i]);
|
|
||||||
|
|
||||||
return stringArray;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string StringFromNativeUtf8(IntPtr nativeUtf8)
|
|
||||||
{
|
|
||||||
int len = 0;
|
|
||||||
while (Marshal.ReadByte(nativeUtf8, len) != 0) ++len;
|
|
||||||
byte[] buffer = new byte[len];
|
|
||||||
Marshal.Copy(nativeUtf8, buffer, 0, buffer.Length);
|
|
||||||
return Encoding.UTF8.GetString(buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static byte[] GetUtf8Bytes(string s) => Encoding.UTF8.GetBytes(s + "\0");
|
|
||||||
|
|
||||||
static string LastHistoryPath;
|
static string LastHistoryPath;
|
||||||
static DateTime LastHistoryStartDateTime;
|
static DateTime LastHistoryStartDateTime;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user