This commit is contained in:
Frank Skare
2019-03-13 22:22:51 +01:00
parent 72d6f44e47
commit a392c2c6da
19 changed files with 22694 additions and 51 deletions

View File

@@ -50,6 +50,10 @@ class Script
### Changes ### Changes
### 1.?
- show tracks and show playlist didn't work because the duration wasn't defined in the key bindings
### 1.0 ### 1.0
- much more feature packed context menu - much more feature packed context menu

View File

@@ -67,10 +67,6 @@
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet> <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="mpvnet">
<HintPath>..\mpv.net\bin\Debug\mpvnet.exe</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System" /> <Reference Include="System" />
<Reference Include="System.ComponentModel.Composition" /> <Reference Include="System.ComponentModel.Composition" />
<Reference Include="System.Core" /> <Reference Include="System.Core" />
@@ -85,5 +81,11 @@
<Compile Include="RatingAddon.cs" /> <Compile Include="RatingAddon.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<ProjectReference Include="..\mpv.net\mpv.net.csproj">
<Project>{1751f378-8edf-4b62-be6d-304c7c287089}</Project>
<Name>mpv.net</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project> </Project>

View File

@@ -4,10 +4,6 @@ Microsoft Visual Studio Solution File, Format Version 12.00
VisualStudioVersion = 15.0.26730.8 VisualStudioVersion = 15.0.26730.8
MinimumVisualStudioVersion = 10.0.40219.1 MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "mpv.net", "mpv.net\mpv.net.csproj", "{1751F378-8EDF-4B62-BE6D-304C7C287089}" 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 EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RatingAddon", "RatingAddon\RatingAddon.csproj", "{55C88710-539D-4402-84C8-31694841C731}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RatingAddon", "RatingAddon\RatingAddon.csproj", "{55C88710-539D-4402-84C8-31694841C731}"
EndProject EndProject

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@@ -294,7 +294,7 @@ namespace mpvnet
{ {
mpv.Init(); mpv.Init();
mpv.ObserveBoolProp("fullscreen", MpvChangeFullscreen); mpv.ObserveBoolProp("fullscreen", MpvChangeFullscreen);
mpv.AfterShutdown += Mpv_AfterShutdown; mpv.Shutdown += Mpv_AfterShutdown;
mpv.VideoSizeChanged += Mpv_VideoSizeChanged; mpv.VideoSizeChanged += Mpv_VideoSizeChanged;
mpv.PlaybackRestart += mpv_PlaybackRestart; mpv.PlaybackRestart += mpv_PlaybackRestart;
} }

View File

@@ -1,8 +1,14 @@
using System.Collections; using System;
using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Windows.Forms; using System.Windows.Forms;
using IronPython.Hosting;
using Microsoft.Scripting.Hosting;
using static mpvnet.StaticUsing;
namespace mpvnet namespace mpvnet
{ {
public class Misc public class Misc
@@ -43,4 +49,28 @@ namespace mpvnet
return MessageBox.Show(message, Application.ProductName, MessageBoxButtons.OKCancel, MessageBoxIcon.Question); return MessageBox.Show(message, Application.ProductName, MessageBoxButtons.OKCancel, MessageBoxIcon.Question);
} }
} }
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());
}
}
}
} }

View File

@@ -113,8 +113,8 @@
L cycle-values loop-file "inf" "no" #menu: Shift+L ; Tools > Toggle Infinite Looping 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 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 Ctrl+H cycle-values hwdec "auto" "no" #menu: Ctrl+H ; Tools > Cycle Hardware Decoding
F8 show_text ${playlist} #menu: F8 ; Tools > Show Playlist F8 show-text ${playlist} 5000 #menu: F8 ; Tools > Show Playlist
F9 show_text ${track-list} #menu: F9 ; Tools > Show Audio/Video/Subtitle List 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://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 _ script-message mpv.net shell-execute https://github.com/mpv-player/mpv/blob/master/etc/input.conf #menu: _ ; Tools > Web > Show mpv default keys

View File

@@ -131,7 +131,16 @@ namespace mpvnet
MPV_LOG_LEVEL_TRACE = 70, MPV_LOG_LEVEL_TRACE = 70,
} }
[StructLayout(LayoutKind.Sequential)] 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 struct mpv_event_log_message
{ {
public string prefix; public string prefix;
@@ -159,9 +168,17 @@ namespace mpvnet
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Sequential)]
public struct mpv_event_property public struct mpv_event_property
{ {
[MarshalAs(UnmanagedType.LPUTF8Str)] public string name; [MarshalAs(UnmanagedType.LPUTF8Str)]
public string name;
public mpv_format format; public mpv_format format;
public IntPtr data; public IntPtr data;
} }
[StructLayout(LayoutKind.Sequential)]
public struct mpv_event_end_file
{
public int reason;
public int error;
}
} }
} }

View File

@@ -8,6 +8,7 @@ using System.Runtime.InteropServices;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows.Forms; using System.Windows.Forms;
using static mpvnet.libmpv; using static mpvnet.libmpv;
using static mpvnet.Native; using static mpvnet.Native;
using static mpvnet.StaticUsing; using static mpvnet.StaticUsing;
@@ -18,20 +19,40 @@ namespace mpvnet
public class mpv public class mpv
{ {
public static event Action<string[]> ClientMessage;
public static event Action Shutdown; public static event Action Shutdown;
public static event Action AfterShutdown; public static event Action LogMessage;
public static event Action GetPropertyReply;
public static event Action<string[]> ClientMessage;
public static event Action PlaybackRestart; public static event Action PlaybackRestart;
public static event Action VideoSizeChanged; public static event Action VideoSizeChanged;
public static event Action<EndFileEventMode> EndFile;
public static event Action SetPropertyReply;
public static event Action CommandReply;
public static event Action StartFile;
public static event Action FileLoaded;
public static event Action TracksChanged;
public static event Action TrackSwitched;
public static event Action Idle;
public static event Action Pause;
public static event Action Unpause;
public static event Action Tick;
public static event Action ScriptInputDispatch;
public static event Action VideoReconfig;
public static event Action AudioReconfig;
public static event Action MetadataUpdate;
public static event Action Seek;
public static event Action ChapterChange;
public static event Action QueueOverflow;
public static IntPtr MpvHandle; public static IntPtr MpvHandle;
public static IntPtr MpvWindowHandle; public static IntPtr MpvWindowHandle;
public static Addon Addon; 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 Size VideoSize = new Size(1920, 1080);
public static string mpvConfFolderPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\mpv\\"; 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 InputConfPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\mpv\\input.conf";
public static string mpvConfPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\mpv\\mpv.conf"; public static string mpvConfPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\mpv\\mpv.conf";
public static List<PyScript> PyScripts { get; } = new List<PyScript>();
private static Dictionary<string, string> _mpvConv; private static Dictionary<string, string> _mpvConv;
@@ -75,19 +96,41 @@ namespace mpvnet
SetStringProp("wid", MainForm.Hwnd.ToString()); SetStringProp("wid", MainForm.Hwnd.ToString());
SetStringProp("force-window", "yes"); SetStringProp("force-window", "yes");
mpv_initialize(MpvHandle); mpv_initialize(MpvHandle);
LoadScripts();
ProcessCommandLine(); ProcessCommandLine();
Task.Run(() => { LoadScripts(); });
Task.Run(() => { Addon = new Addon(); }); Task.Run(() => { Addon = new Addon(); });
Task.Run(() => { EventLoop(); }); Task.Run(() => { EventLoop(); });
} }
public static void LoadScripts()
{
string[] extensions = { ".lua", ".js" };
string[] scripts = Directory.GetFiles(Application.StartupPath + "\\Scripts");
foreach (var scriptPath in scripts)
{
string ext = Path.GetExtension(scriptPath);
if (extensions.Contains(ext.ToLower()))
mpv.Command("load-script", $"{scriptPath}");
}
foreach (var scriptPath in scripts)
{
string ext = Path.GetExtension(scriptPath);
if (ext == ".py")
PyScripts.Add(new PyScript(File.ReadAllText(scriptPath)));
}
}
public static void EventLoop() public static void EventLoop()
{ {
while (true) while (true)
{ {
IntPtr ptr = mpv_wait_event(MpvHandle, -1); IntPtr ptr = mpv_wait_event(MpvHandle, -1);
mpv_event evt = (mpv_event)Marshal.PtrToStructure(ptr, typeof(mpv_event)); mpv_event evt = (mpv_event)Marshal.PtrToStructure(ptr, typeof(mpv_event));
Debug.WriteLine(evt.event_id); //Debug.WriteLine(evt.event_id);
if (MpvWindowHandle == IntPtr.Zero) if (MpvWindowHandle == IntPtr.Zero)
MpvWindowHandle = FindWindowEx(MainForm.Hwnd, IntPtr.Zero, "mpv", null); MpvWindowHandle = FindWindowEx(MainForm.Hwnd, IntPtr.Zero, "mpv", null);
@@ -96,22 +139,50 @@ namespace mpvnet
{ {
case mpv_event_id.MPV_EVENT_SHUTDOWN: case mpv_event_id.MPV_EVENT_SHUTDOWN:
Shutdown?.Invoke(); Shutdown?.Invoke();
AfterShutdown?.Invoke();
return; 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: case mpv_event_id.MPV_EVENT_FILE_LOADED:
FileLoaded?.Invoke();
LoadFolder(); LoadFolder();
break; break;
case mpv_event_id.MPV_EVENT_PLAYBACK_RESTART: case mpv_event_id.MPV_EVENT_TRACKS_CHANGED:
PlaybackRestart?.Invoke(); TracksChanged?.Invoke();
break;
Size s = new Size(GetIntProp("dwidth", false), GetIntProp("dheight", false)); case mpv_event_id.MPV_EVENT_TRACK_SWITCHED:
TrackSwitched?.Invoke();
if (VideoSize != s && s != Size.Empty) break;
{ case mpv_event_id.MPV_EVENT_IDLE:
VideoSize = s; Idle?.Invoke();
VideoSizeChanged?.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; break;
case mpv_event_id.MPV_EVENT_CLIENT_MESSAGE: case mpv_event_id.MPV_EVENT_CLIENT_MESSAGE:
if (ClientMessage != null) if (ClientMessage != null)
@@ -130,17 +201,44 @@ namespace mpvnet
{ {
MsgError(ex.GetType().Name + "\r\n\r\n" + ex.ToString()); MsgError(ex.GetType().Name + "\r\n\r\n" + ex.ToString());
} }
ClientMessage?.Invoke(args); 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; break;
case mpv_event_id.MPV_EVENT_PROPERTY_CHANGE: 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) if (event_propertyData.format == mpv_format.MPV_FORMAT_FLAG)
foreach (var action in BoolPropChangeActions) foreach (var i in BoolPropChangeActions)
action.Invoke(Marshal.PtrToStructure<int>(eventData.data) == 1); 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; break;
} }
} }
@@ -220,16 +318,20 @@ namespace mpvnet
public static void ObserveBoolProp(string name, Action<bool> action) 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); int err = mpv_observe_property(MpvHandle, (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($"{name}: {(mpv_error)err}");
else
BoolPropChangeActions.Add(new KeyValuePair<string, Action<bool>>(name, action));
} }
public static void UnobserveBoolProp(string name, Action<bool> 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()); int err = mpv_unobserve_property(MpvHandle, (ulong)action.GetHashCode());
if (err < 0) if (err < 0)
@@ -344,18 +446,15 @@ namespace mpvnet
} }
public static byte[] GetUtf8Bytes(string s) => Encoding.UTF8.GetBytes(s + "\0"); public static byte[] GetUtf8Bytes(string s) => Encoding.UTF8.GetBytes(s + "\0");
}
public static void LoadScripts() public enum EndFileEventMode
{ {
foreach (var i in Directory.GetFiles(Application.StartupPath + "\\Scripts")) Eof,
{ Stop,
string[] extensions = { ".lua", ".js" }; Quit,
Error,
if (!extensions.Contains(Path.GetExtension(i).ToLower())) Redirect,
continue; Unknown
mpv.Command("load-script", $"{i}");
}
}
} }
} }

View File

@@ -94,6 +94,29 @@
<ApplicationManifest>app.manifest</ApplicationManifest> <ApplicationManifest>app.manifest</ApplicationManifest>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <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" />
<Reference Include="System.ComponentModel.Composition" /> <Reference Include="System.ComponentModel.Composition" />
<Reference Include="System.Core" /> <Reference Include="System.Core" />
@@ -127,6 +150,7 @@
<Compile Include="UI.cs" /> <Compile Include="UI.cs" />
<EmbeddedResource Include="MainForm.resx"> <EmbeddedResource Include="MainForm.resx">
<DependentUpon>MainForm.cs</DependentUpon> <DependentUpon>MainForm.cs</DependentUpon>
<SubType>Designer</SubType>
</EmbeddedResource> </EmbeddedResource>
<EmbeddedResource Include="Properties\Resources.resx"> <EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator> <Generator>ResXFileCodeGenerator</Generator>