Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3fd1285ad8 | ||
|
|
91a67c29a7 | ||
|
|
c8ce0b6dfc | ||
|
|
c075f4982b | ||
|
|
303355ce63 | ||
|
|
a392c2c6da | ||
|
|
72d6f44e47 | ||
|
|
2e695e43bf | ||
|
|
207c2fc685 | ||
|
|
3939dc7924 |
@@ -11,7 +11,7 @@ Public Class CSScriptAddon
|
||||
Implements IAddon
|
||||
|
||||
Sub New()
|
||||
Dim scriptDir = mpv.mpvConfFolderPath + "scripts"
|
||||
Dim scriptDir = mp.mpvConfFolderPath + "scripts"
|
||||
If Not Directory.Exists(scriptDir) Then Return
|
||||
Dim csFiles = Directory.GetFiles(scriptDir, "*.cs")
|
||||
If csFiles.Count = 0 Then Return
|
||||
|
||||
@@ -52,11 +52,6 @@
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>.\CSScriptLibrary.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="mpvnet, Version=0.2.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\mpv.net\bin\Debug\mpvnet.exe</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.ComponentModel.Composition" />
|
||||
<Reference Include="System.Data" />
|
||||
@@ -117,5 +112,12 @@
|
||||
<ItemGroup>
|
||||
<Content Include="CSScriptLibrary.dll" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\mpv.net\mpv.net.csproj">
|
||||
<Project>{1751f378-8edf-4b62-be6d-304c7c287089}</Project>
|
||||
<Name>mpv.net</Name>
|
||||
<Private>False</Private>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.VisualBasic.targets" />
|
||||
</Project>
|
||||
@@ -8,11 +8,11 @@ Imports System.Runtime.InteropServices
|
||||
|
||||
' Review the values of the assembly attributes
|
||||
|
||||
<Assembly: AssemblyTitle("PowerShellAddon")>
|
||||
<Assembly: AssemblyTitle("CSScriptAddon")>
|
||||
<Assembly: AssemblyDescription("")>
|
||||
<Assembly: AssemblyCompany("")>
|
||||
<Assembly: AssemblyProduct("PowerShellAddon")>
|
||||
<Assembly: AssemblyCopyright("Copyright © 2017")>
|
||||
<Assembly: AssemblyProduct("CSScriptAddon")>
|
||||
<Assembly: AssemblyCopyright("Copyright © 2019")>
|
||||
<Assembly: AssemblyTrademark("")>
|
||||
|
||||
<Assembly: ComVisible(False)>
|
||||
|
||||
47
README.md
47
README.md
@@ -8,12 +8,13 @@ mpv manual: https://mpv.io/manual/master/
|
||||
|
||||
### Features
|
||||
|
||||
- mpv's OSC, IPC, Lua/JS, conf files and more
|
||||
- Customizable context menu defined in the same file as the keybindings
|
||||
- Addons support for using .NET languages
|
||||
- C# scripts implemented with CS-Script
|
||||
- Addon API for .NET languages
|
||||
- Python scripting implemented with IronPython
|
||||
- C# scripting implemented with CS-Script
|
||||
- mpv's OSC, IPC, Lua/JS, conf files and more
|
||||
|
||||

|
||||

|
||||
|
||||
### Context Menu
|
||||
|
||||
@@ -48,8 +49,46 @@ class Script
|
||||
}
|
||||
```
|
||||
|
||||
### Python Scripting
|
||||
|
||||
A simple Python script located at: C:\Users\user\AppData\Roaming\mpv\scripts
|
||||
|
||||
```
|
||||
# when seeking displays position and
|
||||
# duration like so: 70:00 / 80:00
|
||||
# which is different from mpv which
|
||||
# uses 01:10:00 / 01:20:00
|
||||
|
||||
import math
|
||||
|
||||
def seek():
|
||||
mp.commandv('show-text',
|
||||
format(mp.get_property_number("time-pos")) + " / " + format(mp.get_property_number("duration")))
|
||||
|
||||
def format(f):
|
||||
sec = round(f)
|
||||
|
||||
if sec < 0:
|
||||
sec = 0
|
||||
|
||||
pos_min_floor = math.floor(sec / 60)
|
||||
sec_rest = sec - pos_min_floor * 60
|
||||
return add_zero(pos_min_floor) + ":" + add_zero(sec_rest)
|
||||
|
||||
def add_zero(val):
|
||||
val = round(val)
|
||||
return "" + str(int(val)) if (val > 9) else "0" + str(int(val))
|
||||
|
||||
mp.register_event("seek", seek) # or use: mp.Seek += seek
|
||||
```
|
||||
|
||||
### Changes
|
||||
|
||||
### 1.1
|
||||
|
||||
- added support for Python scripting via IronPython
|
||||
- show tracks and show playlist didn't work because the duration wasn't defined in the key bindings
|
||||
|
||||
### 1.0
|
||||
|
||||
- much more feature packed context menu
|
||||
|
||||
@@ -14,8 +14,8 @@ namespace RatingAddon
|
||||
|
||||
public RatingAddon()
|
||||
{
|
||||
mpv.ClientMessage += mpv_ClientMessage;
|
||||
mpv.Shutdown += mpv_Shutdown;
|
||||
mp.ClientMessage += mpv_ClientMessage;
|
||||
mp.Shutdown += mpv_Shutdown;
|
||||
}
|
||||
|
||||
private void mpv_Shutdown()
|
||||
@@ -51,8 +51,8 @@ namespace RatingAddon
|
||||
if (args?.Length != 2 || args[0] != "rate-file" || ! int.TryParse(args[1], out rating))
|
||||
return;
|
||||
|
||||
Dic[mpv.GetStringProp("path")] = rating;
|
||||
mpv.Command("show-text", $"Rating: {rating}");
|
||||
Dic[mp.GetStringProp("path")] = rating;
|
||||
mp.Command("show-text", $"Rating: {rating}");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -67,10 +67,6 @@
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="mpvnet">
|
||||
<HintPath>..\mpv.net\bin\Debug\mpvnet.exe</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.ComponentModel.Composition" />
|
||||
<Reference Include="System.Core" />
|
||||
@@ -85,5 +81,12 @@
|
||||
<Compile Include="RatingAddon.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\mpv.net\mpv.net.csproj">
|
||||
<Project>{1751f378-8edf-4b62-be6d-304c7c287089}</Project>
|
||||
<Name>mpv.net</Name>
|
||||
<Private>False</Private>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
||||
@@ -1,31 +0,0 @@
|
||||
// when seeking displays position and
|
||||
// duration like so: 00:00 / 120:00
|
||||
// this is different from MPC which
|
||||
// uses 00:00:00 / 02:00:00
|
||||
|
||||
function add_zero(val)
|
||||
{
|
||||
val = Math.round(val);
|
||||
return val > 9 ? "" + val : "0" + val;
|
||||
}
|
||||
|
||||
function format(val)
|
||||
{
|
||||
var sec = Math.round(val);
|
||||
|
||||
if (sec < 0)
|
||||
sec = 0;
|
||||
|
||||
pos_min_floor = Math.floor(sec / 60);
|
||||
sec_rest = sec - pos_min_floor * 60;
|
||||
return add_zero(pos_min_floor) + ":" + add_zero(sec_rest);
|
||||
}
|
||||
|
||||
function on_seek(_)
|
||||
{
|
||||
mp.commandv("show-text",
|
||||
format(mp.get_property_number("time-pos")) + " / " +
|
||||
format(mp.get_property_number("duration")));
|
||||
}
|
||||
|
||||
mp.register_event("seek", on_seek);
|
||||
@@ -4,10 +4,6 @@ Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
VisualStudioVersion = 15.0.26730.8
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "mpv.net", "mpv.net\mpv.net.csproj", "{1751F378-8EDF-4B62-BE6D-304C7C287089}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{55C88710-539D-4402-84C8-31694841C731} = {55C88710-539D-4402-84C8-31694841C731}
|
||||
{71808A87-8B1C-4DF8-957C-D79C3B164CCA} = {71808A87-8B1C-4DF8-957C-D79C3B164CCA}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RatingAddon", "RatingAddon\RatingAddon.csproj", "{55C88710-539D-4402-84C8-31694841C731}"
|
||||
EndProject
|
||||
|
||||
@@ -28,7 +28,7 @@ namespace mpvnet
|
||||
foreach (string i in Directory.GetDirectories(dir))
|
||||
catalog.Catalogs.Add(new DirectoryCatalog(i, "*Addon.dll"));
|
||||
|
||||
dir = mpv.mpvConfFolderPath + "\\Addons";
|
||||
dir = mp.mpvConfFolderPath + "\\Addons";
|
||||
|
||||
if (Directory.Exists(dir))
|
||||
foreach (string i in Directory.GetDirectories(dir))
|
||||
|
||||
@@ -50,41 +50,41 @@ namespace mpvnet
|
||||
d.Filter = Misc.GetFilter(Misc.FileTypes);
|
||||
|
||||
if (d.ShowDialog() == DialogResult.OK)
|
||||
mpv.LoadFiles(d.FileNames);
|
||||
mp.LoadFiles(d.FileNames);
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
public static void open_config_folder(string[] args)
|
||||
{
|
||||
Process.Start(mpv.mpvConfFolderPath);
|
||||
Process.Start(mp.mpvConfFolderPath);
|
||||
}
|
||||
|
||||
public static void show_keys(string[] args)
|
||||
{
|
||||
Process.Start(mpv.InputConfPath);
|
||||
Process.Start(mp.InputConfPath);
|
||||
}
|
||||
|
||||
private static void CreateMpvConf()
|
||||
{
|
||||
if (!File.Exists(mpv.mpvConfPath))
|
||||
if (!File.Exists(mp.mpvConfPath))
|
||||
{
|
||||
if (!Directory.Exists(mpv.mpvConfFolderPath))
|
||||
Directory.CreateDirectory(mpv.mpvConfFolderPath);
|
||||
if (!Directory.Exists(mp.mpvConfFolderPath))
|
||||
Directory.CreateDirectory(mp.mpvConfFolderPath);
|
||||
|
||||
File.WriteAllText(mpv.mpvConfPath, "# https://mpv.io/manual/master/#configuration-files");
|
||||
File.WriteAllText(mp.mpvConfPath, "# https://mpv.io/manual/master/#configuration-files");
|
||||
}
|
||||
}
|
||||
|
||||
public static void show_prefs(string[] args)
|
||||
{
|
||||
CreateMpvConf();
|
||||
Process.Start(mpv.mpvConfPath);
|
||||
Process.Start(mp.mpvConfPath);
|
||||
}
|
||||
|
||||
public static void history(string[] args)
|
||||
{
|
||||
var fp = mpv.mpvConfFolderPath + "history.txt";
|
||||
var fp = mp.mpvConfFolderPath + "history.txt";
|
||||
|
||||
if (File.Exists(fp))
|
||||
Process.Start(fp);
|
||||
@@ -103,7 +103,7 @@ namespace mpvnet
|
||||
CreateMpvConf();
|
||||
|
||||
bool changed = false;
|
||||
string fp = mpv.mpvConfPath;
|
||||
string fp = mp.mpvConfPath;
|
||||
var confLines = File.ReadAllLines(fp);
|
||||
|
||||
for (int i = 0; i < confLines.Length; i++)
|
||||
@@ -130,21 +130,21 @@ namespace mpvnet
|
||||
|
||||
public static void show_info(string[] args)
|
||||
{
|
||||
var fi = new FileInfo(mpv.GetStringProp("path"));
|
||||
var fi = new FileInfo(mp.GetStringProp("path"));
|
||||
|
||||
using (var mi = new MediaInfo(fi.FullName))
|
||||
{
|
||||
var w = mi.GetInfo(MediaInfoStreamKind.Video, "Width");
|
||||
var h = mi.GetInfo(MediaInfoStreamKind.Video, "Height");
|
||||
var pos = TimeSpan.FromSeconds(mpv.GetIntProp("time-pos"));
|
||||
var dur = TimeSpan.FromSeconds(mpv.GetIntProp("duration"));
|
||||
var pos = TimeSpan.FromSeconds(mp.GetIntProp("time-pos"));
|
||||
var dur = TimeSpan.FromSeconds(mp.GetIntProp("duration"));
|
||||
string mibr = mi.GetInfo(MediaInfoStreamKind.Video, "BitRate");
|
||||
|
||||
if (mibr == "")
|
||||
mibr = "0";
|
||||
|
||||
var br = Convert.ToInt32(mibr) / 1000.0 / 1000.0;
|
||||
var vf = mpv.GetStringProp("video-format").ToUpper();
|
||||
var vf = mp.GetStringProp("video-format").ToUpper();
|
||||
var fn = fi.Name;
|
||||
|
||||
if (fn.Length > 60)
|
||||
@@ -158,7 +158,7 @@ namespace mpvnet
|
||||
((int)(fi.Length / 1024 / 1024)).ToString() +
|
||||
$" MB - {w} x {h}\n{vf} - {br.ToString("f1")} Mb/s" + "\n" + fn;
|
||||
|
||||
mpv.Command("show-text", info, "5000");
|
||||
mp.Command("show-text", info, "5000");
|
||||
|
||||
string FormatTime(double value) => ((int)(Math.Floor(value))).ToString("00");
|
||||
}
|
||||
|
||||
BIN
mpv.net/IronPython/IKVM.Reflection.dll
Normal file
BIN
mpv.net/IronPython/IKVM.Reflection.dll
Normal file
Binary file not shown.
BIN
mpv.net/IronPython/IronPython.Modules.dll
Normal file
BIN
mpv.net/IronPython/IronPython.Modules.dll
Normal file
Binary file not shown.
BIN
mpv.net/IronPython/IronPython.dll
Normal file
BIN
mpv.net/IronPython/IronPython.dll
Normal file
Binary file not shown.
BIN
mpv.net/IronPython/IronPythonAddon.dll
Normal file
BIN
mpv.net/IronPython/IronPythonAddon.dll
Normal file
Binary file not shown.
BIN
mpv.net/IronPython/Microsoft.Dynamic.dll
Normal file
BIN
mpv.net/IronPython/Microsoft.Dynamic.dll
Normal file
Binary file not shown.
BIN
mpv.net/IronPython/Microsoft.Scripting.dll
Normal file
BIN
mpv.net/IronPython/Microsoft.Scripting.dll
Normal file
Binary file not shown.
1
mpv.net/MainForm.Designer.cs
generated
1
mpv.net/MainForm.Designer.cs
generated
@@ -52,7 +52,6 @@
|
||||
this.Name = "MainForm";
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
|
||||
this.Text = "mpv.net";
|
||||
this.Load += new System.EventHandler(this.MainForm_Load);
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading;
|
||||
using System.Windows.Forms;
|
||||
|
||||
using System.Diagnostics;
|
||||
using static mpvnet.StaticUsing;
|
||||
|
||||
namespace mpvnet
|
||||
@@ -16,7 +16,7 @@ namespace mpvnet
|
||||
|
||||
private Point LastCursorPosChanged;
|
||||
private int LastCursorChangedTickCount;
|
||||
private bool IsCloseRequired = true;
|
||||
private bool IsClosed;
|
||||
|
||||
public ContextMenuStripEx CMS;
|
||||
|
||||
@@ -30,7 +30,7 @@ namespace mpvnet
|
||||
SetFormPosSize();
|
||||
Instance = this;
|
||||
Hwnd = Handle;
|
||||
ChangeFullscreen((mpv.mpvConv.ContainsKey("fullscreen") && mpv.mpvConv["fullscreen"] == "yes") || (mpv.mpvConv.ContainsKey("fs") && mpv.mpvConv["fs"] == "yes"));
|
||||
ChangeFullscreen((mp.mpvConv.ContainsKey("fullscreen") && mp.mpvConv["fullscreen"] == "yes") || (mp.mpvConv.ContainsKey("fs") && mp.mpvConv["fs"] == "yes"));
|
||||
CMS = new ContextMenuStripEx(components);
|
||||
CMS.Opened += CMS_Opened;
|
||||
ContextMenuStrip = CMS;
|
||||
@@ -44,15 +44,15 @@ namespace mpvnet
|
||||
|
||||
public void BuildMenu()
|
||||
{
|
||||
if (!File.Exists(mpv.InputConfPath))
|
||||
if (!File.Exists(mp.InputConfPath))
|
||||
{
|
||||
if (!Directory.Exists(mpv.mpvConfFolderPath))
|
||||
Directory.CreateDirectory(mpv.mpvConfFolderPath);
|
||||
if (!Directory.Exists(mp.mpvConfFolderPath))
|
||||
Directory.CreateDirectory(mp.mpvConfFolderPath);
|
||||
|
||||
File.WriteAllText(mpv.InputConfPath, Properties.Resources.input_conf);
|
||||
File.WriteAllText(mp.InputConfPath, Properties.Resources.input_conf);
|
||||
}
|
||||
|
||||
foreach (var i in File.ReadAllText(mpv.InputConfPath).SplitLinesNoEmpty())
|
||||
foreach (var i in File.ReadAllText(mp.InputConfPath).SplitLinesNoEmpty())
|
||||
{
|
||||
if (!i.Contains("#menu:"))
|
||||
continue;
|
||||
@@ -73,7 +73,7 @@ namespace mpvnet
|
||||
var menuItem = CMS.Add(path, () => {
|
||||
try
|
||||
{
|
||||
mpv.CommandString(cmd, false);
|
||||
mp.CommandString(cmd, false);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -93,11 +93,11 @@ namespace mpvnet
|
||||
|
||||
private string LastHistory;
|
||||
|
||||
private void mpv_PlaybackRestart()
|
||||
private void mp_PlaybackRestart()
|
||||
{
|
||||
var fn = mpv.GetStringProp("filename");
|
||||
var fn = mp.GetStringProp("filename");
|
||||
BeginInvoke(new Action(() => { Text = fn + " - mpv.net " + Application.ProductVersion; }));
|
||||
var fp = mpv.mpvConfFolderPath + "history.txt";
|
||||
var fp = mp.mpvConfFolderPath + "history.txt";
|
||||
|
||||
if (LastHistory != fn && File.Exists(fp))
|
||||
{
|
||||
@@ -121,14 +121,14 @@ namespace mpvnet
|
||||
MsgError(e.ToString());
|
||||
}
|
||||
|
||||
private void Mpv_VideoSizeChanged()
|
||||
private void mp_VideoSizeChanged()
|
||||
{
|
||||
BeginInvoke(new Action(() => SetFormPosSize()));
|
||||
}
|
||||
|
||||
private void Mpv_AfterShutdown()
|
||||
private void mp_Shutdown()
|
||||
{
|
||||
if (IsCloseRequired)
|
||||
if (!IsClosed)
|
||||
Invoke(new Action(() => Close()));
|
||||
}
|
||||
|
||||
@@ -137,7 +137,7 @@ namespace mpvnet
|
||||
get => WindowState == FormWindowState.Maximized;
|
||||
}
|
||||
|
||||
void MpvChangeFullscreen(bool value)
|
||||
void mp_ChangeFullscreen(bool value)
|
||||
{
|
||||
BeginInvoke(new Action(() => ChangeFullscreen(value)));
|
||||
}
|
||||
@@ -166,19 +166,19 @@ namespace mpvnet
|
||||
case 0x0100: // WM_KEYDOWN
|
||||
case 0x0101: // WM_KEYUP
|
||||
case 0x020A: // WM_MOUSEWHEEL
|
||||
if (mpv.MpvWindowHandle != IntPtr.Zero)
|
||||
Native.SendMessage(mpv.MpvWindowHandle, m.Msg, m.WParam, m.LParam);
|
||||
if (mp.MpvWindowHandle != IntPtr.Zero)
|
||||
Native.SendMessage(mp.MpvWindowHandle, m.Msg, m.WParam, m.LParam);
|
||||
break;
|
||||
case 0x203: // Native.WM.LBUTTONDBLCLK
|
||||
if (!IsMouseInOSC())
|
||||
mpv.CommandString("cycle fullscreen");
|
||||
mp.CommandString("cycle fullscreen");
|
||||
break;
|
||||
case 0x0214: // WM_SIZING
|
||||
var rc = Marshal.PtrToStructure<Native.RECT>(m.LParam);
|
||||
var r = rc;
|
||||
NativeHelp.SubtractWindowBorders(Handle, ref r);
|
||||
int c_w = r.Right - r.Left, c_h = r.Bottom - r.Top;
|
||||
float aspect = mpv.VideoSize.Width / (float)mpv.VideoSize.Height;
|
||||
float aspect = mp.VideoSize.Width / (float)mp.VideoSize.Height;
|
||||
int d_w = (int)(c_h * aspect - c_w);
|
||||
int d_h = (int)(c_w / aspect - c_h);
|
||||
int[] d_corners = { d_w, d_h, -d_w, -d_h };
|
||||
@@ -198,10 +198,10 @@ namespace mpvnet
|
||||
|
||||
void SetFormPosSize()
|
||||
{
|
||||
if (IsFullscreen || mpv.VideoSize.Width == 0) return;
|
||||
if (IsFullscreen || mp.VideoSize.Width == 0) return;
|
||||
var wa = Screen.GetWorkingArea(this);
|
||||
int h = (int)(wa.Height * 0.6);
|
||||
int w = (int)(h * mpv.VideoSize.Width / (float)mpv.VideoSize.Height);
|
||||
int w = (int)(h * mp.VideoSize.Width / (float)mp.VideoSize.Height);
|
||||
Point middlePos = new Point(Left + Width / 2, Top + Height / 2);
|
||||
var r = new Native.RECT(new Rectangle(0, 0, w, h));
|
||||
NativeHelp.AddWindowBorders(Handle, ref r);
|
||||
@@ -227,7 +227,7 @@ namespace mpvnet
|
||||
base.OnDragDrop(e);
|
||||
|
||||
if (e.Data.GetDataPresent(DataFormats.FileDrop))
|
||||
mpv.LoadFiles(e.Data.GetData(DataFormats.FileDrop) as String[]);
|
||||
mp.LoadFiles(e.Data.GetData(DataFormats.FileDrop) as String[]);
|
||||
}
|
||||
|
||||
protected override void OnMouseDown(MouseEventArgs e)
|
||||
@@ -249,7 +249,7 @@ namespace mpvnet
|
||||
var p2 = PointToScreen(e.Location);
|
||||
|
||||
if (Math.Abs(p1.X - p2.X) < 10 && Math.Abs(p1.Y - p2.Y) < 10)
|
||||
mpv.Command("quit");
|
||||
mp.Command("quit");
|
||||
}
|
||||
|
||||
protected override void OnMouseMove(MouseEventArgs e)
|
||||
@@ -257,19 +257,12 @@ namespace mpvnet
|
||||
base.OnMouseMove(e);
|
||||
|
||||
// send mouse command to make OSC show
|
||||
mpv.CommandString($"mouse {e.X} {e.Y}");
|
||||
mp.CommandString($"mouse {e.X} {e.Y}");
|
||||
|
||||
if (CursorHelp.IsPosDifferent(LastCursorPosChanged))
|
||||
CursorHelp.Show();
|
||||
}
|
||||
|
||||
protected override void OnFormClosed(FormClosedEventArgs e)
|
||||
{
|
||||
base.OnFormClosed(e);
|
||||
IsCloseRequired = false;
|
||||
mpv.Command("quit");
|
||||
}
|
||||
|
||||
bool IsMouseInOSC()
|
||||
{
|
||||
return PointToClient(Control.MousePosition).Y > ClientSize.Height * 0.9;
|
||||
@@ -290,13 +283,27 @@ namespace mpvnet
|
||||
}
|
||||
}
|
||||
|
||||
private void MainForm_Load(object sender, EventArgs ea)
|
||||
protected override void OnLoad(EventArgs e)
|
||||
{
|
||||
mpv.Init();
|
||||
mpv.ObserveBoolProp("fullscreen", MpvChangeFullscreen);
|
||||
mpv.AfterShutdown += Mpv_AfterShutdown;
|
||||
mpv.VideoSizeChanged += Mpv_VideoSizeChanged;
|
||||
mpv.PlaybackRestart += mpv_PlaybackRestart;
|
||||
base.OnLoad(e);
|
||||
mp.Init();
|
||||
mp.ObserveBoolProp("fullscreen", mp_ChangeFullscreen);
|
||||
mp.Shutdown += mp_Shutdown;
|
||||
mp.VideoSizeChanged += mp_VideoSizeChanged;
|
||||
mp.PlaybackRestart += mp_PlaybackRestart;
|
||||
}
|
||||
|
||||
protected override void OnFormClosed(FormClosedEventArgs e)
|
||||
{
|
||||
base.OnFormClosed(e);
|
||||
IsClosed = true;
|
||||
mp.Command("quit");
|
||||
|
||||
for (int i = 0; i < 99; i++)
|
||||
{
|
||||
if (mp.IsShutdownComplete) break;
|
||||
Thread.Sleep(50);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
[assembly: AssemblyVersion("1.1.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.1.0.0")]
|
||||
|
||||
33
mpv.net/PyScript.cs
Normal file
33
mpv.net/PyScript.cs
Normal file
@@ -0,0 +1,33 @@
|
||||
using System;
|
||||
|
||||
using IronPython.Hosting;
|
||||
using Microsoft.Scripting.Hosting;
|
||||
|
||||
using static mpvnet.StaticUsing;
|
||||
|
||||
namespace mpvnet
|
||||
{
|
||||
public class PyScript
|
||||
{
|
||||
ScriptEngine engine;
|
||||
ScriptScope scope;
|
||||
|
||||
public PyScript(string code)
|
||||
{
|
||||
try
|
||||
{
|
||||
engine = Python.CreateEngine();
|
||||
scope = engine.CreateScope();
|
||||
scope.ImportModule("clr");
|
||||
engine.Execute("import clr", scope);
|
||||
engine.Execute("clr.AddReference(\"mpvnet\")", scope);
|
||||
engine.Execute("from mpvnet import *", scope);
|
||||
engine.Execute(code, scope);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MsgError(ex.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -104,7 +104,7 @@
|
||||
k script-message mpv.net show-keys #menu: K ; Settings > Show Keys
|
||||
c script-message mpv.net open-config-folder #menu: C ; Settings > Open Config Folder
|
||||
|
||||
i show-progress ; script-message mpv.net show-info #menu: I ; Tools | Info
|
||||
i script-message mpv.net show-info #menu: I ; Tools | Info
|
||||
t script-binding stats/display-stats #menu: T ; Tools > Show Statistics
|
||||
T script-binding stats/display-stats-toggle #menu: Shift+T ; Tools > Toggle Statistics
|
||||
_ ignore #menu: _ ; Tools > -
|
||||
@@ -113,8 +113,8 @@
|
||||
L cycle-values loop-file "inf" "no" #menu: Shift+L ; Tools > Toggle Infinite Looping
|
||||
DEL script-binding osc/visibility #menu: Delete ; Tools > Toggle OSC Visibility
|
||||
Ctrl+H cycle-values hwdec "auto" "no" #menu: Ctrl+H ; Tools > Cycle Hardware Decoding
|
||||
F8 show_text ${playlist} #menu: F8 ; Tools > Show Playlist
|
||||
F9 show_text ${track-list} #menu: F9 ; Tools > Show Audio/Video/Subtitle List
|
||||
F8 show-text ${playlist} 5000 #menu: F8 ; Tools > Show Playlist
|
||||
F9 show-text ${track-list} 5000 #menu: F9 ; Tools > Show Audio/Video/Subtitle List
|
||||
|
||||
_ script-message mpv.net shell-execute https://mpv.io/manual/stable/ #menu: _ ; Tools > Web > Show mpv manual
|
||||
_ script-message mpv.net shell-execute https://github.com/mpv-player/mpv/blob/master/etc/input.conf #menu: _ ; Tools > Web > Show mpv default keys
|
||||
|
||||
@@ -29,6 +29,9 @@ namespace mpvnet
|
||||
[DllImport("mpv-1.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern int mpv_get_property(IntPtr mpvHandle, byte[] name, mpv_format format, ref 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);
|
||||
|
||||
@@ -102,7 +105,8 @@ namespace mpvnet
|
||||
MPV_EVENT_PLAYBACK_RESTART = 21,
|
||||
MPV_EVENT_PROPERTY_CHANGE = 22,
|
||||
MPV_EVENT_CHAPTER_CHANGE = 23,
|
||||
MPV_EVENT_QUEUE_OVERFLOW = 24
|
||||
MPV_EVENT_QUEUE_OVERFLOW = 24,
|
||||
MPV_EVENT_HOOK = 25
|
||||
}
|
||||
|
||||
public enum mpv_format
|
||||
@@ -131,6 +135,15 @@ namespace mpvnet
|
||||
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
|
||||
{
|
||||
@@ -159,9 +172,16 @@ namespace mpvnet
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct mpv_event_property
|
||||
{
|
||||
[MarshalAs(UnmanagedType.LPUTF8Str)] public string name;
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,37 +1,67 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
using static mpvnet.libmpv;
|
||||
using static mpvnet.Native;
|
||||
using static mpvnet.StaticUsing;
|
||||
|
||||
using PyRT = IronPython.Runtime;
|
||||
|
||||
namespace mpvnet
|
||||
{
|
||||
public delegate void MpvBoolPropChangeHandler(string propName, bool value);
|
||||
|
||||
public class mpv
|
||||
public class mp
|
||||
{
|
||||
public static event Action<string[]> ClientMessage;
|
||||
public static event Action Shutdown;
|
||||
public static event Action AfterShutdown;
|
||||
public static event Action PlaybackRestart;
|
||||
public static event Action VideoSizeChanged;
|
||||
// Lua/JS evens libmpv events
|
||||
|
||||
// MPV_EVENT_NONE
|
||||
public static event Action Shutdown; // shutdown MPV_EVENT_SHUTDOWN
|
||||
public static event Action LogMessage; // log-message MPV_EVENT_LOG_MESSAGE
|
||||
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 CommandReply; // command-reply MPV_EVENT_COMMAND_REPLY
|
||||
public static event Action StartFile; // start-file MPV_EVENT_START_FILE
|
||||
public static event Action<EndFileEventMode> EndFile; // end-file MPV_EVENT_END_FILE
|
||||
public static event Action FileLoaded; // file-loaded MPV_EVENT_FILE_LOADED
|
||||
public static event Action TracksChanged; // MPV_EVENT_TRACKS_CHANGED
|
||||
public static event Action TrackSwitched; // MPV_EVENT_TRACK_SWITCHED
|
||||
public static event Action Idle; // idle MPV_EVENT_IDLE
|
||||
public static event Action Pause; // MPV_EVENT_PAUSE
|
||||
public static event Action Unpause; // MPV_EVENT_UNPAUSE
|
||||
public static event Action Tick; // tick MPV_EVENT_TICK
|
||||
public static event Action ScriptInputDispatch; // MPV_EVENT_SCRIPT_INPUT_DISPATCH
|
||||
public static event Action<string[]> ClientMessage; // client-message MPV_EVENT_CLIENT_MESSAGE
|
||||
public static event Action VideoReconfig; // video-reconfig MPV_EVENT_VIDEO_RECONFIG
|
||||
public static event Action AudioReconfig; // audio-reconfig MPV_EVENT_AUDIO_RECONFIG
|
||||
public static event Action MetadataUpdate; // MPV_EVENT_METADATA_UPDATE
|
||||
public static event Action Seek; // seek MPV_EVENT_SEEK
|
||||
public static event Action PlaybackRestart; // playback-restart MPV_EVENT_PLAYBACK_RESTART
|
||||
// MPV_EVENT_PROPERTY_CHANGE
|
||||
public static event Action ChapterChange; // MPV_EVENT_CHAPTER_CHANGE
|
||||
public static event Action QueueOverflow; // MPV_EVENT_QUEUE_OVERFLOW
|
||||
public static event Action Hook; // MPV_EVENT_HOOK
|
||||
|
||||
public static IntPtr MpvHandle;
|
||||
public static IntPtr MpvWindowHandle;
|
||||
public static Addon Addon;
|
||||
public static List<Action<bool>> BoolPropChangeActions = new List<Action<bool>>();
|
||||
public static List<KeyValuePair<string, Action<bool>>> BoolPropChangeActions = new List<KeyValuePair<string, Action<bool>>>();
|
||||
public static Size VideoSize = new Size(1920, 1080);
|
||||
public static string mpvConfFolderPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\mpv\\";
|
||||
public static string InputConfPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\mpv\\input.conf";
|
||||
public static string mpvConfPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\mpv\\mpv.conf";
|
||||
public static List<PyScript> PyScripts { get; } = new List<PyScript>();
|
||||
public static bool IsShutdownComplete { get; set; }
|
||||
|
||||
private static Dictionary<string, string> _mpvConv;
|
||||
|
||||
@@ -76,17 +106,34 @@ namespace mpvnet
|
||||
SetStringProp("force-window", "yes");
|
||||
mpv_initialize(MpvHandle);
|
||||
ProcessCommandLine();
|
||||
Task.Run(() => { LoadScripts(); });
|
||||
Task.Run(() => { Addon = new Addon(); });
|
||||
Task.Run(() => { EventLoop(); });
|
||||
}
|
||||
|
||||
public static void LoadScripts()
|
||||
{
|
||||
string[] jsLua = { ".lua", ".js" };
|
||||
string[] startupScripts = Directory.GetFiles(Application.StartupPath + "\\Scripts");
|
||||
|
||||
foreach (var scriptPath in startupScripts)
|
||||
if (jsLua.Contains(Path.GetExtension(scriptPath).ToLower()))
|
||||
mp.Command("load-script", $"{scriptPath}");
|
||||
|
||||
foreach (var scriptPath in startupScripts)
|
||||
if (Path.GetExtension(scriptPath) == ".py")
|
||||
PyScripts.Add(new PyScript(File.ReadAllText(scriptPath)));
|
||||
|
||||
foreach(var scriptPath in Directory.GetFiles(mp.mpvConfFolderPath + "scripts", "*.py"))
|
||||
PyScripts.Add(new PyScript(File.ReadAllText(scriptPath)));
|
||||
}
|
||||
|
||||
public static void EventLoop()
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
IntPtr ptr = mpv_wait_event(MpvHandle, -1);
|
||||
mpv_event evt = (mpv_event)Marshal.PtrToStructure(ptr, typeof(mpv_event));
|
||||
Debug.WriteLine(evt.event_id);
|
||||
|
||||
if (MpvWindowHandle == IntPtr.Zero)
|
||||
MpvWindowHandle = FindWindowEx(MainForm.Hwnd, IntPtr.Zero, "mpv", null);
|
||||
@@ -95,22 +142,51 @@ namespace mpvnet
|
||||
{
|
||||
case mpv_event_id.MPV_EVENT_SHUTDOWN:
|
||||
Shutdown?.Invoke();
|
||||
AfterShutdown?.Invoke();
|
||||
IsShutdownComplete = true;
|
||||
return;
|
||||
case mpv_event_id.MPV_EVENT_LOG_MESSAGE:
|
||||
LogMessage?.Invoke();
|
||||
break;
|
||||
case mpv_event_id.MPV_EVENT_GET_PROPERTY_REPLY:
|
||||
GetPropertyReply?.Invoke();
|
||||
break;
|
||||
case mpv_event_id.MPV_EVENT_SET_PROPERTY_REPLY:
|
||||
SetPropertyReply?.Invoke();
|
||||
break;
|
||||
case mpv_event_id.MPV_EVENT_COMMAND_REPLY:
|
||||
CommandReply?.Invoke();
|
||||
break;
|
||||
case mpv_event_id.MPV_EVENT_START_FILE:
|
||||
StartFile?.Invoke();
|
||||
break;
|
||||
case mpv_event_id.MPV_EVENT_END_FILE:
|
||||
var end_fileData = (mpv_event_end_file)Marshal.PtrToStructure(evt.data, typeof(mpv_event_end_file));
|
||||
EndFile?.Invoke((EndFileEventMode)end_fileData.reason);
|
||||
break;
|
||||
case mpv_event_id.MPV_EVENT_FILE_LOADED:
|
||||
FileLoaded?.Invoke();
|
||||
LoadFolder();
|
||||
break;
|
||||
case mpv_event_id.MPV_EVENT_PLAYBACK_RESTART:
|
||||
PlaybackRestart?.Invoke();
|
||||
|
||||
Size s = new Size(GetIntProp("dwidth", false), GetIntProp("dheight", false));
|
||||
|
||||
if (VideoSize != s && s != Size.Empty)
|
||||
{
|
||||
VideoSize = s;
|
||||
VideoSizeChanged?.Invoke();
|
||||
}
|
||||
|
||||
case mpv_event_id.MPV_EVENT_TRACKS_CHANGED:
|
||||
TracksChanged?.Invoke();
|
||||
break;
|
||||
case mpv_event_id.MPV_EVENT_TRACK_SWITCHED:
|
||||
TrackSwitched?.Invoke();
|
||||
break;
|
||||
case mpv_event_id.MPV_EVENT_IDLE:
|
||||
Idle?.Invoke();
|
||||
break;
|
||||
case mpv_event_id.MPV_EVENT_PAUSE:
|
||||
Pause?.Invoke();
|
||||
break;
|
||||
case mpv_event_id.MPV_EVENT_UNPAUSE:
|
||||
Unpause?.Invoke();
|
||||
break;
|
||||
case mpv_event_id.MPV_EVENT_TICK:
|
||||
Tick?.Invoke();
|
||||
break;
|
||||
case mpv_event_id.MPV_EVENT_SCRIPT_INPUT_DISPATCH:
|
||||
ScriptInputDispatch?.Invoke();
|
||||
break;
|
||||
case mpv_event_id.MPV_EVENT_CLIENT_MESSAGE:
|
||||
if (ClientMessage != null)
|
||||
@@ -129,22 +205,122 @@ namespace mpvnet
|
||||
{
|
||||
MsgError(ex.GetType().Name + "\r\n\r\n" + ex.ToString());
|
||||
}
|
||||
|
||||
ClientMessage?.Invoke(args);
|
||||
}
|
||||
|
||||
break;
|
||||
case mpv_event_id.MPV_EVENT_VIDEO_RECONFIG:
|
||||
VideoReconfig?.Invoke();
|
||||
break;
|
||||
case mpv_event_id.MPV_EVENT_AUDIO_RECONFIG:
|
||||
AudioReconfig?.Invoke();
|
||||
break;
|
||||
case mpv_event_id.MPV_EVENT_METADATA_UPDATE:
|
||||
MetadataUpdate?.Invoke();
|
||||
break;
|
||||
case mpv_event_id.MPV_EVENT_SEEK:
|
||||
Seek?.Invoke();
|
||||
break;
|
||||
case mpv_event_id.MPV_EVENT_PROPERTY_CHANGE:
|
||||
var eventData = (mpv_event_property)Marshal.PtrToStructure(evt.data, typeof(mpv_event_property));
|
||||
var event_propertyData = (mpv_event_property)Marshal.PtrToStructure(evt.data, typeof(mpv_event_property));
|
||||
|
||||
if (eventData.format == mpv_format.MPV_FORMAT_FLAG)
|
||||
foreach (var action in BoolPropChangeActions)
|
||||
action.Invoke(Marshal.PtrToStructure<int>(eventData.data) == 1);
|
||||
if (event_propertyData.format == mpv_format.MPV_FORMAT_FLAG)
|
||||
foreach (var i in BoolPropChangeActions)
|
||||
if (i.Key== event_propertyData.name)
|
||||
i.Value.Invoke(Marshal.PtrToStructure<int>(event_propertyData.data) == 1);
|
||||
break;
|
||||
case mpv_event_id.MPV_EVENT_PLAYBACK_RESTART:
|
||||
PlaybackRestart?.Invoke();
|
||||
Size s = new Size(GetIntProp("dwidth", false), GetIntProp("dheight", false));
|
||||
|
||||
if (VideoSize != s && s != Size.Empty)
|
||||
{
|
||||
VideoSize = s;
|
||||
VideoSizeChanged?.Invoke();
|
||||
}
|
||||
break;
|
||||
case mpv_event_id.MPV_EVENT_CHAPTER_CHANGE:
|
||||
ChapterChange?.Invoke();
|
||||
break;
|
||||
case mpv_event_id.MPV_EVENT_QUEUE_OVERFLOW:
|
||||
QueueOverflow?.Invoke();
|
||||
break;
|
||||
case mpv_event_id.MPV_EVENT_HOOK:
|
||||
Hook?.Invoke();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class EventObject
|
||||
{
|
||||
public PyRT.PythonFunction PythonFunction { get; set; }
|
||||
public EventInfo EventInfo { get; set; }
|
||||
public Delegate Delegate { get; set; }
|
||||
|
||||
public void Invoke()
|
||||
{
|
||||
PyRT.Operations.PythonCalls.Call(PythonFunction);
|
||||
}
|
||||
|
||||
public void InvokeEndFileEventMode(EndFileEventMode arg)
|
||||
{
|
||||
PyRT.Operations.PythonCalls.Call(PythonFunction, new[] { arg });
|
||||
}
|
||||
|
||||
public void InvokeStrings(string[] arg)
|
||||
{
|
||||
PyRT.Operations.PythonCalls.Call(PythonFunction, new[] { arg });
|
||||
}
|
||||
}
|
||||
|
||||
private static List<EventObject> EventObjects = new List<EventObject>();
|
||||
|
||||
public static void register_event(string name, PyRT.PythonFunction pyFunc)
|
||||
{
|
||||
foreach (var eventInfo in typeof(mp).GetEvents())
|
||||
{
|
||||
if (eventInfo.Name.ToLower() == name.Replace("-", ""))
|
||||
{
|
||||
EventObject eventObject = new EventObject();
|
||||
EventObjects.Add(eventObject);
|
||||
eventObject.PythonFunction = pyFunc;
|
||||
MethodInfo mi;
|
||||
|
||||
if (eventInfo.EventHandlerType == typeof(Action))
|
||||
{
|
||||
mi = eventObject.GetType().GetMethod(nameof(EventObject.Invoke));
|
||||
}
|
||||
else if (eventInfo.EventHandlerType == typeof(Action<EndFileEventMode>))
|
||||
{
|
||||
mi = eventObject.GetType().GetMethod(nameof(EventObject.InvokeEndFileEventMode));
|
||||
}
|
||||
else if (eventInfo.EventHandlerType == typeof(Action<string[]>))
|
||||
{
|
||||
mi = eventObject.GetType().GetMethod(nameof(EventObject.InvokeStrings));
|
||||
}
|
||||
else
|
||||
throw new Exception();
|
||||
|
||||
eventObject.EventInfo = eventInfo;
|
||||
Delegate handler = Delegate.CreateDelegate(eventInfo.EventHandlerType, eventObject, mi);
|
||||
eventObject.Delegate = handler;
|
||||
eventInfo.AddEventHandler(eventObject, handler);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void unregister_event(PyRT.PythonFunction pyFunc)
|
||||
{
|
||||
foreach (var eventObjects in EventObjects)
|
||||
if (eventObjects.PythonFunction == pyFunc)
|
||||
eventObjects.EventInfo.RemoveEventHandler(eventObjects, eventObjects.Delegate);
|
||||
}
|
||||
|
||||
public static void commandv(params string[] args)
|
||||
{
|
||||
Command(args);
|
||||
}
|
||||
|
||||
public static void Command(params string[] args)
|
||||
{
|
||||
if (MpvHandle == IntPtr.Zero)
|
||||
@@ -208,6 +384,22 @@ namespace mpvnet
|
||||
return lpBuffer.ToInt32();
|
||||
}
|
||||
|
||||
public static double get_property_number(string name)
|
||||
{
|
||||
return GetDoubleProp(name);
|
||||
}
|
||||
|
||||
public static double GetDoubleProp(string name, bool throwException = true)
|
||||
{
|
||||
double val = 0;
|
||||
int err = mpv_get_property(MpvHandle, GetUtf8Bytes(name), mpv_format.MPV_FORMAT_DOUBLE, ref val);
|
||||
|
||||
if (err < 0 && throwException)
|
||||
throw new Exception($"{name}: {(mpv_error)err}");
|
||||
else
|
||||
return val;
|
||||
}
|
||||
|
||||
public static void SetIntProp(string name, int value)
|
||||
{
|
||||
Int64 val = value;
|
||||
@@ -219,16 +411,20 @@ namespace mpvnet
|
||||
|
||||
public static void ObserveBoolProp(string name, Action<bool> action)
|
||||
{
|
||||
BoolPropChangeActions.Add(action);
|
||||
int err = mpv_observe_property(MpvHandle, (ulong)action.GetHashCode(), name, mpv_format.MPV_FORMAT_FLAG);
|
||||
|
||||
if (err < 0)
|
||||
throw new Exception($"{name}: {(mpv_error)err}");
|
||||
else
|
||||
BoolPropChangeActions.Add(new KeyValuePair<string, Action<bool>>(name, action));
|
||||
}
|
||||
|
||||
public static void UnobserveBoolProp(string name, Action<bool> action)
|
||||
{
|
||||
BoolPropChangeActions.Remove(action);
|
||||
foreach (var i in BoolPropChangeActions.ToArray())
|
||||
if (i.Value == action)
|
||||
BoolPropChangeActions.Remove(i);
|
||||
|
||||
int err = mpv_unobserve_property(MpvHandle, (ulong)action.GetHashCode());
|
||||
|
||||
if (err < 0)
|
||||
@@ -241,9 +437,9 @@ namespace mpvnet
|
||||
|
||||
foreach (string i in args)
|
||||
if (!i.StartsWith("--") && File.Exists(i))
|
||||
mpv.Command("loadfile", i, "append");
|
||||
mp.Command("loadfile", i, "append");
|
||||
|
||||
mpv.SetStringProp("playlist-pos", "0", false);
|
||||
mp.SetStringProp("playlist-pos", "0", false);
|
||||
|
||||
foreach (string i in args)
|
||||
{
|
||||
@@ -253,27 +449,27 @@ namespace mpvnet
|
||||
{
|
||||
string left = i.Substring(2, i.IndexOf("=") - 2);
|
||||
string right = i.Substring(left.Length + 3);
|
||||
mpv.SetStringProp(left, right);
|
||||
mp.SetStringProp(left, right);
|
||||
}
|
||||
else
|
||||
mpv.SetStringProp(i.Substring(2), "yes");
|
||||
mp.SetStringProp(i.Substring(2), "yes");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void LoadFiles(string[] files)
|
||||
{
|
||||
int count = mpv.GetIntProp("playlist-count");
|
||||
int count = mp.GetIntProp("playlist-count");
|
||||
|
||||
foreach (string file in files)
|
||||
mpv.Command("loadfile", file, "append");
|
||||
mp.Command("loadfile", file, "append");
|
||||
|
||||
mpv.SetIntProp("playlist-pos", count);
|
||||
mp.SetIntProp("playlist-pos", count);
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
mpv.Command("playlist-remove", "0");
|
||||
mp.Command("playlist-remove", "0");
|
||||
|
||||
mpv.LoadFolder();
|
||||
mp.LoadFolder();
|
||||
}
|
||||
|
||||
private static bool WasFolderLoaded;
|
||||
@@ -344,4 +540,14 @@ namespace mpvnet
|
||||
|
||||
public static byte[] GetUtf8Bytes(string s) => Encoding.UTF8.GetBytes(s + "\0");
|
||||
}
|
||||
|
||||
public enum EndFileEventMode
|
||||
{
|
||||
Eof,
|
||||
Stop,
|
||||
Quit,
|
||||
Error,
|
||||
Redirect,
|
||||
Unknown
|
||||
}
|
||||
}
|
||||
@@ -94,6 +94,29 @@
|
||||
<ApplicationManifest>app.manifest</ApplicationManifest>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="IKVM.Reflection, Version=7.2.4630.5, Culture=neutral, PublicKeyToken=13235d27fcbfff58, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>IronPython\IKVM.Reflection.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="IronPython, Version=2.7.9.0, Culture=neutral, PublicKeyToken=7f709c5b713576e1, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>IronPython\IronPython.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="IronPython.Modules, Version=2.7.9.0, Culture=neutral, PublicKeyToken=7f709c5b713576e1, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>IronPython\IronPython.Modules.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="IronPythonAddon">
|
||||
<HintPath>IronPython\IronPythonAddon.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Dynamic, Version=1.2.2.0, Culture=neutral, PublicKeyToken=7f709c5b713576e1, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>IronPython\Microsoft.Dynamic.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Scripting, Version=1.2.2.0, Culture=neutral, PublicKeyToken=7f709c5b713576e1, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>IronPython\Microsoft.Scripting.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.ComponentModel.Composition" />
|
||||
<Reference Include="System.Core" />
|
||||
@@ -109,6 +132,7 @@
|
||||
<Compile Include="Menu.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Include="PyScript.cs" />
|
||||
<Compile Include="StringExtensions.cs" />
|
||||
<Compile Include="libmpv.cs" />
|
||||
<Compile Include="MainForm.cs">
|
||||
@@ -118,7 +142,7 @@
|
||||
<DependentUpon>MainForm.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Misc.cs" />
|
||||
<Compile Include="mpv.cs" />
|
||||
<Compile Include="mp.cs" />
|
||||
<Compile Include="Command.cs" />
|
||||
<Compile Include="Native.cs" />
|
||||
<Compile Include="NativeHelp.cs" />
|
||||
@@ -127,6 +151,7 @@
|
||||
<Compile Include="UI.cs" />
|
||||
<EmbeddedResource Include="MainForm.resx">
|
||||
<DependentUpon>MainForm.cs</DependentUpon>
|
||||
<SubType>Designer</SubType>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Properties\Resources.resx">
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
|
||||
@@ -3,10 +3,8 @@ $exePath = $scriptDir + "\mpv.net\bin\Debug\mpvnet.exe"
|
||||
$version = [Diagnostics.FileVersionInfo]::GetVersionInfo($exePath).FileVersion
|
||||
$desktopDir = [Environment]::GetFolderPath("Desktop")
|
||||
$targetDir = $desktopDir + "\mpv.net-" + $version
|
||||
if (Test-Path $targetDir) { rd $targetDir -recurse }
|
||||
Copy-Item $scriptDir\mpv.net\bin\Debug $targetDir -recurse
|
||||
$addonDir = $targetDir + "\Addons"
|
||||
Remove-Item $addonDir -Recurse -Include *mpvnet.exe, *mpvnet.exe.config, *mpvnet.pdb
|
||||
$7zPath = "C:\Program Files\7-Zip\7z.exe"
|
||||
$args = "a -t7z -mx9 $targetDir.7z -r $targetDir\*"
|
||||
Start-Process -FilePath $7zPath -ArgumentList $args
|
||||
BIN
screenshot.png
Normal file
BIN
screenshot.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 59 KiB |
Reference in New Issue
Block a user