Compare commits

..

8 Commits

Author SHA1 Message Date
Frank Skare
407b49b3ad 5.4.7.0 2020-05-06 18:51:38 +02:00
Frank Skare
0e92d4ec0c 5.4.7.0 2020-05-06 18:43:20 +02:00
Frank Skare
4f96835e19 support avisynth portable 2020-05-06 11:11:09 +02:00
Frank Skare
56d954d94e manual 2020-05-04 16:30:39 +02:00
Frank Skare
a8aeb1e3e9 manual 2020-05-04 16:28:59 +02:00
Frank Skare
415fd266a2 log error fix 2020-05-04 15:15:40 +02:00
Frank Skare
51f9e17380 5.4.6.0 2020-05-04 05:50:29 +02:00
Frank Skare
28045ad33e 5.4.5.1 Beta 2020-05-03 11:10:56 +02:00
47 changed files with 1187 additions and 847 deletions

View File

@@ -1,8 +1,42 @@
5.4.4.7 Beta (not yet released) 5.4.7.1 Beta (not yet released)
============ ============
-
5.4.7.0
=======
- log error fix
- workaround to support AviSynth portable (ffmpeg blocks loading AviSynth from path env var)
- attempt to fix not reproducible volume input issue
- attempt to fix exception caused by powershell being not available on Win 7
5.4.6.0
=======
- youtube-dl update
- auto update routine fix
5.4.5.1 Beta
============
- extensions no longer need to end with *Extension.dll but rather
the file name and the directory name must be identical
- text encoding exception fix
- the PowerShell script host is more feature complete, easier to use
and more efficient, there were however many PowerShell and C# breaking
changes requrired to make the core more robust and efficient
- Python 2 script host removed, Python 3 support is planned for summer
5.4.5.0
=======
stable release, no changes since the last beta
5.4.4.6 Beta 5.4.4.6 Beta

View File

@@ -174,9 +174,9 @@ Support
Before making a support request, please try a newer [beta version](#beta) first. Before making a support request, please try a newer [beta version](#beta) first.
[Support thread in VideoHelp forum](https://forum.videohelp.com/threads/392514-mpv-net-a-extendable-media-player-for-windows) Bugs and feature requests can be made on the github [issue tracker](https://github.com/stax76/mpv.net/issues), feel free to use for anything mpv.net related.
[Issue tracker](https://github.com/stax76/mpv.net/issues), feel free to use for anything mpv.net related. Or use the [support thread](https://forum.videohelp.com/threads/392514-mpv-net-a-extendable-media-player-for-windows) in the VideoHelp forum.
Settings Settings
@@ -341,7 +341,7 @@ The PowerShell scripting host is like extensions not initialized before media fi
mpv.net does not define scripting interfaces but instead exposed its complete internals, there are no compatibility guaranties. mpv.net does not define scripting interfaces but instead exposed its complete internals, there are no compatibility guaranties.
[Example Scripts](scripts/examples) [Example Scripts](scripts)
#### C# #### C#
@@ -358,16 +358,16 @@ Script code can be written within a C# [extension](#extensions), that way full c
The C# scripting host is like [extensions](#extensions) not initialized before media files are loaded. The C# scripting host is like [extensions](#extensions) not initialized before media files are loaded.
[Example Scripts](scripts/examples) [Example Scripts](scripts)
Extensions Extensions
---------- ----------
Extensions are located in the config folder and the filename must end with 'Extension.dll': Extensions are located in a subfolder _extensions_ in the config folder and the filename must have the same name as the directory:
```Text ```Text
<config folder>\Extensions\ExampleExtension\ExampleExtension.dll <config folder>\extensions\ExampleExtension\ExampleExtension.dll
``` ```
mpv.net does not define extension interfaces but instead exposed its complete internals, there are no compatibility guaranties. mpv.net does not define extension interfaces but instead exposed its complete internals, there are no compatibility guaranties.

View File

@@ -7,7 +7,6 @@ $include = @(
'*.iss', '*.iss',
'*.js', '*.js',
'*.lua', '*.lua',
'*.md',
'*.ps1', '*.ps1',
'*.resx', '*.resx',
'*.sln', '*.sln',

View File

@@ -8,6 +8,7 @@ using System.Collections.Generic;
using System.IO; using System.IO;
using mpvnet; using mpvnet;
using static mpvnet.Core;
namespace RatingExtension // the assembly name must end with 'Extension' namespace RatingExtension // the assembly name must end with 'Extension'
{ {
@@ -19,8 +20,8 @@ namespace RatingExtension // the assembly name must end with 'Extension'
public RatingExtension() // plugin initialization public RatingExtension() // plugin initialization
{ {
mp.ClientMessage += ClientMessage; //handles keys defined in input.conf core.ClientMessage += ClientMessage; //handles keys defined in input.conf
mp.Shutdown += Shutdown; // handles MPV_EVENT_SHUTDOWN core.Shutdown += Shutdown; // handles MPV_EVENT_SHUTDOWN
} }
// handles MPV_EVENT_SHUTDOWN // handles MPV_EVENT_SHUTDOWN
@@ -53,10 +54,10 @@ namespace RatingExtension // the assembly name must end with 'Extension'
if (int.TryParse(args[1], out int rating)) if (int.TryParse(args[1], out int rating))
{ {
string path = mp.get_property_string("path"); string path = core.get_property_string("path");
if (!File.Exists(path)) return; if (!File.Exists(path)) return;
Dic[path] = rating; Dic[path] = rating;
mp.commandv("show-text", $"Rating: {rating}"); core.commandv("show-text", $"Rating: {rating}");
} }
else if (args[1] == "about") else if (args[1] == "about")
Msg.Show("Rating Extension", "This extension writes a rating to the filename of rated videos when mpv.net shuts down.\n\nThe input.conf defaults contain key bindings for this extension to set ratings."); Msg.Show("Rating Extension", "This extension writes a rating to the filename of rated videos when mpv.net shuts down.\n\nThe input.conf defaults contain key bindings for this extension to set ratings.");

View File

@@ -13,6 +13,7 @@ using System.IO;
using mpvnet; using mpvnet;
using CSScriptLibrary; using CSScriptLibrary;
using static mpvnet.Core;
// the file name of extensions must end with 'Extension' // the file name of extensions must end with 'Extension'
namespace ScriptingExtension namespace ScriptingExtension
@@ -27,8 +28,8 @@ namespace ScriptingExtension
//Script = new Script(); //Script = new Script();
List<string> files = new List<string>(); List<string> files = new List<string>();
if (Directory.Exists(mp.ConfigFolder + "scripts-cs")) if (Directory.Exists(core.ConfigFolder + "scripts-cs"))
files.AddRange(Directory.GetFiles(mp.ConfigFolder + "scripts-cs", "*.cs")); files.AddRange(Directory.GetFiles(core.ConfigFolder + "scripts-cs", "*.cs"));
if (Directory.Exists(Folder.Startup + "scripts")) if (Directory.Exists(Folder.Startup + "scripts"))
foreach (string path in Directory.GetFiles(Folder.Startup + "scripts", "*.cs")) foreach (string path in Directory.GetFiles(Folder.Startup + "scripts", "*.cs"))

View File

@@ -2,12 +2,13 @@
using System.IO; using System.IO;
using mpvnet; using mpvnet;
using static mpvnet.Core;
class Script class Script
{ {
public Script() public Script()
{ {
mp.Shutdown += Shutdown; core.Shutdown += Shutdown;
} }
void Shutdown() void Shutdown()

Binary file not shown.

View File

@@ -8,6 +8,7 @@ using System.Windows.Forms;
using UI; using UI;
using static libmpv; using static libmpv;
using static mpvnet.Core;
using System.Threading.Tasks; using System.Threading.Tasks;
@@ -21,7 +22,7 @@ namespace mpvnet
public static string[] SubtitleTypes { get; } = { "srt", "ass", "idx", "sup", "ttxt", "ssa", "smi" }; public static string[] SubtitleTypes { get; } = { "srt", "ass", "idx", "sup", "ttxt", "ssa", "smi" };
public static string RegPath { get; } = @"HKCU\Software\" + Application.ProductName; public static string RegPath { get; } = @"HKCU\Software\" + Application.ProductName;
public static string ConfPath { get => mp.ConfigFolder + "mpvnet.conf"; } public static string ConfPath { get => core.ConfigFolder + "mpvnet.conf"; }
public static string ProcessInstance { get; set; } = "single"; public static string ProcessInstance { get; set; } = "single";
public static string DarkMode { get; set; } = "always"; public static string DarkMode { get; set; } = "always";
public static string DarkTheme { get; set; } = "dark"; public static string DarkTheme { get; set; } = "dark";
@@ -49,8 +50,8 @@ namespace mpvnet
public static void Init() public static void Init()
{ {
string dummy = mp.ConfigFolder; string dummy = core.ConfigFolder;
var dummy2 = mp.Conf; var dummy2 = core.Conf;
foreach (var i in Conf) foreach (var i in Conf)
ProcessProperty(i.Key, i.Value, true); ProcessProperty(i.Key, i.Value, true);
@@ -59,7 +60,7 @@ namespace mpvnet
{ {
try try
{ {
string filePath = mp.ConfigFolder + "mpvnet-debug.log"; string filePath = core.ConfigFolder + "mpvnet-debug.log";
if (File.Exists(filePath)) if (File.Exists(filePath))
File.Delete(filePath); File.Delete(filePath);
@@ -78,23 +79,16 @@ namespace mpvnet
string themeContent = null; string themeContent = null;
if (File.Exists(mp.ConfigFolder + "theme.conf")) if (File.Exists(core.ConfigFolder + "theme.conf"))
themeContent = File.ReadAllText(mp.ConfigFolder + "theme.conf"); themeContent = File.ReadAllText(core.ConfigFolder + "theme.conf");
Theme.Init( Theme.Init(
themeContent, themeContent,
Properties.Resources.theme, Properties.Resources.theme,
IsDarkMode ? DarkTheme : LightTheme); IsDarkMode ? DarkTheme : LightTheme);
mp.Shutdown += Shutdown; core.Shutdown += Shutdown;
mp.Initialized += Initialized; core.Initialized += Initialized;
mp.LogMessage += ShowFatalError;
}
static void ShowFatalError(mpv_log_level level, string msg)
{
if (!App.IsStartedFromTerminal && level == mpv_log_level.MPV_LOG_LEVEL_FATAL)
Msg.ShowError(msg);
} }
public static void RunAction(Action action) public static void RunAction(Action action)
@@ -103,6 +97,7 @@ namespace mpvnet
try try
{ {
action.Invoke(); action.Invoke();
Debug.WriteLine(Environment.TickCount);
} }
catch (Exception e) catch (Exception e)
{ {
@@ -116,25 +111,36 @@ namespace mpvnet
if (obj is Exception e) if (obj is Exception e)
{ {
if (App.IsStartedFromTerminal) if (App.IsStartedFromTerminal)
ConsoleHelp.WriteError(e.ToString(), "mpv.net"); ConsoleHelp.WriteError(e.ToString());
else else
Msg.ShowException(e); Msg.ShowException(e);
} }
else else
{ {
if (App.IsStartedFromTerminal) if (App.IsStartedFromTerminal)
ConsoleHelp.WriteError(obj.ToString(), "mpv.net"); ConsoleHelp.WriteError(obj.ToString());
else else
Msg.ShowError(obj.ToString()); Msg.ShowError(obj.ToString());
} }
} }
public static void ShowError(string title, string msg)
{
if (App.IsStartedFromTerminal)
{
ConsoleHelp.WriteError(title);
ConsoleHelp.WriteError(msg);
}
else
Msg.ShowError(title, msg);
}
static void Initialized() static void Initialized()
{ {
if (RememberVolume) if (RememberVolume)
{ {
mp.set_property_int("volume", RegistryHelp.GetInt(App.RegPath, "Volume", 70)); core.set_property_int("volume", RegistryHelp.GetInt(App.RegPath, "Volume", 70));
mp.set_property_string("mute", RegistryHelp.GetString(App.RegPath, "Mute", "no")); core.set_property_string("mute", RegistryHelp.GetString(App.RegPath, "Mute", "no"));
} }
} }
@@ -142,8 +148,8 @@ namespace mpvnet
{ {
if (RememberVolume) if (RememberVolume)
{ {
RegistryHelp.SetValue(App.RegPath, "Volume", mp.get_property_int("volume")); RegistryHelp.SetValue(App.RegPath, "Volume", core.get_property_int("volume"));
RegistryHelp.SetValue(App.RegPath, "Mute", mp.get_property_string("mute")); RegistryHelp.SetValue(App.RegPath, "Mute", core.get_property_string("mute"));
} }
} }
@@ -184,7 +190,7 @@ namespace mpvnet
case "light-theme": LightTheme = value.Trim('\'', '"'); return true; case "light-theme": LightTheme = value.Trim('\'', '"'); return true;
default: default:
if (writeError) if (writeError)
ConsoleHelp.WriteError($"unknown mpvnet.conf property: {name}", "mpv.net"); ConsoleHelp.WriteError($"unknown mpvnet.conf property: {name}");
return false; return false;
} }
} }

View File

@@ -8,13 +8,13 @@ using System.Windows.Forms;
using System.Windows.Interop; using System.Windows.Interop;
using VB = Microsoft.VisualBasic; using VB = Microsoft.VisualBasic;
using ScriptHost;
using static NewLine; using static NewLine;
using static mpvnet.Core;
namespace mpvnet namespace mpvnet
{ {
public class Command public class Commands
{ {
public static void Execute(string id, string[] args) public static void Execute(string id, string[] args)
{ {
@@ -36,7 +36,7 @@ namespace mpvnet
case "show-about": ShowDialog(typeof(AboutWindow)); break; case "show-about": ShowDialog(typeof(AboutWindow)); break;
case "show-conf-editor": ShowDialog(typeof(ConfWindow)); break; case "show-conf-editor": ShowDialog(typeof(ConfWindow)); break;
case "show-input-editor": ShowDialog(typeof(InputWindow)); break; case "show-input-editor": ShowDialog(typeof(InputWindow)); break;
case "open-conf-folder": Process.Start(mp.ConfigFolder); break; case "open-conf-folder": Process.Start(core.ConfigFolder); break;
case "shell-execute": Process.Start(args[0]); break; case "shell-execute": Process.Start(args[0]); break;
case "show-info": ShowInfo(); break; case "show-info": ShowInfo(); break;
case "playlist-first": PlaylistFirst(); break; case "playlist-first": PlaylistFirst(); break;
@@ -49,7 +49,7 @@ namespace mpvnet
} }
} }
public static void InvokeOnMainThread(Action action) => MainForm.Instance.Invoke(action); public static void InvokeOnMainThread(Action action) => MainForm.Instance.BeginInvoke(action);
public static void ShowDialog(Type winType) public static void ShowDialog(Type winType)
{ {
@@ -74,7 +74,7 @@ namespace mpvnet
InvokeOnMainThread(new Action(() => { InvokeOnMainThread(new Action(() => {
using (var d = new OpenFileDialog() { Multiselect = true }) using (var d = new OpenFileDialog() { Multiselect = true })
if (d.ShowDialog() == DialogResult.OK) if (d.ShowDialog() == DialogResult.OK)
mp.LoadFiles(d.FileNames, loadFolder, append); core.LoadFiles(d.FileNames, loadFolder, append);
})); }));
} }
@@ -90,13 +90,13 @@ namespace mpvnet
{ {
if (Directory.Exists(d.SelectedPath + "\\BDMV")) if (Directory.Exists(d.SelectedPath + "\\BDMV"))
{ {
mp.set_property_string("bluray-device", d.SelectedPath); core.set_property_string("bluray-device", d.SelectedPath);
mp.LoadFiles(new[] { @"bd://" }, false, false); core.LoadFiles(new[] { @"bd://" }, false, false);
} }
else else
{ {
mp.set_property_string("dvd-device", d.SelectedPath); core.set_property_string("dvd-device", d.SelectedPath);
mp.LoadFiles(new[] { @"dvd://" }, false, false); core.LoadFiles(new[] { @"dvd://" }, false, false);
} }
} }
} }
@@ -105,31 +105,31 @@ namespace mpvnet
public static void PlaylistFirst() public static void PlaylistFirst()
{ {
int pos = mp.get_property_int("playlist-pos"); int pos = core.get_property_int("playlist-pos");
if (pos != 0) if (pos != 0)
mp.set_property_int("playlist-pos", 0); core.set_property_int("playlist-pos", 0);
} }
public static void PlaylistLast() public static void PlaylistLast()
{ {
int pos = mp.get_property_int("playlist-pos"); int pos = core.get_property_int("playlist-pos");
int count = mp.get_property_int("playlist-count"); int count = core.get_property_int("playlist-count");
if (pos < count - 1) if (pos < count - 1)
mp.set_property_int("playlist-pos", count - 1); core.set_property_int("playlist-pos", count - 1);
} }
public static void ShowHistory() public static void ShowHistory()
{ {
if (File.Exists(mp.ConfigFolder + "history.txt")) if (File.Exists(core.ConfigFolder + "history.txt"))
Process.Start(mp.ConfigFolder + "history.txt"); Process.Start(core.ConfigFolder + "history.txt");
else else
{ {
if (Msg.ShowQuestion("Create history.txt file in config folder?", if (Msg.ShowQuestion("Create history.txt file in config folder?",
"mpv.net will write the date, time and filename of opened files to it.") == MsgResult.OK) "mpv.net will write the date, time and filename of opened files to it.") == MsgResult.OK)
File.WriteAllText(mp.ConfigFolder + "history.txt", ""); File.WriteAllText(core.ConfigFolder + "history.txt", "");
} }
} }
@@ -139,13 +139,13 @@ namespace mpvnet
{ {
string performer, title, album, genre, date, duration, text = ""; string performer, title, album, genre, date, duration, text = "";
long fileSize = 0; long fileSize = 0;
string path = mp.get_property_string("path"); string path = core.get_property_string("path");
if (path.Contains("://")) if (path.Contains("://"))
path = mp.get_property_string("media-title"); path = core.get_property_string("media-title");
int width = mp.get_property_int("video-params/w"); int width = core.get_property_int("video-params/w");
int height = mp.get_property_int("video-params/h"); int height = core.get_property_int("video-params/h");
if (File.Exists(path)) if (File.Exists(path))
{ {
@@ -171,7 +171,7 @@ namespace mpvnet
text += "Size: " + mediaInfo.GetInfo(MediaInfoStreamKind.General, "FileSize/String") + "\n"; text += "Size: " + mediaInfo.GetInfo(MediaInfoStreamKind.General, "FileSize/String") + "\n";
text += "Type: " + path.ShortExt().ToUpper(); text += "Type: " + path.ShortExt().ToUpper();
mp.commandv("show-text", text, "5000"); core.commandv("show-text", text, "5000");
return; return;
} }
} }
@@ -185,16 +185,16 @@ namespace mpvnet
"Size: " + mediaInfo.GetInfo(MediaInfoStreamKind.General, "FileSize/String") + "\n" + "Size: " + mediaInfo.GetInfo(MediaInfoStreamKind.General, "FileSize/String") + "\n" +
"Type: " + path.ShortExt().ToUpper(); "Type: " + path.ShortExt().ToUpper();
mp.commandv("show-text", text, "5000"); core.commandv("show-text", text, "5000");
return; return;
} }
} }
} }
TimeSpan position = TimeSpan.FromSeconds(mp.get_property_number("time-pos")); TimeSpan position = TimeSpan.FromSeconds(core.get_property_number("time-pos"));
TimeSpan duration2 = TimeSpan.FromSeconds(mp.get_property_number("duration")); TimeSpan duration2 = TimeSpan.FromSeconds(core.get_property_number("duration"));
string videoFormat = mp.get_property_string("video-format").ToUpper(); string videoFormat = core.get_property_string("video-format").ToUpper();
string audioCodec = mp.get_property_string("audio-codec-name").ToUpper(); string audioCodec = core.get_property_string("audio-codec-name").ToUpper();
text = path.FileName() + "\n" + text = path.FileName() + "\n" +
FormatTime(position.TotalMinutes) + ":" + FormatTime(position.TotalMinutes) + ":" +
@@ -208,12 +208,12 @@ namespace mpvnet
text += $"{videoFormat}\n{audioCodec}"; text += $"{videoFormat}\n{audioCodec}";
mp.commandv("show-text", text, "5000"); core.commandv("show-text", text, "5000");
string FormatTime(double value) => ((int)value).ToString("00"); string FormatTime(double value) => ((int)value).ToString("00");
} }
catch (Exception e) catch (Exception e)
{ {
Msg.ShowException(e); App.ShowException(e);
} }
} }
@@ -221,9 +221,12 @@ namespace mpvnet
{ {
InvokeOnMainThread(new Action(() => { InvokeOnMainThread(new Action(() => {
string command = VB.Interaction.InputBox("Enter a mpv command to be executed.", "Execute Command", RegistryHelp.GetString(App.RegPath, "RecentExecutedCommand")); string command = VB.Interaction.InputBox("Enter a mpv command to be executed.", "Execute Command", RegistryHelp.GetString(App.RegPath, "RecentExecutedCommand"));
if (string.IsNullOrEmpty(command)) return;
if (string.IsNullOrEmpty(command))
return;
RegistryHelp.SetValue(App.RegPath, "RecentExecutedCommand", command); RegistryHelp.SetValue(App.RegPath, "RecentExecutedCommand", command);
mp.command(command, false); core.command(command, false);
})); }));
} }
@@ -231,12 +234,14 @@ namespace mpvnet
{ {
InvokeOnMainThread(new Action(() => { InvokeOnMainThread(new Action(() => {
string clipboard = System.Windows.Forms.Clipboard.GetText(); string clipboard = System.Windows.Forms.Clipboard.GetText();
if (string.IsNullOrEmpty(clipboard) || (!clipboard.Contains("://") && !File.Exists(clipboard)) || clipboard.Contains("\n")) if (string.IsNullOrEmpty(clipboard) || (!clipboard.Contains("://") && !File.Exists(clipboard)) || clipboard.Contains("\n"))
{ {
Msg.ShowError("The clipboard does not contain a valid URL or file, URLs have to contain :// and are not allowed to contain a newline character."); App.ShowError("No URL found", "The clipboard does not contain a valid URL or file.");
return; return;
} }
mp.LoadFiles(new [] { clipboard }, false, Control.ModifierKeys.HasFlag(Keys.Control));
core.LoadFiles(new [] { clipboard }, false, Control.ModifierKeys.HasFlag(Keys.Control));
})); }));
} }
@@ -245,7 +250,7 @@ namespace mpvnet
InvokeOnMainThread(new Action(() => { InvokeOnMainThread(new Action(() => {
using (var d = new OpenFileDialog()) using (var d = new OpenFileDialog())
{ {
string path = mp.get_property_string("path"); string path = core.get_property_string("path");
if (File.Exists(path)) if (File.Exists(path))
d.InitialDirectory = Path.GetDirectoryName(path); d.InitialDirectory = Path.GetDirectoryName(path);
@@ -254,7 +259,7 @@ namespace mpvnet
if (d.ShowDialog() == DialogResult.OK) if (d.ShowDialog() == DialogResult.OK)
foreach (string filename in d.FileNames) foreach (string filename in d.FileNames)
mp.commandv("sub-add", filename); core.commandv("sub-add", filename);
} }
})); }));
} }
@@ -264,40 +269,40 @@ namespace mpvnet
InvokeOnMainThread(new Action(() => { InvokeOnMainThread(new Action(() => {
using (var d = new OpenFileDialog()) using (var d = new OpenFileDialog())
{ {
string path = mp.get_property_string("path"); string path = core.get_property_string("path");
if (File.Exists(path)) if (File.Exists(path))
d.InitialDirectory = Path.GetDirectoryName(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 i in d.FileNames)
mp.commandv("audio-add", i); core.commandv("audio-add", i);
} }
})); }));
} }
public static void CycleAudio() public static void CycleAudio()
{ {
string path = mp.get_property_string("path"); string path = core.get_property_string("path");
if (!File.Exists(path)) if (!File.Exists(path))
return; return;
using (MediaInfo mi = new MediaInfo(path)) using (MediaInfo mi = new MediaInfo(path))
{ {
MediaTrack[] audTracks = mp.MediaTracks.Where(track => track.Type == "a").ToArray(); MediaTrack[] audTracks = core.MediaTracks.Where(track => track.Type == "a").ToArray();
if (audTracks.Length < 2) if (audTracks.Length < 2)
return; return;
int aid = mp.get_property_int("aid"); int aid = core.get_property_int("aid");
aid += 1; aid += 1;
if (aid > audTracks.Length) if (aid > audTracks.Length)
aid = 1; aid = 1;
mp.commandv("set", "aid", aid.ToString()); core.commandv("set", "aid", aid.ToString());
mp.commandv("show-text", audTracks[aid - 1].Text.Substring(3), "5000"); core.commandv("show-text", audTracks[aid - 1].Text.Substring(3), "5000");
} }
} }
@@ -317,7 +322,7 @@ namespace mpvnet
'' ''
}"; }";
string json = mp.get_property_string("profile-list"); string json = core.get_property_string("profile-list");
string file = Path.GetTempPath() + @"\mpv profile-list.txt"; string file = Path.GetTempPath() + @"\mpv profile-list.txt";
File.WriteAllText(file, BR + PowerShell.InvokeAndReturnString(code, "json", json)); File.WriteAllText(file, BR + PowerShell.InvokeAndReturnString(code, "json", json));
Process.Start(file); Process.Start(file);
@@ -344,7 +349,7 @@ namespace mpvnet
} }
}"; }";
string json = mp.get_property_string("command-list"); string json = core.get_property_string("command-list");
string file = Path.GetTempPath() + @"\mpv command-list.txt"; string file = Path.GetTempPath() + @"\mpv command-list.txt";
File.WriteAllText(file, PowerShell.InvokeAndReturnString(code, "json", json) + BR); File.WriteAllText(file, PowerShell.InvokeAndReturnString(code, "json", json) + BR);
Process.Start(file); Process.Start(file);
@@ -353,7 +358,7 @@ namespace mpvnet
static void ShowProperties() static void ShowProperties()
{ {
string file = Path.GetTempPath() + @"\mpv property-list.txt"; string file = Path.GetTempPath() + @"\mpv property-list.txt";
var props = mp.get_property_string("property-list").Split(',').OrderBy(prop => prop); var props = core.get_property_string("property-list").Split(',').OrderBy(prop => prop);
File.WriteAllText(file, BR + string.Join(BR, props) + BR); File.WriteAllText(file, BR + string.Join(BR, props) + BR);
Process.Start(file); Process.Start(file);
} }

View File

@@ -1,10 +1,13 @@
using System; 
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel.Composition; using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting; using System.ComponentModel.Composition.Hosting;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using static mpvnet.Core;
namespace mpvnet namespace mpvnet
{ {
public class Extension public class Extension
@@ -25,20 +28,23 @@ namespace mpvnet
{ {
string[] knownExtensions = { "RatingExtension", "ScriptingExtension" }; string[] knownExtensions = { "RatingExtension", "ScriptingExtension" };
foreach (string path in Directory.GetDirectories(dir)) foreach (string extDir in Directory.GetDirectories(dir))
{ {
if (knownExtensions.Contains(Path.GetFileName(path))) if (knownExtensions.Contains(Path.GetFileName(extDir)))
catalog.Catalogs.Add(new DirectoryCatalog(path, "*Extension.dll")); catalog.Catalogs.Add(new DirectoryCatalog(extDir, Path.GetFileName(extDir) + ".dll"));
else else
Msg.ShowError("Failed to load extension", path + "\n\nOnly extensions that ship with mpv.net are allowed in <startup>\\extensions\n\nUser extensions have to use <config folder>\\extensions\n\nNever copy or install a new mpv.net version over a old mpv.net version."); ConsoleHelp.WriteError("Failed to load extension:\n\n" + extDir +
"\n\nOnly extensions that ship with mpv.net are allowed in <startup>\\extensions" +
"\n\nUser extensions have to use <config folder>\\extensions" +
"\n\nNever copy or install a new mpv.net version over a old mpv.net version.");
} }
} }
dir = mp.ConfigFolder + "extensions"; dir = core.ConfigFolder + "extensions";
if (Directory.Exists(dir)) if (Directory.Exists(dir))
foreach (string i in Directory.GetDirectories(dir)) foreach (string extDir in Directory.GetDirectories(dir))
catalog.Catalogs.Add(new DirectoryCatalog(i, "*Extension.dll")); catalog.Catalogs.Add(new DirectoryCatalog(extDir, Path.GetFileName(extDir) + ".dll"));
if (catalog.Catalogs.Count > 0) if (catalog.Catalogs.Count > 0)
{ {
@@ -48,7 +54,7 @@ namespace mpvnet
} }
catch (Exception ex) catch (Exception ex)
{ {
Msg.ShowException(ex); App.ShowException(ex);
} }
} }
} }
@@ -56,4 +62,4 @@ namespace mpvnet
public interface IExtension public interface IExtension
{ {
} }
} }

View File

@@ -6,7 +6,10 @@ public static class ConsoleHelp
{ {
public static int Padding { get; set; } public static int Padding { get; set; }
public static void WriteError(object obj, string module = null) => Write(obj, module, ConsoleColor.Red, false); public static void WriteError(object obj, string module = "mpv.net")
{
Write(obj, module, ConsoleColor.Red, false);
}
public static void Write(object obj, string module = "mpv.net") public static void Write(object obj, string module = "mpv.net")
{ {

View File

@@ -14,6 +14,8 @@ using System.Windows.Forms;
using Microsoft.Win32; using Microsoft.Win32;
using static mpvnet.Core;
namespace mpvnet namespace mpvnet
{ {
public class Sys public class Sys
@@ -186,7 +188,7 @@ namespace mpvnet
public static ObservableCollection<CommandItem> Items { public static ObservableCollection<CommandItem> Items {
get { get {
if (_Items is null) if (_Items is null)
_Items = GetItems(File.ReadAllText(mp.InputConfPath)); _Items = GetItems(File.ReadAllText(core.InputConfPath));
return _Items; return _Items;
} }
@@ -227,4 +229,4 @@ namespace mpvnet
{ {
public static string Startup { get; } = Application.StartupPath + @"\"; public static string Startup { get; } = Application.StartupPath + @"\";
} }
} }

250
mpv.net/Misc/PowerShell.cs Normal file
View File

@@ -0,0 +1,250 @@

using System;
using System.Collections.Generic;
using System.Linq;
using System.Management.Automation;
using System.Management.Automation.Runspaces;
using System.Threading;
using System.Threading.Tasks;
using static mpvnet.Core;
using static NewLine;
namespace mpvnet
{
public class PowerShell
{
public Runspace Runspace { get; set; }
public Pipeline Pipeline { get; set; }
public string Module { get; set; }
public bool Print { get; set; }
public List<string> Scripts { get; } = new List<string>();
public List<KeyValuePair<string, object>> Variables = new List<KeyValuePair<string, object>>();
public string[] Parameters { get; }
public event Action<string, object[]> Event;
public event Action<string, object> PropertyChanged;
public List<KeyValuePair<string, ScriptBlock>> EventHandlers = new List<KeyValuePair<string, ScriptBlock>>();
public List<KeyValuePair<string, ScriptBlock>> PropChangedHandlers = new List<KeyValuePair<string, ScriptBlock>>();
public static List<PowerShell> Instances { get; } = new List<PowerShell>();
public object Invoke() => Invoke(null, null);
public object Invoke(string variable, object obj)
{
try
{
Runspace = RunspaceFactory.CreateRunspace();
Runspace.ApartmentState = ApartmentState.STA;
Runspace.Open();
Pipeline = Runspace.CreatePipeline();
foreach (string script in Scripts)
Pipeline.Commands.AddScript(script);
if (Parameters != null)
foreach (string param in Parameters)
foreach (Command command in Pipeline.Commands)
command.Parameters.Add(null, param);
Runspace.SessionStateProxy.SetVariable("mp", this);
foreach (var i in Variables)
Runspace.SessionStateProxy.SetVariable(i.Key, i.Value);
if (!string.IsNullOrEmpty(variable))
Runspace.SessionStateProxy.SetVariable(variable, obj);
if (Print)
{
Pipeline.Output.DataReady += Output_DataReady;
Pipeline.Error.DataReady += Error_DataReady;
}
return Pipeline.Invoke();
}
catch (RuntimeException e)
{
string message = e.Message + BR + BR + e.ErrorRecord.ScriptStackTrace.Replace(
" <ScriptBlock>, <No file>", "") + BR + BR + Module + BR;
throw new PowerShellException(message);
}
catch (Exception e)
{
throw e;
}
}
public static string InvokeAndReturnString(string code, string varName, object varValue)
{
PowerShell ps = new PowerShell() { Print = false };
ps.Scripts.Add(code);
string ret = string.Join(Environment.NewLine, (ps.Invoke(varName, varValue)
as IEnumerable<object>).Select(item => item.ToString())).ToString();
ps.Runspace.Dispose();
return ret;
}
public void Output_DataReady(object sender, EventArgs e)
{
var output = sender as PipelineReader<PSObject>;
while (output.Count > 0)
ConsoleHelp.Write(output.Read(), Module);
}
public void Error_DataReady(object sender, EventArgs e)
{
var output = sender as PipelineReader<Object>;
while (output.Count > 0)
ConsoleHelp.WriteError(output.Read(), Module);
}
public void RedirectStreams(PSEventJob job)
{
if (Print)
{
job.Output.DataAdded += Output_DataAdded;
job.Error.DataAdded += Error_DataAdded;
}
}
public void commandv(params string[] args) => core.commandv(args);
public void command(string command) => core.command(command);
public bool get_property_bool(string name) => core.get_property_bool(name);
public void set_property_bool(string name, bool value) => core.set_property_bool(name, value);
public int get_property_int(string name) => core.get_property_int(name);
public void set_property_int(string name, int value) => core.set_property_int(name, value);
public double get_property_number(string name) => core.get_property_number(name);
public void set_property_number(string name, double value) => core.set_property_number(name, value);
public string get_property_string(string name) => core.get_property_string(name);
public void set_property_string(string name, string value) => core.set_property_string(name, value);
public void observe_property(string name, string type, ScriptBlock sb)
{
PropChangedHandlers.Add(new KeyValuePair<string, ScriptBlock>(name, sb));
switch (type)
{
case "bool": case "boolean":
core.observe_property_bool(name, (value) => Task.Run(() => PropertyChanged.Invoke(name, value)));
break;
case "string":
core.observe_property_string(name, (value) => Task.Run(() => PropertyChanged.Invoke(name, value)));
break;
case "int": case "integer":
core.observe_property_int(name, (value) => Task.Run(() => PropertyChanged.Invoke(name, value)));
break;
case "float": case "double":
core.observe_property_double(name, (value) => Task.Run(() => PropertyChanged.Invoke(name, value)));
break;
case "nil": case "none": case "native":
core.observe_property(name, () => Task.Run(() => PropertyChanged.Invoke(name, null)));
break;
default:
App.ShowError("Invalid Type", "Valid types are: bool or boolean, string, int or integer, float or double, nil or none or native");
break;
}
}
public void register_event(string name, ScriptBlock sb)
{
EventHandlers.Add(new KeyValuePair<string, ScriptBlock>(name, sb));
switch (name)
{
case "log-message":
core.LogMessageAsync += (level, msg) => Event.Invoke("log-message", new object[] { level, msg });
break;
case "end-file":
core.EndFileAsync += (reason) => Event.Invoke("end-file", new object[] { reason });
break;
case "client-message":
core.ClientMessageAsync += (args) => Event.Invoke("client-message", args);
break;
case "shutdown":
core.Shutdown += () => Event.Invoke("shutdown", null);
break;
case "get-property-reply":
core.GetPropertyReplyAsync += () => Event.Invoke("get-property-reply", null);
break;
case "set-property-reply":
core.SetPropertyReplyAsync += () => Event.Invoke("set-property-reply", null);
break;
case "command-reply":
core.CommandReplyAsync += () => Event.Invoke("command-reply", null);
break;
case "start-file":
core.StartFileAsync += () => Event.Invoke("start-file", null);
break;
case "file-loaded":
core.FileLoadedAsync += () => Event.Invoke("file-loaded", null);
break;
case "idle":
core.IdleAsync += () => Event.Invoke("idle", null);
break;
case "video-reconfig":
core.VideoReconfigAsync += () => Event.Invoke("video-reconfig", null);
break;
case "audio-reconfig":
core.AudioReconfigAsync += () => Event.Invoke("audio-reconfig", null);
break;
case "seek":
core.SeekAsync += () => Event.Invoke("seek", null);
break;
case "playback-restart":
core.PlaybackRestartAsync += () => Event.Invoke("playback-restart", null);
break;
}
}
void Output_DataAdded(object sender, DataAddedEventArgs e)
{
var output = sender as PSDataCollection<PSObject>;
ConsoleHelp.Write(output[e.Index], Module);
}
void Error_DataAdded(object sender, DataAddedEventArgs e)
{
var error = sender as PSDataCollection<ErrorRecord>;
ConsoleHelp.WriteError(error[e.Index], Module);
}
public static void Shutdown()
{
foreach (PowerShell ps in Instances)
ps.Runspace.Dispose();
}
}
public class PowerShellException : Exception
{
public PowerShellException(string message) : base(message)
{
}
}
}

View File

@@ -6,6 +6,8 @@ using System.Collections.Generic;
using System.Threading; using System.Threading;
using System.Diagnostics; using System.Diagnostics;
using static mpvnet.Core;
namespace mpvnet namespace mpvnet
{ {
static class Program static class Program
@@ -21,7 +23,7 @@ namespace mpvnet
if (App.IsStartedFromTerminal) if (App.IsStartedFromTerminal)
WinAPI.AttachConsole(-1 /*ATTACH_PARENT_PROCESS*/); WinAPI.AttachConsole(-1 /*ATTACH_PARENT_PROCESS*/);
if (mp.ConfigFolder == "") if (core.ConfigFolder == "")
return; return;
string[] args = Environment.GetCommandLineArgs().Skip(1).ToArray(); string[] args = Environment.GetCommandLineArgs().Skip(1).ToArray();
@@ -95,4 +97,4 @@ namespace mpvnet
} }
} }
} }
} }

View File

@@ -45,7 +45,7 @@ namespace UI
if (!theme.Dictionary.ContainsKey(key)) if (!theme.Dictionary.ContainsKey(key))
{ {
isKeyMissing = true; isKeyMissing = true;
ConsoleHelp.WriteError($"Theme '{activeTheme}' misses '{key}'", "mpv.net"); ConsoleHelp.WriteError($"Theme '{activeTheme}' misses '{key}'");
break; break;
} }
} }

View File

@@ -6,6 +6,8 @@ using System.Reflection;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using System.Windows.Forms; using System.Windows.Forms;
using static mpvnet.Core;
namespace mpvnet namespace mpvnet
{ {
class UpdateCheck class UpdateCheck
@@ -61,7 +63,7 @@ namespace mpvnet
proc.Start(); proc.Start();
} }
mp.command("quit"); core.command("quit");
} }
RegistryHelp.SetValue(RegistryHelp.ApplicationKey, "UpdateCheckVersion", onlineVersion.ToString()); RegistryHelp.SetValue(RegistryHelp.ApplicationKey, "UpdateCheckVersion", onlineVersion.ToString());
@@ -74,4 +76,4 @@ namespace mpvnet
} }
} }
} }
} }

View File

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

View File

@@ -1,61 +0,0 @@

using System;
using System.IO;
using System.Reflection;
using Microsoft.Scripting;
using Microsoft.Scripting.Hosting;
using IronPython.Hosting;
using IronPython.Runtime;
using IronPython.Runtime.Operations;
namespace mpvnet
{
public class PythonScript
{
ScriptEngine engine;
ScriptScope scope;
public PythonScript(string scriptPath)
{
try
{
engine = Python.CreateEngine();
scope = engine.CreateScope();
scope.ImportModule("clr");
engine.Execute("import clr", scope);
engine.Execute("clr.AddReference(\"mpvnet\")", scope);
engine.Execute("import mpvnet", scope);
engine.Execute("from mpvnet import *", scope);
engine.Execute(File.ReadAllText(scriptPath), scope);
}
catch (Exception ex)
{
if (ex is SyntaxErrorException e)
Msg.ShowError(e.GetType().Name,$"{e.Line}, {e.Column}: " + e.Message + "\n\n" + Path.GetFileName(scriptPath));
else
Msg.ShowError(ex.GetType().Name, ex.Message + "\n\n" + Path.GetFileName(scriptPath));
}
}
}
public class PythonEventObject
{
public PythonFunction PythonFunction { get; set; }
public EventInfo EventInfo { get; set; }
public Delegate Delegate { get; set; }
public void Invoke() => PythonCalls.Call(PythonFunction);
public void InvokeEndFileEventMode(EndFileEventMode arg)
{
PythonCalls.Call(PythonFunction, new[] { arg });
}
public void InvokeStrings(string[] arg)
{
PythonCalls.Call(PythonFunction, new[] { arg });
}
}
}

View File

@@ -1,123 +0,0 @@

using System;
using System.Collections.Generic;
using System.Linq;
using System.Management.Automation;
using System.Management.Automation.Runspaces;
using System.Threading;
namespace ScriptHost
{
public class PowerShell
{
public Runspace Runspace { get; set; }
public Pipeline Pipeline { get; set; }
public string Module { get; set; }
public bool Print { get; set; }
public List<string> Scripts { get; } = new List<string>();
public string[] Parameters { get; }
public static List<PowerShell> Instances { get; } = new List<PowerShell>();
string NL = Environment.NewLine;
public object Invoke() => Invoke(null, null);
public object Invoke(string variable, object obj)
{
try
{
Runspace = RunspaceFactory.CreateRunspace();
Runspace.ApartmentState = ApartmentState.STA;
Runspace.Open();
Pipeline = Runspace.CreatePipeline();
foreach (string script in Scripts)
Pipeline.Commands.AddScript(script);
if (Parameters != null)
foreach (string param in Parameters)
foreach (Command command in Pipeline.Commands)
command.Parameters.Add(null, param);
Runspace.SessionStateProxy.SetVariable("ScriptHost", this);
if (!string.IsNullOrEmpty(variable))
Runspace.SessionStateProxy.SetVariable(variable, obj);
if (Print)
{
Pipeline.Output.DataReady += Output_DataReady;
Pipeline.Error.DataReady += Error_DataReady;
}
return Pipeline.Invoke();
}
catch (RuntimeException e)
{
string message = e.Message + NL + NL + e.ErrorRecord.ScriptStackTrace.Replace(
" <ScriptBlock>, <No file>", "") + NL + NL + Module + NL;
throw new PowerShellException(message);
}
catch (Exception e)
{
throw e;
}
}
public static string InvokeAndReturnString(string code, string varName, object varValue)
{
PowerShell ps = new PowerShell() { Print = false };
ps.Scripts.Add(code);
string ret = string.Join(Environment.NewLine, (ps.Invoke(varName, varValue)
as IEnumerable<object>).Select(item => item.ToString())).ToString();
ps.Runspace.Dispose();
return ret;
}
public void Output_DataReady(object sender, EventArgs e)
{
var output = sender as PipelineReader<PSObject>;
while (output.Count > 0)
ConsoleHelp.Write(output.Read(), Module);
}
public void Error_DataReady(object sender, EventArgs e)
{
var output = sender as PipelineReader<Object>;
while (output.Count > 0)
ConsoleHelp.WriteError(output.Read(), Module);
}
public void RedirectEventJobStreams(PSEventJob job)
{
if (Print)
{
job.Output.DataAdded += Output_DataAdded;
job.Error.DataAdded += Error_DataAdded;
}
}
void Output_DataAdded(object sender, DataAddedEventArgs e)
{
var output = sender as PSDataCollection<PSObject>;
ConsoleHelp.Write(output[e.Index], Module);
}
void Error_DataAdded(object sender, DataAddedEventArgs e)
{
var error = sender as PSDataCollection<ErrorRecord>;
ConsoleHelp.WriteError(error[e.Index], Module);
}
}
public class PowerShellException : Exception
{
public PowerShellException(string message) : base(message)
{
}
}
}

View File

@@ -1,23 +1,67 @@
$ErrorActionPreference = 'Stop' $ErrorActionPreference = 'Stop'
$targetDir = (Split-Path $args[1]) + "\new version"
if ($args.Length -ne 2) {
Write-Host 'Invalid arguments' -ForegroundColor Red
exit
}
if (-not (Get-Command curl.exe)) {
Write-Host 'Error using curl.exe' -ForegroundColor Red
exit
}
if ($PSVersionTable.PSVersion.Major -lt 5) {
Write-Host 'PowerShell 5.1 not found' -ForegroundColor Red
exit
}
Add-Type -AssemblyName Microsoft.VisualBasic
# Delete directory using recycle bin
function Remove-Directory($directory) {
if (Test-Path $directory) {
[Microsoft.VisualBasic.FileIO.FileSystem]::
DeleteDirectory($directory, 'OnlyErrorDialogs', 'SendToRecycleBin')
}
}
$currentDir = $args[1];
$targetDir = (Split-Path $currentDir) + "\new version"
Remove-Directory $targetDir
$targetFile = $targetDir + '.7z' $targetFile = $targetDir + '.7z'
Remove-Item $targetFile -Force -ErrorAction Ignore
Write-Host 'Download new version' -ForegroundColor Green Write-Host 'Download new version' -ForegroundColor Green
curl.exe $args[0] --location --output $targetFile curl.exe $args[0] --location --output $targetFile
if ($LastExitCode) { throw $LastExitCode } if ($LastExitCode) { throw $LastExitCode }
Write-Host 'Unpack new version' -ForegroundColor Green Write-Host 'Unpack new version' -ForegroundColor Green
& ($args[1] + '\7z\7za.exe') x -y $targetFile -o"$targetDir" & ($currentDir + '\7z\7za.exe') x -y $targetFile -o"$targetDir"
if ($LastExitCode) { throw $LastExitCode } if ($LastExitCode) { throw $LastExitCode }
Write-Host 'Delete downloaded file' -ForegroundColor Green Write-Host 'Delete downloaded file' -ForegroundColor Green
Remove-Item $targetFile -Force -Recurse Remove-Item $targetFile -Force -Recurse
$portableConfigDir = $currentDir + '\portable_config'
$portableConfigTempDir = (Split-Path $currentDir) + '\portable config dir temp'
Remove-Item $portableConfigTempDir -Force -ErrorAction Ignore
if (Test-Path $portableConfigDir) {
Write-Host 'Backup portable config' -ForegroundColor Green
Copy-Item $portableConfigDir $portableConfigTempDir -Recurse -Force
}
Write-Host 'Delete current version' -ForegroundColor Green Write-Host 'Delete current version' -ForegroundColor Green
Remove-Item $args[1] -Force -Recurse Remove-Directory $currentDir
Write-Host 'Rename directory' -ForegroundColor Green Write-Host 'Rename directory' -ForegroundColor Green
Rename-Item $targetDir (Split-Path $args[1] -Leaf) Rename-Item $targetDir (Split-Path $currentDir -Leaf)
if (Test-Path $portableConfigTempDir) {
Write-Host 'Restore portable config' -ForegroundColor Green
Move-Item $portableConfigTempDir $portableConfigDir -Force
}
Write-Host 'Update is complete' -ForegroundColor Green Write-Host 'Update is complete' -ForegroundColor Green

View File

@@ -1,7 +1,10 @@
using System.IO; 
using System.IO;
using System.Windows; using System.Windows;
using System.Windows.Input; using System.Windows.Input;
using static mpvnet.Core;
namespace mpvnet namespace mpvnet
{ {
public partial class AboutWindow : Window public partial class AboutWindow : Window
@@ -10,7 +13,7 @@ namespace mpvnet
{ {
InitializeComponent(); InitializeComponent();
Version.Text = $"mpv.net Version {System.Windows.Forms.Application.ProductVersion} ({File.GetLastWriteTime(System.Windows.Forms.Application.ExecutablePath).ToShortDateString()})"; Version.Text = $"mpv.net Version {System.Windows.Forms.Application.ProductVersion} ({File.GetLastWriteTime(System.Windows.Forms.Application.ExecutablePath).ToShortDateString()})";
mpvVersion.Text = $"{mp.get_property_string("mpv-version")} ({File.GetLastWriteTime(Folder.Startup + "mpv-1.dll").ToShortDateString()})"; mpvVersion.Text = $"{core.get_property_string("mpv-version")} ({File.GetLastWriteTime(Folder.Startup + "mpv-1.dll").ToShortDateString()})";
} }
protected override void OnPreviewKeyDown(KeyEventArgs e) => Close(); protected override void OnPreviewKeyDown(KeyEventArgs e) => Close();

View File

@@ -6,6 +6,8 @@ using System.Windows.Data;
using System.Windows.Input; using System.Windows.Input;
using System.Windows.Interop; using System.Windows.Interop;
using static mpvnet.Core;
namespace mpvnet namespace mpvnet
{ {
public partial class CommandPaletteWindow : Window public partial class CommandPaletteWindow : Window
@@ -106,7 +108,7 @@ namespace mpvnet
{ {
CommandItem item = ListView.SelectedItem as CommandItem; CommandItem item = ListView.SelectedItem as CommandItem;
Close(); Close();
mp.command(item.Command); core.command(item.Command);
} }
} }

View File

@@ -11,6 +11,7 @@ using System.Windows.Controls;
using System.Windows.Input; using System.Windows.Input;
using DynamicGUI; using DynamicGUI;
using static mpvnet.Core;
namespace mpvnet namespace mpvnet
{ {
@@ -26,7 +27,7 @@ namespace mpvnet
InitializeComponent(); InitializeComponent();
DataContext = this; DataContext = this;
SearchControl.SearchTextBox.TextChanged += SearchTextBox_TextChanged; SearchControl.SearchTextBox.TextChanged += SearchTextBox_TextChanged;
LoadConf(mp.ConfPath); LoadConf(core.ConfPath);
LoadConf(App.ConfPath); LoadConf(App.ConfPath);
LoadSettings(); LoadSettings();
InitialContent = GetCompareString(); InitialContent = GetCompareString();
@@ -74,7 +75,7 @@ namespace mpvnet
if (InitialContent == GetCompareString()) if (InitialContent == GetCompareString())
return; return;
File.WriteAllText(mp.ConfPath, GetContent("mpv")); File.WriteAllText(core.ConfPath, GetContent("mpv"));
File.WriteAllText(App.ConfPath, GetContent("mpvnet")); File.WriteAllText(App.ConfPath, GetContent("mpvnet"));
Msg.Show("Changes will be available on next mpv.net startup."); Msg.Show("Changes will be available on next mpv.net startup.");
} }
@@ -293,7 +294,7 @@ namespace mpvnet
void OpenSettingsTextBlock_MouseUp(object sender, MouseButtonEventArgs e) void OpenSettingsTextBlock_MouseUp(object sender, MouseButtonEventArgs e)
{ {
Process.Start(Path.GetDirectoryName(mp.ConfPath)); Process.Start(Path.GetDirectoryName(core.ConfPath));
} }
void PreviewTextBlock_MouseUp(object sender, MouseButtonEventArgs e) void PreviewTextBlock_MouseUp(object sender, MouseButtonEventArgs e)
@@ -319,4 +320,4 @@ namespace mpvnet
Close(); Close();
} }
} }
} }

View File

@@ -10,6 +10,8 @@ using System.Windows.Controls;
using System.Windows.Input; using System.Windows.Input;
using System.Windows.Interop; using System.Windows.Interop;
using static mpvnet.Core;
namespace mpvnet namespace mpvnet
{ {
public partial class EverythingWindow : Window public partial class EverythingWindow : Window
@@ -103,7 +105,7 @@ namespace mpvnet
void Execute() void Execute()
{ {
if (ListView.SelectedItem != null) if (ListView.SelectedItem != null)
mp.LoadFiles(new[] { ListView.SelectedItem as string }, true, Keyboard.Modifiers == ModifierKeys.Control); core.LoadFiles(new[] { ListView.SelectedItem as string }, true, Keyboard.Modifiers == ModifierKeys.Control);
Keyboard.Focus(FilterTextBox); Keyboard.Focus(FilterTextBox);
} }

View File

@@ -8,6 +8,8 @@ using System.Windows.Controls;
using System.Windows.Data; using System.Windows.Data;
using System.Windows.Input; using System.Windows.Input;
using static mpvnet.Core;
namespace mpvnet namespace mpvnet
{ {
public partial class InputWindow : Window public partial class InputWindow : Window
@@ -123,7 +125,7 @@ namespace mpvnet
void Window_Closed(object sender, EventArgs e) void Window_Closed(object sender, EventArgs e)
{ {
if (InitialInputConfContent == GetInputConfContent()) return; if (InitialInputConfContent == GetInputConfContent()) return;
File.WriteAllText(mp.InputConfPath, GetInputConfContent()); File.WriteAllText(core.InputConfPath, GetInputConfContent());
Msg.Show("Changes will be available on next mpv.net startup."); Msg.Show("Changes will be available on next mpv.net startup.");
} }

View File

@@ -6,6 +6,7 @@ using System.Windows.Input;
using System.Windows.Interop; using System.Windows.Interop;
using WinForms = System.Windows.Forms; using WinForms = System.Windows.Forms;
using static mpvnet.Core;
namespace mpvnet namespace mpvnet
{ {
@@ -183,7 +184,7 @@ namespace mpvnet
OnKeyUp(new WinForms.KeyEventArgs((WinForms.Keys)(unchecked((int)(long)m.WParam)) | ModifierKeys)); OnKeyUp(new WinForms.KeyEventArgs((WinForms.Keys)(unchecked((int)(long)m.WParam)) | ModifierKeys));
else if (m.Msg == WM_APPCOMMAND) else if (m.Msg == WM_APPCOMMAND)
{ {
if (!mp.get_property_bool("input-media-keys")) if (!core.get_property_bool("input-media-keys"))
return; return;
var value = (AppCommand)(m.LParam.ToInt64() >> 16 & ~0xf000); var value = (AppCommand)(m.LParam.ToInt64() >> 16 & ~0xf000);
@@ -385,4 +386,4 @@ namespace mpvnet
KeyChar = e.Text; KeyChar = e.Text;
} }
} }
} }

View File

@@ -12,7 +12,7 @@ using System.Diagnostics;
using System.Threading.Tasks; using System.Threading.Tasks;
using UI; using UI;
using ScriptHost; using static mpvnet.Core;
namespace mpvnet namespace mpvnet
{ {
@@ -47,30 +47,30 @@ namespace mpvnet
Instance = this; Instance = this;
Hwnd = Handle; Hwnd = Handle;
ConsoleHelp.Padding = 60; ConsoleHelp.Padding = 60;
mp.Init(); core.Init();
mp.Shutdown += Shutdown; core.Shutdown += Shutdown;
mp.VideoSizeChanged += VideoSizeChanged; core.VideoSizeChanged += VideoSizeChanged;
mp.FileLoaded += FileLoaded; core.FileLoaded += FileLoaded;
mp.Idle += Idle; core.Idle += Idle;
mp.Seek += () => UpdateProgressBar(); core.Seek += () => UpdateProgressBar();
mp.observe_property("window-maximized", PropChangeWindowMaximized); core.observe_property("window-maximized", PropChangeWindowMaximized);
mp.observe_property("window-minimized", PropChangeWindowMinimized); core.observe_property("window-minimized", PropChangeWindowMinimized);
mp.observe_property_bool("pause", PropChangePause); core.observe_property_bool("pause", PropChangePause);
mp.observe_property_bool("fullscreen", PropChangeFullscreen); core.observe_property_bool("fullscreen", PropChangeFullscreen);
mp.observe_property_bool("ontop", PropChangeOnTop); core.observe_property_bool("ontop", PropChangeOnTop);
mp.observe_property_bool("border", PropChangeBorder); core.observe_property_bool("border", PropChangeBorder);
mp.observe_property_string("sid", PropChangeSid); core.observe_property_string("sid", PropChangeSid);
mp.observe_property_string("aid", PropChangeAid); core.observe_property_string("aid", PropChangeAid);
mp.observe_property_string("vid", PropChangeVid); core.observe_property_string("vid", PropChangeVid);
mp.observe_property_int("edition", PropChangeEdition); core.observe_property_int("edition", PropChangeEdition);
mp.observe_property_double("window-scale", PropChangeWindowScale); core.observe_property_double("window-scale", PropChangeWindowScale);
if (mp.GPUAPI != "vulkan") if (core.GPUAPI != "vulkan")
mp.ProcessCommandLine(false); core.ProcessCommandLine(false);
AppDomain.CurrentDomain.UnhandledException += (sender, e) => App.ShowException(e.ExceptionObject); AppDomain.CurrentDomain.UnhandledException += (sender, e) => App.ShowException(e.ExceptionObject);
Application.ThreadException += (sender, e) => App.ShowException(e.Exception); Application.ThreadException += (sender, e) => App.ShowException(e.Exception);
@@ -82,10 +82,10 @@ namespace mpvnet
ContextMenu.Opened += ContextMenu_Opened; ContextMenu.Opened += ContextMenu_Opened;
ContextMenu.Opening += ContextMenu_Opening; ContextMenu.Opening += ContextMenu_Opening;
if (mp.Screen == -1) if (core.Screen == -1)
mp.Screen = Array.IndexOf(Screen.AllScreens, Screen.PrimaryScreen); core.Screen = Array.IndexOf(Screen.AllScreens, Screen.PrimaryScreen);
int targetIndex = mp.Screen; int targetIndex = core.Screen;
Screen[] screens = Screen.AllScreens; Screen[] screens = Screen.AllScreens;
if (targetIndex < 0) if (targetIndex < 0)
@@ -99,7 +99,7 @@ namespace mpvnet
Left = target.X + (target.Width - Width) / 2; Left = target.X + (target.Width - Width) / 2;
Top = target.Y + (target.Height - Height) / 2; Top = target.Y + (target.Height - Height) / 2;
if (!mp.Border) if (!core.Border)
FormBorderStyle = FormBorderStyle.None; FormBorderStyle = FormBorderStyle.None;
int posX = RegistryHelp.GetInt(App.RegPath, "PosX"); int posX = RegistryHelp.GetInt(App.RegPath, "PosX");
@@ -111,13 +111,13 @@ namespace mpvnet
Top = posY - Height / 2; Top = posY - Height / 2;
} }
if (mp.WindowMaximized) if (core.WindowMaximized)
{ {
SetFormPosAndSize(1, true); SetFormPosAndSize(1, true);
WindowState = FormWindowState.Maximized; WindowState = FormWindowState.Maximized;
} }
if (mp.WindowMinimized) if (core.WindowMinimized)
{ {
SetFormPosAndSize(1, true); SetFormPosAndSize(1, true);
WindowState = FormWindowState.Minimized; WindowState = FormWindowState.Minimized;
@@ -163,7 +163,7 @@ namespace mpvnet
void ContextMenu_Opening(object sender, CancelEventArgs e) void ContextMenu_Opening(object sender, CancelEventArgs e)
{ {
lock (mp.MediaTracks) lock (core.MediaTracks)
{ {
MenuItem trackMenuItem = FindMenuItem("Track"); MenuItem trackMenuItem = FindMenuItem("Track");
@@ -171,16 +171,16 @@ namespace mpvnet
{ {
trackMenuItem.DropDownItems.Clear(); trackMenuItem.DropDownItems.Clear();
MediaTrack[] audTracks = mp.MediaTracks.Where(track => track.Type == "a").ToArray(); MediaTrack[] audTracks = core.MediaTracks.Where(track => track.Type == "a").ToArray();
MediaTrack[] subTracks = mp.MediaTracks.Where(track => track.Type == "s").ToArray(); MediaTrack[] subTracks = core.MediaTracks.Where(track => track.Type == "s").ToArray();
MediaTrack[] vidTracks = mp.MediaTracks.Where(track => track.Type == "v").ToArray(); MediaTrack[] vidTracks = core.MediaTracks.Where(track => track.Type == "v").ToArray();
MediaTrack[] ediTracks = mp.MediaTracks.Where(track => track.Type == "e").ToArray(); MediaTrack[] ediTracks = core.MediaTracks.Where(track => track.Type == "e").ToArray();
foreach (MediaTrack track in vidTracks) foreach (MediaTrack track in vidTracks)
{ {
MenuItem mi = new MenuItem(track.Text); MenuItem mi = new MenuItem(track.Text);
mi.Action = () => mp.commandv("set", "vid", track.ID.ToString()); mi.Action = () => core.commandv("set", "vid", track.ID.ToString());
mi.Checked = mp.Vid == track.ID.ToString(); mi.Checked = core.Vid == track.ID.ToString();
trackMenuItem.DropDownItems.Add(mi); trackMenuItem.DropDownItems.Add(mi);
} }
@@ -190,8 +190,8 @@ namespace mpvnet
foreach (MediaTrack track in audTracks) foreach (MediaTrack track in audTracks)
{ {
MenuItem mi = new MenuItem(track.Text); MenuItem mi = new MenuItem(track.Text);
mi.Action = () => mp.commandv("set", "aid", track.ID.ToString()); mi.Action = () => core.commandv("set", "aid", track.ID.ToString());
mi.Checked = mp.Aid == track.ID.ToString(); mi.Checked = core.Aid == track.ID.ToString();
trackMenuItem.DropDownItems.Add(mi); trackMenuItem.DropDownItems.Add(mi);
} }
@@ -201,16 +201,16 @@ namespace mpvnet
foreach (MediaTrack track in subTracks) foreach (MediaTrack track in subTracks)
{ {
MenuItem mi = new MenuItem(track.Text); MenuItem mi = new MenuItem(track.Text);
mi.Action = () => mp.commandv("set", "sid", track.ID.ToString()); mi.Action = () => core.commandv("set", "sid", track.ID.ToString());
mi.Checked = mp.Sid == track.ID.ToString(); mi.Checked = core.Sid == track.ID.ToString();
trackMenuItem.DropDownItems.Add(mi); trackMenuItem.DropDownItems.Add(mi);
} }
if (subTracks.Length > 0) if (subTracks.Length > 0)
{ {
MenuItem mi = new MenuItem("S: No subtitles"); MenuItem mi = new MenuItem("S: No subtitles");
mi.Action = () => mp.commandv("set", "sid", "no"); mi.Action = () => core.commandv("set", "sid", "no");
mi.Checked = mp.Sid == "no"; mi.Checked = core.Sid == "no";
trackMenuItem.DropDownItems.Add(mi); trackMenuItem.DropDownItems.Add(mi);
} }
@@ -220,14 +220,14 @@ namespace mpvnet
foreach (MediaTrack track in ediTracks) foreach (MediaTrack track in ediTracks)
{ {
MenuItem mi = new MenuItem(track.Text); MenuItem mi = new MenuItem(track.Text);
mi.Action = () => mp.commandv("set", "edition", track.ID.ToString()); mi.Action = () => core.commandv("set", "edition", track.ID.ToString());
mi.Checked = mp.Edition == track.ID; mi.Checked = core.Edition == track.ID;
trackMenuItem.DropDownItems.Add(mi); trackMenuItem.DropDownItems.Add(mi);
} }
} }
} }
lock (mp.Chapters) lock (core.Chapters)
{ {
MenuItem chaptersMenuItem = FindMenuItem("Chapters"); MenuItem chaptersMenuItem = FindMenuItem("Chapters");
@@ -235,11 +235,11 @@ namespace mpvnet
{ {
chaptersMenuItem.DropDownItems.Clear(); chaptersMenuItem.DropDownItems.Clear();
foreach (var i in mp.Chapters) foreach (var i in core.Chapters)
{ {
MenuItem mi = new MenuItem(i.Key); MenuItem mi = new MenuItem(i.Key);
mi.ShortcutKeyDisplayString = TimeSpan.FromSeconds(i.Value).ToString().Substring(0, 8) + " "; mi.ShortcutKeyDisplayString = TimeSpan.FromSeconds(i.Value).ToString().Substring(0, 8) + " ";
mi.Action = () => mp.commandv("seek", i.Value.ToString(CultureInfo.InvariantCulture), "absolute"); mi.Action = () => core.commandv("seek", i.Value.ToString(CultureInfo.InvariantCulture), "absolute");
chaptersMenuItem.DropDownItems.Add(mi); chaptersMenuItem.DropDownItems.Add(mi);
} }
} }
@@ -252,7 +252,7 @@ namespace mpvnet
recent.DropDownItems.Clear(); recent.DropDownItems.Clear();
foreach (string path in RecentFiles) foreach (string path in RecentFiles)
MenuItem.Add(recent.DropDownItems, path, () => mp.LoadFiles(new[] { path }, true, Control.ModifierKeys.HasFlag(Keys.Control))); MenuItem.Add(recent.DropDownItems, path, () => core.LoadFiles(new[] { path }, true, Control.ModifierKeys.HasFlag(Keys.Control)));
recent.DropDownItems.Add(new ToolStripSeparator()); recent.DropDownItems.Add(new ToolStripSeparator());
MenuItem mi = new MenuItem("Clear List"); MenuItem mi = new MenuItem("Clear List");
@@ -287,7 +287,7 @@ namespace mpvnet
if (WindowState != FormWindowState.Normal) if (WindowState != FormWindowState.Normal)
return; return;
if (mp.Fullscreen) if (core.Fullscreen)
{ {
CycleFullscreen(true); CycleFullscreen(true);
return; return;
@@ -295,17 +295,17 @@ namespace mpvnet
} }
Screen screen = Screen.FromControl(this); Screen screen = Screen.FromControl(this);
int autoFitHeight = Convert.ToInt32(screen.WorkingArea.Height * mp.Autofit); int autoFitHeight = Convert.ToInt32(screen.WorkingArea.Height * core.Autofit);
if (mp.VideoSize.Height == 0 || mp.VideoSize.Width == 0 || if (core.VideoSize.Height == 0 || core.VideoSize.Width == 0 ||
mp.VideoSize.Width / (float)mp.VideoSize.Height < App.MinimumAspectRatio) core.VideoSize.Width / (float)core.VideoSize.Height < App.MinimumAspectRatio)
mp.VideoSize = new Size((int)(autoFitHeight * (16 / 9.0)), autoFitHeight); core.VideoSize = new Size((int)(autoFitHeight * (16 / 9.0)), autoFitHeight);
Size videoSize = mp.VideoSize; Size videoSize = core.VideoSize;
int height = videoSize.Height; int height = videoSize.Height;
if (mp.WasInitialSizeSet || scale != 1) if (core.WasInitialSizeSet || scale != 1)
height = ClientSize.Height; height = ClientSize.Height;
else else
{ {
@@ -317,7 +317,7 @@ namespace mpvnet
if (App.StartSize != "video") if (App.StartSize != "video")
height = autoFitHeight; height = autoFitHeight;
mp.WasInitialSizeSet = true; core.WasInitialSizeSet = true;
} }
height = Convert.ToInt32(height * scale); height = Convert.ToInt32(height * scale);
@@ -325,15 +325,15 @@ namespace mpvnet
int maxHeight = screen.WorkingArea.Height - (Height - ClientSize.Height); int maxHeight = screen.WorkingArea.Height - (Height - ClientSize.Height);
int maxWidth = screen.WorkingArea.Width - (Width - ClientSize.Width); int maxWidth = screen.WorkingArea.Width - (Width - ClientSize.Width);
if (height < maxHeight * mp.AutofitSmaller) if (height < maxHeight * core.AutofitSmaller)
{ {
height = Convert.ToInt32(maxHeight * mp.AutofitSmaller); height = Convert.ToInt32(maxHeight * core.AutofitSmaller);
width = Convert.ToInt32(height * videoSize.Width / (double)videoSize.Height); width = Convert.ToInt32(height * videoSize.Width / (double)videoSize.Height);
} }
if (height > maxHeight * mp.AutofitLarger) if (height > maxHeight * core.AutofitLarger)
{ {
height = Convert.ToInt32(maxHeight * mp.AutofitLarger); height = Convert.ToInt32(maxHeight * core.AutofitLarger);
width = Convert.ToInt32(height * videoSize.Width / (double)videoSize.Height); width = Convert.ToInt32(height * videoSize.Width / (double)videoSize.Height);
} }
@@ -374,7 +374,7 @@ namespace mpvnet
public void CycleFullscreen(bool enabled) public void CycleFullscreen(bool enabled)
{ {
LastCycleFullscreen = Environment.TickCount; LastCycleFullscreen = Environment.TickCount;
mp.Fullscreen = enabled; core.Fullscreen = enabled;
if (enabled) if (enabled)
{ {
@@ -401,7 +401,7 @@ namespace mpvnet
else else
WindowState = FormWindowState.Normal; WindowState = FormWindowState.Normal;
if (mp.Border) if (core.Border)
FormBorderStyle = FormBorderStyle.Sizable; FormBorderStyle = FormBorderStyle.Sizable;
else else
FormBorderStyle = FormBorderStyle.None; FormBorderStyle = FormBorderStyle.None;
@@ -414,7 +414,7 @@ namespace mpvnet
public void BuildMenu() public void BuildMenu()
{ {
string content = File.ReadAllText(mp.InputConfPath); string content = File.ReadAllText(core.InputConfPath);
var items = CommandItem.GetItems(content); var items = CommandItem.GetItems(content);
if (!content.Contains("#menu:")) if (!content.Contains("#menu:"))
@@ -438,7 +438,7 @@ namespace mpvnet
MenuItem menuItem = ContextMenu.Add(path, () => { MenuItem menuItem = ContextMenu.Add(path, () => {
try { try {
mp.command(item.Command); core.command(item.Command);
} catch (Exception ex) { } catch (Exception ex) {
Msg.ShowException(ex); Msg.ShowException(ex);
} }
@@ -451,19 +451,24 @@ namespace mpvnet
void FileLoaded() void FileLoaded()
{ {
string path = mp.get_property_string("path"); string path = core.get_property_string("path");
BeginInvoke(new Action(() => { BeginInvoke(new Action(() => {
if (path.Contains("://")) if (path.Contains("://"))
Text = mp.get_property_string("media-title") + " - mpv.net " + Application.ProductVersion; Text = core.get_property_string("media-title") + " - mpv.net " + Application.ProductVersion;
else if (path.Contains(":\\") || path.StartsWith("\\\\")) else if (path.Contains(":\\") || path.StartsWith("\\\\"))
Text = path.FileName() + " - mpv.net " + Application.ProductVersion; Text = path.FileName() + " - mpv.net " + Application.ProductVersion;
else else
Text = "mpv.net " + Application.ProductVersion; Text = "mpv.net " + Application.ProductVersion;
int interval = (int)(mp.Duration.TotalMilliseconds / 100); int interval = (int)(core.Duration.TotalMilliseconds / 100);
if (interval < 100) interval = 100;
if (interval > 1000) interval = 1000; if (interval < 100)
interval = 100;
if (interval > 1000)
interval = 1000;
ProgressTimer.Interval = interval; ProgressTimer.Interval = interval;
UpdateProgressBar(); UpdateProgressBar();
})); }));
@@ -510,19 +515,20 @@ namespace mpvnet
case 0x20A: // WM_MOUSEWHEEL case 0x20A: // WM_MOUSEWHEEL
case 0x100: // WM_KEYDOWN case 0x100: // WM_KEYDOWN
case 0x101: // WM_KEYUP case 0x101: // WM_KEYUP
case 0x102: // WM_CHAR
case 0x104: // WM_SYSKEYDOWN case 0x104: // WM_SYSKEYDOWN
case 0x105: // WM_SYSKEYUP case 0x105: // WM_SYSKEYUP
case 0x106: // WM_SYSCHAR
case 0x319: // WM_APPCOMMAND case 0x319: // WM_APPCOMMAND
if (mp.WindowHandle != IntPtr.Zero) if (core.WindowHandle != IntPtr.Zero)
m.Result = WinAPI.SendMessage(mp.WindowHandle, m.Msg, m.WParam, m.LParam); m.Result = WinAPI.SendMessage(core.WindowHandle, m.Msg, m.WParam, m.LParam);
if (m.Msg == 0x319) // WM_APPCOMMAND
return;
break; break;
case 0x0200: // WM_MOUSEMOVE case 0x0200: // WM_MOUSEMOVE
if (Environment.TickCount - LastCycleFullscreen > 500) if (Environment.TickCount - LastCycleFullscreen > 500)
{ {
Point pos = PointToClient(Cursor.Position); Point pos = PointToClient(Cursor.Position);
mp.command($"mouse {pos.X} {pos.Y}"); core.command($"mouse {pos.X} {pos.Y}");
} }
if (CursorHelp.IsPosDifferent(LastCursorPosition)) if (CursorHelp.IsPosDifferent(LastCursorPosition))
@@ -530,12 +536,12 @@ namespace mpvnet
break; break;
case 0x2a3: // WM_MOUSELEAVE case 0x2a3: // WM_MOUSELEAVE
//osc won't auto hide after mouse left window in borderless mode //osc won't auto hide after mouse left window in borderless mode
mp.command($"mouse {ClientSize.Width / 2} {ClientSize.Height / 3}"); core.command($"mouse {ClientSize.Width / 2} {ClientSize.Height / 3}");
break; break;
case 0x203: // WM_LBUTTONDBLCLK case 0x203: // WM_LBUTTONDBLCLK
{ {
Point pos = PointToClient(Cursor.Position); Point pos = PointToClient(Cursor.Position);
mp.command($"mouse {pos.X} {pos.Y} 0 double"); core.command($"mouse {pos.X} {pos.Y} 0 double");
} }
break; break;
case 0x02E0: // WM_DPICHANGED case 0x02E0: // WM_DPICHANGED
@@ -553,7 +559,7 @@ namespace mpvnet
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;
Size s = mp.VideoSize; Size s = core.VideoSize;
if (s == Size.Empty) if (s == Size.Empty)
s = new Size(16, 9); s = new Size(16, 9);
@@ -582,11 +588,11 @@ namespace mpvnet
switch (mode) switch (mode)
{ {
case "single": case "single":
mp.LoadFiles(files, true, Control.ModifierKeys.HasFlag(Keys.Control)); core.LoadFiles(files, true, Control.ModifierKeys.HasFlag(Keys.Control));
break; break;
case "queue": case "queue":
foreach (string file in files) foreach (string file in files)
mp.commandv("loadfile", file, "append"); core.commandv("loadfile", file, "append");
break; break;
} }
@@ -595,7 +601,7 @@ namespace mpvnet
return; return;
} }
if (m.Msg == TaskbarButtonCreatedMessage && mp.TaskbarProgress) if (m.Msg == TaskbarButtonCreatedMessage && core.TaskbarProgress)
{ {
Taskbar = new Taskbar(Handle); Taskbar = new Taskbar(Handle);
ProgressTimer.Start(); ProgressTimer.Start();
@@ -622,26 +628,26 @@ namespace mpvnet
void UpdateProgressBar() void UpdateProgressBar()
{ {
if (mp.TaskbarProgress && Taskbar != null) if (core.TaskbarProgress && Taskbar != null)
Taskbar.SetValue(mp.get_property_number("time-pos"), mp.Duration.TotalSeconds); Taskbar.SetValue(core.get_property_number("time-pos"), core.Duration.TotalSeconds);
} }
void PropChangeOnTop(bool value) => BeginInvoke(new Action(() => TopMost = value)); void PropChangeOnTop(bool value) => BeginInvoke(new Action(() => TopMost = value));
void PropChangeAid(string value) => mp.Aid = value; void PropChangeAid(string value) => core.Aid = value;
void PropChangeSid(string value) => mp.Sid = value; void PropChangeSid(string value) => core.Sid = value;
void PropChangeVid(string value) => mp.Vid = value; void PropChangeVid(string value) => core.Vid = value;
void PropChangeEdition(int value) => mp.Edition = value; void PropChangeEdition(int value) => core.Edition = value;
void PropChangeWindowScale(double value) void PropChangeWindowScale(double value)
{ {
if (value != 1) if (value != 1)
{ {
BeginInvoke(new Action(() => SetFormPosAndSize(value))); BeginInvoke(new Action(() => SetFormPosAndSize(value)));
mp.command("no-osd set window-scale 1"); core.command("no-osd set window-scale 1");
} }
} }
@@ -652,11 +658,11 @@ namespace mpvnet
BeginInvoke(new Action(() => BeginInvoke(new Action(() =>
{ {
mp.WindowMaximized = mp.get_property_bool("window-maximized"); core.WindowMaximized = core.get_property_bool("window-maximized");
if (mp.WindowMaximized && WindowState != FormWindowState.Maximized) if (core.WindowMaximized && WindowState != FormWindowState.Maximized)
WindowState = FormWindowState.Maximized; WindowState = FormWindowState.Maximized;
else if (!mp.WindowMaximized && WindowState == FormWindowState.Maximized) else if (!core.WindowMaximized && WindowState == FormWindowState.Maximized)
WindowState = FormWindowState.Normal; WindowState = FormWindowState.Normal;
})); }));
} }
@@ -668,25 +674,25 @@ namespace mpvnet
BeginInvoke(new Action(() => BeginInvoke(new Action(() =>
{ {
mp.WindowMinimized = mp.get_property_bool("window-minimized"); core.WindowMinimized = core.get_property_bool("window-minimized");
if (mp.WindowMinimized && WindowState != FormWindowState.Minimized) if (core.WindowMinimized && WindowState != FormWindowState.Minimized)
WindowState = FormWindowState.Minimized; WindowState = FormWindowState.Minimized;
else if (!mp.WindowMinimized && WindowState == FormWindowState.Minimized) else if (!core.WindowMinimized && WindowState == FormWindowState.Minimized)
WindowState = FormWindowState.Normal; WindowState = FormWindowState.Normal;
})); }));
} }
void PropChangeBorder(bool enabled) { void PropChangeBorder(bool enabled) {
mp.Border = enabled; core.Border = enabled;
BeginInvoke(new Action(() => { BeginInvoke(new Action(() => {
if (!IsFullscreen) if (!IsFullscreen)
{ {
if (mp.Border && FormBorderStyle == FormBorderStyle.None) if (core.Border && FormBorderStyle == FormBorderStyle.None)
FormBorderStyle = FormBorderStyle.Sizable; FormBorderStyle = FormBorderStyle.Sizable;
if (!mp.Border && FormBorderStyle == FormBorderStyle.Sizable) if (!core.Border && FormBorderStyle == FormBorderStyle.Sizable)
FormBorderStyle = FormBorderStyle.None; FormBorderStyle = FormBorderStyle.None;
} }
})); }));
@@ -694,7 +700,7 @@ namespace mpvnet
void PropChangePause(bool enabled) void PropChangePause(bool enabled)
{ {
if (Taskbar != null && mp.TaskbarProgress) if (Taskbar != null && core.TaskbarProgress)
{ {
if (enabled) if (enabled)
Taskbar.SetState(TaskbarStates.Paused); Taskbar.SetState(TaskbarStates.Paused);
@@ -707,8 +713,8 @@ namespace mpvnet
{ {
base.OnLoad(e); base.OnLoad(e);
if (mp.GPUAPI != "vulkan") if (core.GPUAPI != "vulkan")
mp.VideoSizeAutoResetEvent.WaitOne(App.StartThreshold); core.VideoSizeAutoResetEvent.WaitOne(App.StartThreshold);
LastCycleFullscreen = Environment.TickCount; LastCycleFullscreen = Environment.TickCount;
SetFormPosAndSize(); SetFormPosAndSize();
@@ -718,8 +724,8 @@ namespace mpvnet
{ {
base.OnShown(e); base.OnShown(e);
if (mp.GPUAPI == "vulkan") if (core.GPUAPI == "vulkan")
mp.ProcessCommandLine(false); core.ProcessCommandLine(false);
ToolStripRendererEx.ForegroundColor = Theme.Current.GetWinFormsColor("menu-foreground"); ToolStripRendererEx.ForegroundColor = Theme.Current.GetWinFormsColor("menu-foreground");
ToolStripRendererEx.BackgroundColor = Theme.Current.GetWinFormsColor("menu-background"); ToolStripRendererEx.BackgroundColor = Theme.Current.GetWinFormsColor("menu-background");
@@ -733,7 +739,7 @@ namespace mpvnet
System.Windows.Application.Current.ShutdownMode = System.Windows.ShutdownMode.OnExplicitShutdown; System.Windows.Application.Current.ShutdownMode = System.Windows.ShutdownMode.OnExplicitShutdown;
Cursor.Position = new Point(Cursor.Position.X + 1, Cursor.Position.Y); Cursor.Position = new Point(Cursor.Position.X + 1, Cursor.Position.Y);
UpdateCheck.DailyCheck(); UpdateCheck.DailyCheck();
mp.LoadScripts(); core.LoadScripts();
Task.Run(() => App.Extension = new Extension()); Task.Run(() => App.Extension = new Extension());
ShownTickCount = Environment.TickCount; ShownTickCount = Environment.TickCount;
} }
@@ -749,8 +755,8 @@ namespace mpvnet
{ {
base.OnResize(e); base.OnResize(e);
if (mp.IsLogoVisible) if (core.IsLogoVisible)
mp.ShowLogo(); core.ShowLogo();
if (FormBorderStyle != FormBorderStyle.None) if (FormBorderStyle != FormBorderStyle.None)
{ {
@@ -764,16 +770,16 @@ namespace mpvnet
{ {
if (WindowState == FormWindowState.Minimized) if (WindowState == FormWindowState.Minimized)
{ {
mp.set_property_string("window-minimized", "yes"); core.set_property_string("window-minimized", "yes");
} }
else if (WindowState == FormWindowState.Normal) else if (WindowState == FormWindowState.Normal)
{ {
mp.set_property_string("window-maximized", "no"); core.set_property_string("window-maximized", "no");
mp.set_property_string("window-minimized", "no"); core.set_property_string("window-minimized", "no");
} }
else if (WindowState == FormWindowState.Maximized) else if (WindowState == FormWindowState.Maximized)
{ {
mp.set_property_string("window-maximized", "yes"); core.set_property_string("window-maximized", "yes");
} }
} }
} }
@@ -784,16 +790,13 @@ namespace mpvnet
SaveWindowProperties(); SaveWindowProperties();
RegistryHelp.SetValue(App.RegPath, "Recent", RecentFiles.ToArray()); RegistryHelp.SetValue(App.RegPath, "Recent", RecentFiles.ToArray());
if (mp.IsQuitNeeded) if (core.IsQuitNeeded)
mp.commandv("quit"); core.commandv("quit");
if (!mp.ShutdownAutoResetEvent.WaitOne(10000)) if (!core.ShutdownAutoResetEvent.WaitOne(10000))
Msg.ShowError("Shutdown thread failed to complete within 10 seconds."); Msg.ShowError("Shutdown thread failed to complete within 10 seconds.");
try { // PowerShell 5.1 might not be available PowerShell.Shutdown();
foreach (PowerShell ps in PowerShell.Instances)
ps.Runspace.Dispose();
} catch {}
} }
protected override void OnMouseDown(MouseEventArgs e) protected override void OnMouseDown(MouseEventArgs e)
@@ -809,7 +812,7 @@ namespace mpvnet
} }
if (Width - e.Location.X < 10 && e.Location.Y < 10) if (Width - e.Location.X < 10 && e.Location.Y < 10)
mp.commandv("quit"); core.commandv("quit");
} }
protected override void OnDragEnter(DragEventArgs e) protected override void OnDragEnter(DragEventArgs e)
@@ -825,10 +828,10 @@ namespace mpvnet
base.OnDragDrop(e); base.OnDragDrop(e);
if (e.Data.GetDataPresent(DataFormats.FileDrop)) if (e.Data.GetDataPresent(DataFormats.FileDrop))
mp.LoadFiles(e.Data.GetData(DataFormats.FileDrop) as String[], true, Control.ModifierKeys.HasFlag(Keys.Control)); core.LoadFiles(e.Data.GetData(DataFormats.FileDrop) as String[], true, Control.ModifierKeys.HasFlag(Keys.Control));
if (e.Data.GetDataPresent(DataFormats.Text)) if (e.Data.GetDataPresent(DataFormats.Text))
mp.LoadFiles(new[] { e.Data.GetData(DataFormats.Text).ToString() }, true, Control.ModifierKeys.HasFlag(Keys.Control)); core.LoadFiles(new[] { e.Data.GetData(DataFormats.Text).ToString() }, true, Control.ModifierKeys.HasFlag(Keys.Control));
} }
protected override void OnLostFocus(EventArgs e) protected override void OnLostFocus(EventArgs e)
@@ -839,8 +842,10 @@ namespace mpvnet
protected override void OnKeyDown(KeyEventArgs e) protected override void OnKeyDown(KeyEventArgs e)
{ {
e.SuppressKeyPress = true; // prevent beep using alt key if (Control.ModifierKeys == Keys.Alt)
e.SuppressKeyPress = true; // prevent beep using alt key
base.OnKeyDown(e); base.OnKeyDown(e);
} }
} }
} }

View File

@@ -76,29 +76,6 @@
<GenerateSerializationAssemblies>Auto</GenerateSerializationAssemblies> <GenerateSerializationAssemblies>Auto</GenerateSerializationAssemblies>
</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="Microsoft.VisualBasic" /> <Reference Include="Microsoft.VisualBasic" />
<Reference Include="PresentationCore" /> <Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" /> <Reference Include="PresentationFramework" />
@@ -156,7 +133,7 @@
<Compile Include="Misc\UpdateCheck.cs" /> <Compile Include="Misc\UpdateCheck.cs" />
<Compile Include="Misc\RegistryHelp.cs" /> <Compile Include="Misc\RegistryHelp.cs" />
<Compile Include="Misc\Theme.cs" /> <Compile Include="Misc\Theme.cs" />
<Compile Include="Scripting\PowerShell.cs" /> <Compile Include="Misc\PowerShell.cs" />
<Compile Include="WPF\SearchTextBoxUserControl.xaml.cs"> <Compile Include="WPF\SearchTextBoxUserControl.xaml.cs">
<DependentUpon>SearchTextBoxUserControl.xaml</DependentUpon> <DependentUpon>SearchTextBoxUserControl.xaml</DependentUpon>
</Compile> </Compile>
@@ -179,7 +156,6 @@
<DesignTime>True</DesignTime> <DesignTime>True</DesignTime>
<DependentUpon>Resources.resx</DependentUpon> <DependentUpon>Resources.resx</DependentUpon>
</Compile> </Compile>
<Compile Include="Scripting\IronPython.cs" />
<Compile Include="mpv\libmpv.cs" /> <Compile Include="mpv\libmpv.cs" />
<Compile Include="WinForms\MainForm.cs"> <Compile Include="WinForms\MainForm.cs">
<SubType>Form</SubType> <SubType>Form</SubType>
@@ -188,8 +164,8 @@
<DependentUpon>MainForm.cs</DependentUpon> <DependentUpon>MainForm.cs</DependentUpon>
</Compile> </Compile>
<Compile Include="Misc\Misc.cs" /> <Compile Include="Misc\Misc.cs" />
<Compile Include="mpv\mp.cs" /> <Compile Include="mpv\Core.cs" />
<Compile Include="Misc\Command.cs" /> <Compile Include="Misc\Commands.cs" />
<Compile Include="Native\Native.cs" /> <Compile Include="Native\Native.cs" />
<Compile Include="Native\NativeHelp.cs" /> <Compile Include="Native\NativeHelp.cs" />
<Compile Include="Misc\Program.cs" /> <Compile Include="Misc\Program.cs" />

File diff suppressed because it is too large Load Diff

View File

@@ -44,6 +44,9 @@ public class libmpv
[DllImport("mpv-1.dll", CallingConvention = CallingConvention.Cdecl)] [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); 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_set_property(IntPtr mpvHandle, byte[] name, mpv_format format, ref double data);
[DllImport("mpv-1.dll", CallingConvention = CallingConvention.Cdecl)] [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); public static extern mpv_error mpv_observe_property(IntPtr mpvHandle, UInt64 reply_userdata, [MarshalAs(UnmanagedType.LPUTF8Str)] string name, mpv_format format);
@@ -149,9 +152,9 @@ public class libmpv
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Sequential)]
public struct mpv_event_log_message public struct mpv_event_log_message
{ {
public string prefix; public IntPtr prefix;
public string level; public IntPtr level;
public string text; public IntPtr text;
public mpv_log_level log_level; public mpv_log_level log_level;
} }

View File

@@ -8,9 +8,11 @@ using System.Linq;
class Script class Script
{ {
MainForm MainForm; MainForm MainForm;
Core core;
public Script() public Script()
{ {
core = Core.core;
MainForm = mpvnet.MainForm.Instance; MainForm = mpvnet.MainForm.Instance;
MainForm.ContextMenu.Opening += ContextMenu_Opening; MainForm.ContextMenu.Opening += ContextMenu_Opening;
} }
@@ -24,13 +26,13 @@ class Script
return; return;
menuItem.DropDownItems.Clear(); menuItem.DropDownItems.Clear();
var editionTracks = mp.MediaTracks.Where(track => track.Type == "e"); var editionTracks = core.MediaTracks.Where(track => track.Type == "e");
foreach (MediaTrack track in editionTracks) foreach (MediaTrack track in editionTracks)
{ {
MenuItem mi = new MenuItem(track.Text); MenuItem mi = new MenuItem(track.Text);
mi.Action = () => { mp.commandv("set", "edition", track.ID.ToString()); }; mi.Action = () => { core.commandv("set", "edition", track.ID.ToString()); };
mi.Checked = mp.Edition == track.ID; mi.Checked = core.Edition == track.ID;
menuItem.DropDownItems.Add(mi); menuItem.DropDownItems.Add(mi);
} }
} }

View File

@@ -11,9 +11,10 @@ class Script
{ {
string content = "ctrl+w script-message my-message-1 my-argument-1"; string content = "ctrl+w script-message my-message-1 my-argument-1";
string sectionName = Assembly.GetExecutingAssembly().GetName().Name; string sectionName = Assembly.GetExecutingAssembly().GetName().Name;
mp.commandv("define-section", sectionName, content, "force"); Core core = Core.core;
mp.commandv("enable-section", sectionName); core.commandv("define-section", sectionName, content, "force");
mp.ClientMessage += ClientMessage; core.commandv("enable-section", sectionName);
core.ClientMessage += ClientMessage;
} }
void ClientMessage(string[] args) void ClientMessage(string[] args)

View File

@@ -6,13 +6,16 @@ using mpvnet;
class Script class Script
{ {
Core core;
public Script() public Script()
{ {
mp.observe_property_bool("fullscreen", FullscreenChange); core = Core.core;
core.observe_property_bool("fullscreen", FullscreenChange);
} }
void FullscreenChange(bool value) void FullscreenChange(bool value)
{ {
mp.commandv("show-text", "fullscreen: " + value); core.commandv("show-text", "fullscreen: " + value);
} }
} }

View File

@@ -9,12 +9,14 @@ using mpvnet;
class Script class Script
{ {
MainForm Form; MainForm Form;
Core core;
bool WasPlaying; bool WasPlaying;
bool WasPaused; bool WasPaused;
public Script() public Script()
{ {
core = Core.core;
Form = MainForm.Instance; Form = MainForm.Instance;
Form.Resize += Form_Resize; Form.Resize += Form_Resize;
} }
@@ -23,11 +25,11 @@ class Script
{ {
if (Form.WindowState == FormWindowState.Minimized) if (Form.WindowState == FormWindowState.Minimized)
{ {
WasPlaying = !mp.get_property_bool("pause"); WasPlaying = !core.get_property_bool("pause");
if (WasPlaying) if (WasPlaying)
{ {
mp.set_property_bool("pause", true, true); core.set_property_bool("pause", true, true);
WasPaused = true; WasPaused = true;
} }
} }
@@ -35,7 +37,7 @@ class Script
{ {
if (WasPaused) if (WasPaused)
{ {
mp.set_property_bool("pause", false, true); core.set_property_bool("pause", false, true);
WasPaused = false; WasPaused = false;
} }
} }

View File

@@ -1,4 +0,0 @@
// This script shows a message box using the Msg class of mpv.net.
[Msg]::Show("Hello World")

View File

@@ -1,25 +0,0 @@
# Shows the Open File dialog to open a file without loading its folder into the playlist.
# In input.conf add: <key> script-message load-without-folder
$job = Register-ObjectEvent -InputObject ([mpvnet.mp]) -EventName ClientMessage -Action {
# exit if message does not equal 'load-without-folder'
if ($args.Length -ne 1 -or $args[0] -ne 'load-without-folder')
{
exit
}
$dialog = New-Object Windows.Forms.OpenFileDialog
if ($dialog.ShowDialog() -ne "OK") {
$dialog.Dispose()
exit
}
[mp]::Load($dialog.FileNames, $false, $false);
$dialog.Dispose()
}
$ScriptHost.RedirectEventJobStreams($job)

View File

@@ -1,8 +0,0 @@
# Display position in window title bar when seeking
$job = Register-ObjectEvent -InputObject ([mpvnet.mp]) -EventName Seek -Action {
[MainForm]::Instance.Text = [mp]::get_property_number("time-pos")
}
$ScriptHost.RedirectEventJobStreams($job)

View File

@@ -3,7 +3,6 @@
function showPlaylist() function showPlaylist()
{ {
// set font size // set font size
mp.set_property_number("osd-font-size", 40); mp.set_property_number("osd-font-size", 40);

View File

@@ -8,18 +8,16 @@
local did_minimize = false local did_minimize = false
mp.observe_property("window-minimized", "bool", function(name, value) mp.observe_property("window-minimized", "bool", function(name, value)
local pause = mp.get_property_bool("pause") local pause = mp.get_property_native("pause")
if value == true then if value == true then
if pause == false then if pause == false then
mp.set_property_bool("pause", true) mp.set_property_native("pause", true)
did_minimize = true did_minimize = true
end end
elseif value == false then elseif value == false then
if did_minimize and (pause == true) then if did_minimize and (pause == true) then
mp.set_property_bool("pause", false) mp.set_property_native("pause", false)
end end
did_minimize = false did_minimize = false
end end
end) end)

View File

@@ -0,0 +1,20 @@
# Shows the Open File dialog to open a file without loading its folder into the playlist.
# In input.conf add: <key> script-message load-without-folder
$code = {
if ($args[0] -eq 'load-without-folder')
{
$dialog = New-Object Windows.Forms.OpenFileDialog
if ($dialog.ShowDialog() -eq 'OK')
{
$core.LoadFiles($dialog.FileNames, $false, $false);
}
$dialog.Dispose()
}
}
$mp.register_event("client-message", $code)

View File

@@ -0,0 +1,27 @@
Set-Variable wasPaused $false -Option AllScope
$code = {
$isMinimized = $args[0]
$isPaused = $mp.get_property_bool('pause')
if ($isMinimized)
{
if (-not $isPaused)
{
$mp.set_property_bool('pause', $true)
$wasPaused = $true
}
}
else
{
if ($wasPaused -and $isPaused)
{
$mp.set_property_bool('pause', $false)
}
$wasPaused = $false
}
}
$mp.observe_property('window-minimized', 'bool', $code)