Compare commits

..

44 Commits
5.1 ... 5.4.2

Author SHA1 Message Date
Frank Skare
857926696c update changelog 2019-10-13 05:47:09 +02:00
Frank Skare
4451a6c185 5.4.2 2019-10-13 05:45:50 +02:00
Frank Skare
ea6a71b7c3 restore resulted in collapsed window when maximized = yes was used 2019-10-13 05:15:41 +02:00
Frank Skare
625dddcfbb clipboard monitoring feature removed because it was causing to many issues 2019-10-13 04:37:18 +02:00
Frank Skare
0cd769fc0c the log feature was not working 2019-10-13 04:12:48 +02:00
Frank Skare
f5e0c92824 new screenshot 2019-10-09 07:05:46 +02:00
Frank Skare
327a097bcf there was a sound when closed from taskbar due to a exception 2019-10-04 17:36:14 +02:00
Frank Skare
68626fa536 for URLs the media title is shown in the title bar 2019-10-01 01:19:01 +02:00
Frank Skare
8935101058 fix issue with clipboard url detection 2019-09-28 04:01:10 +02:00
Frank Skare
6947c925b9 Toggle Shuffle has been added to the menu defaults 2019-09-27 22:41:36 +02:00
Frank Skare
4562131078 support added for --list-properties 2019-09-20 04:45:24 +02:00
Frank Skare
21188f0942 test 2019-09-11 11:04:10 +02:00
Frank Skare
1316559ebc test 1 2019-09-11 11:02:43 +02:00
Frank Skare
cd576f9211 manual updated 2019-09-11 10:26:42 +02:00
Frank Skare
1bac8e8937 update changelog 2019-09-09 07:37:02 +02:00
Frank Skare
e6d0449f8f update changelog 2019-09-09 07:13:19 +02:00
Frank Skare
e0e40b7918 improved python error messages 2019-09-09 07:09:10 +02:00
Frank Skare
b59f16a425 improved PowerShell scrip host 2019-09-09 05:56:08 +02:00
Frank Skare
46b110d93b improved PowerShell scrip host 2019-09-09 00:46:08 +02:00
Frank Skare
7e8a654ada improved PowerShell scrip host 2019-09-08 22:16:58 +02:00
Frank Skare
c2c33228a0 a issue with the taskbar-progress feature was fixed 2019-09-06 04:32:39 +02:00
Frank Skare
0a28f13d51 5.4 Release 2019-09-05 19:00:54 +02:00
Frank Skare
9f3a1da931 fix relative file path not found 2019-09-05 09:12:19 +02:00
Frank Skare
05874ad6be update changelog 2019-09-05 08:15:13 +02:00
Frank Skare
078e8046bd added taskbar-progress implementation 2019-09-05 06:20:44 +02:00
Frank Skare
b07901485e fixed history being written even when history file wasn't created prior 2019-08-28 09:36:10 +02:00
Frank Skare
a37cbef8a8 long file names work now even if not enabled by the OS 2019-08-21 17:21:04 +02:00
Frank Skare
8debcc171c added new setting to start with maximized window 2019-08-21 16:52:09 +02:00
Frank Skare
e230f0f474 osc=yes and input-media-keys=yes was enforced, can now be disabled in mpv.conf 2019-08-16 19:37:07 +02:00
Frank Skare
558bd67591 update readme 2019-08-11 05:53:42 +02:00
Frank Skare
a7e4892acf update readme 2019-08-11 05:53:05 +02:00
Frank Skare
a0ba69c1aa readme update 2019-08-11 05:52:22 +02:00
Frank Skare
1e7e80577d 5.3 Release 2019-08-11 05:47:17 +02:00
Frank Skare
2177308b02 new config setting recent-count added 2019-08-11 04:58:42 +02:00
Frank Skare
a8c2409ed1 new menu items added to navigate to the first and last playlist position 2019-08-09 01:59:20 +02:00
Frank Skare
1ef9e64a41 scale, cscale, dscale defaults have been set to spline36 2019-08-08 19:07:27 +02:00
Frank Skare
f0546485cf Open > Open DVD/Blu-ray Drive/Folder 2019-08-08 18:45:34 +02:00
Frank Skare
032e91e4b4 mpv setting osd-scale-by-window added to config dialog 2019-08-08 03:31:57 +02:00
Frank Skare
1447636eb7 fixed race condition causing various features to fail 2019-08-07 13:16:05 +02:00
Frank Skare
966f96a02b 5.2 Release 2019-08-06 18:44:40 +02:00
Frank Skare
954c014708 bug fix for logo not shown on start 2019-08-06 01:49:51 +02:00
Frank Skare
ad30dc5ae2 command line processing was improved 2019-08-05 03:06:40 +02:00
Frank Skare
3f74344b99 terminal screenshot 2019-08-01 20:29:43 +02:00
Frank Skare
96d8d88d09 readme update 2019-08-01 12:54:15 +02:00
41 changed files with 797 additions and 487 deletions

View File

@@ -1,3 +1,71 @@
### 5.4.2
- new: the [scripting wiki page](https://github.com/stax76/mpv.net/wiki/Scripting#powershell) was improved
- new: Toggle Shuffle has been added to the menu defaults
- new: for URLs the media title is shown in the title bar and in the info command
instead of displaying the URL, mpv.conf defaults were changed to use
[protocol.https] osd-playing-msg = '${media-title}'
- fix: on the very first start volume was set to 0 and mute was set to yes
- fix: there was a sound when closed from taskbar
- fix: the log feature was not working
- fix: clipboard monitoring removed because it was causing to many issues
- fix: restore resulted in collapsed window when maximized = yes was used
- update: libmpv shinchiro 2019-10-06
- update: youtube-dl 2019-10-01
### 5.4.1.1
- a issue with the taskbar-progress feature was fixed
- improved PowerShell scrip host
### 5.4.1
- fix ArgumentOutOfRangeException
### 5.4
- added taskbar-progress implementation
- added new setting to start with maximized window
- long file paths work now even if not enabled by the OS
- fixed history being written even when history file wasn't created prior
- libmpv updated to shinchiro 2019-08-31
### 5.3
- added new feature: Open > Open DVD/Blu-ray Drive/Folder...
- the default of remember-volume has been set to yes
- scale, cscale, dscale defaults have been set to spline36,
profile=gpu-hq is not used in the defaults because it starts very slow
- new menu items have been added to navigate to the first and
last playlist position, key bindings: Home, End
- new config setting recent-count added, amount of menu items
shown under 'Open > Recent'
- in the config dialog the description for keep-open was corrected
because unlike mpv, mpv.net will never terminate automatically
- there was a rare occasion where the mpv.net logo wasn't shown
- fix excessive memory usage using `osd-scale-by-window = no`
- mpv setting osd-scale-by-window added to config dialog
### 5.2.1
- fixed race condition causing various features to fail
### 5.2
- bug fix for single-instance not working with unicode filenames
- bug fix for logo not shown on start
- osd-visibility.js script was removed because the OSC uses too much memory
- youtube-dl was updated
- libmpv was updated to shinchiro 2019-08-04
- in case mpv.net was started from a terminal it sets now the mpv property input-terminal to yes,
this means mpv.net will now receive and handle input keys from the terminal
- certain command line properties didn't work (input-terminal, terminal, input-file,
config, config-dir, input-conf, load-scripts, script, scripts, player-operation-mode)
- the about dialog shows now the mpv version and build date
- the dialog that asks for a config folder has now a cancel option
### 5.1 ### 5.1
- 'Tools > Execute mpv command' was replaced with [mpv-repl](https://github.com/rossy/mpv-repl) - 'Tools > Execute mpv command' was replaced with [mpv-repl](https://github.com/rossy/mpv-repl)
@@ -12,7 +80,7 @@
- 'Tools > Manage File Associations' was replaced by 'Tools > OS Setup', - 'Tools > Manage File Associations' was replaced by 'Tools > OS Setup',
it has now a feature to add and remove mpv.net to and from the Path it has now a feature to add and remove mpv.net to and from the Path
environment variable and the OS default apps settings can be opened (Win 10 only) environment variable and the OS default apps settings can be opened (Win 10 only)
- startup folder and config folder beeing identical was causing a critical issue - startup folder and config folder being identical was causing a critical issue
as mpv.net was loading extensions twice and scripts four times, now identical as mpv.net was loading extensions twice and scripts four times, now identical
folders are no longer permitted folders are no longer permitted
- error messages are shown when unknown scripts and extensions are found in the startup folder - error messages are shown when unknown scripts and extensions are found in the startup folder

View File

@@ -133,7 +133,7 @@ It's also possible to change the default application using the Open With feature
In order to play videos from sites such as YouTube the Chrome Extension [Play with mpv](https://chrome.google.com/webstore/detail/play-with-mpv/hahklcmnfgffdlchjigehabfbiigleji) can be used. In order to play videos from sites such as YouTube the Chrome Extension [Play with mpv](https://chrome.google.com/webstore/detail/play-with-mpv/hahklcmnfgffdlchjigehabfbiigleji) can be used.
Due to Chrome Extensions not being able to start a app, another app that communicates with the extension is required, this app can be downloaded [here](http://www.mediafire.com/file/6tmwdjsfknhmsxy/play-with-mpvnet-server.7z/file). The extension works only when the app is running, to have the app always running a link can be created in the auto start folder located at: Due to Chrome Extensions not being able to start a app, another app that communicates with the extension is required, this app can be downloaded [here](http://www.mediafire.com/file/lezj8lwqt5zf75v/play-with-mpvnet-server.7z/file). The extension works only when the app is running, to have the app always running a link can be created in the auto start folder located at:
`C:\Users\%username%\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup` `C:\Users\%username%\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup`
@@ -149,9 +149,11 @@ The Open Files menu entry is one way to open files in mpv.net, it supports multi
Another way to open files is the command line, it is used by the Windows File Explorer if file associations exist. Another way to open files is the command line, it is used by the Windows File Explorer if file associations exist.
When mpv.net is started from a terminal such as PowerShell, mpv.net attaches to the terminal and outputs status and debug messages.
A third way is to drag and drop files on the main window. A third way is to drag and drop files on the main window.
Whenever the control key is pressed when files are opened, the playlist is not cleared but the files are appended to the playlist. Whenever the control key is pressed when files or URLs are opened, the playlist is not cleared but the files or URLs are appended to the playlist. This works in all mpv.net features that open files or URLs.
### Open > Open URL ### Open > Open URL
@@ -159,7 +161,9 @@ The Open URL menu entry can be used to open URLs for example from YouTube.
mpv.net monitors the Windows clipboard and ask if URLs should be played in case it finds a URL in the clipboard. This feature uses a keyword whitelist that can be configured in the config editor. mpv.net monitors the Windows clipboard and ask if URLs should be played in case it finds a URL in the clipboard. This feature uses a keyword whitelist that can be configured in the config editor.
Whenever the control key is pressed when URLs are opened, the playlist is not cleared but the URLs are appended to the playlist. When mpv.net is started from a terminal such as PowerShell, mpv.net attaches to the terminal and outputs status and debug messages.
Whenever the control key is pressed when files or URLs are opened, the playlist is not cleared but the files or URLs are appended to the playlist. This works in all mpv.net features that open files or URLs.
### Open > Show media search ### Open > Show media search

View File

@@ -62,7 +62,8 @@ Table of contents
- Language agnostic JSON IPC to control the player with a external programs - Language agnostic JSON IPC to control the player with a external programs
- On Screen Controler (OSC, play control buttons) - On Screen Controler (OSC, play control buttons)
- [Command Line Interface](https://mpv.io/manual/master/#options) - [Command Line Interface](https://mpv.io/manual/master/#options)
- If started from a PowerShell terminal mpv.net will attach to the terminal and print status and debug output - If started from a PowerShell terminal mpv.net will attach to the terminal and print status and debug output ([Screenshot](#terminal-and-repl-screenshot))
- [OSD REPL](https://github.com/rossy/mpv-repl)
- DXVA2 video decoding acceleration - DXVA2 video decoding acceleration
- OpenGL based video output capable of features loved by videophiles, such as video scaling with popular high quality algorithms, color management, frame timing, interpolation, HDR, and more - OpenGL based video output capable of features loved by videophiles, such as video scaling with popular high quality algorithms, color management, frame timing, interpolation, HDR, and more
- Search feature powered by [Everything](https://www.voidtools.com) to find and play media ([Screenshot](#media-search-screenshot)) - Search feature powered by [Everything](https://www.voidtools.com) to find and play media ([Screenshot](#media-search-screenshot))
@@ -79,7 +80,7 @@ Table of contents
- Screenshot feature with many options - Screenshot feature with many options
- File history feature to log time and filename - File history feature to log time and filename
- A-B loop feature - A-B loop feature
- watch later feature to save the position - Watch later feature to save the position
- [Manual](#manual) - [Manual](#manual)
### Screenshots ### Screenshots
@@ -100,6 +101,12 @@ A searchable config editor as alternative to edit the mpv.conf file manually.
![](https://raw.githubusercontent.com/stax76/mpv.net/master/img/ConfEditor.png) ![](https://raw.githubusercontent.com/stax76/mpv.net/master/img/ConfEditor.png)
#### Terminal and REPL Screenshot
mpv.net attached to a PowerShell terminal showing the [OSD REPL](https://github.com/rossy/mpv-repl).
![](https://raw.githubusercontent.com/stax76/mpv.net/master/img/Terminal.png)
#### Input Editor Screenshot #### Input Editor Screenshot
A searchable key and mouse binding editor. A searchable key and mouse binding editor.

View File

@@ -30,13 +30,13 @@ namespace RatingExtension // the assembly name must end with 'Extension'
{ {
string filepath = i.Key; string filepath = i.Key;
int rating = i.Value; int rating = i.Value;
if (String.IsNullOrEmpty(filepath) || ! File.Exists(filepath)) if (String.IsNullOrEmpty(filepath) || !File.Exists(filepath))
return; return;
string basename = Path.GetFileNameWithoutExtension(filepath); string basename = Path.GetFileNameWithoutExtension(filepath);
for (int x = 0; x < 6; x++) for (int x = 0; x < 6; x++)
if (basename.Contains(" (" + x.ToString() + "stars)")) if (basename.Contains(" (" + x + "stars)"))
basename = basename.Replace(" (" + x.ToString() + "stars)", ""); basename = basename.Replace(" (" + x + "stars)", "");
basename += $" ({rating}stars)"; basename += $" ({rating}stars)";
string newPath = Path.Combine(Path.GetDirectoryName(filepath), basename + Path.GetExtension(filepath)); string newPath = Path.Combine(Path.GetDirectoryName(filepath), basename + Path.GetExtension(filepath));

View File

@@ -9,7 +9,7 @@
<AppDesignerFolder>Properties</AppDesignerFolder> <AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>RatingExtension</RootNamespace> <RootNamespace>RatingExtension</RootNamespace>
<AssemblyName>RatingExtension</AssemblyName> <AssemblyName>RatingExtension</AssemblyName>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion> <TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment> <FileAlignment>512</FileAlignment>
<TargetFrameworkProfile /> <TargetFrameworkProfile />
</PropertyGroup> </PropertyGroup>

View File

@@ -28,9 +28,9 @@ namespace ScriptingExtension // the file name of extensions must end with 'Exten
if (Directory.Exists(mp.ConfigFolder + "scripts")) if (Directory.Exists(mp.ConfigFolder + "scripts"))
scriptFiles.AddRange(Directory.GetFiles(mp.ConfigFolder + "scripts", "*.cs")); scriptFiles.AddRange(Directory.GetFiles(mp.ConfigFolder + "scripts", "*.cs"));
if (Directory.Exists(PathHelp.StartupPath + "scripts")) if (Directory.Exists(Folder.Startup + "scripts"))
foreach (string path in Directory.GetFiles(PathHelp.StartupPath + "scripts", "*.cs")) foreach (string path in Directory.GetFiles(Folder.Startup + "scripts", "*.cs"))
scriptFiles.AddRange(Directory.GetFiles(PathHelp.StartupPath + "scripts", "*.cs")); scriptFiles.AddRange(Directory.GetFiles(Folder.Startup + "scripts", "*.cs"));
if (scriptFiles.Count == 0) return; if (scriptFiles.Count == 0) return;
CSScriptLibrary.CSScript.EvaluatorConfig.Engine = EvaluatorEngine.CodeDom; CSScriptLibrary.CSScript.EvaluatorConfig.Engine = EvaluatorEngine.CodeDom;

View File

@@ -9,7 +9,7 @@
<AppDesignerFolder>Properties</AppDesignerFolder> <AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>ScriptingExtension</RootNamespace> <RootNamespace>ScriptingExtension</RootNamespace>
<AssemblyName>ScriptingExtension</AssemblyName> <AssemblyName>ScriptingExtension</AssemblyName>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion> <TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment> <FileAlignment>512</FileAlignment>
<TargetFrameworkProfile /> <TargetFrameworkProfile />
</PropertyGroup> </PropertyGroup>

View File

@@ -1,40 +1,17 @@
using System; using System.IO;
using System.Windows.Forms;
using mpvnet; using mpvnet;
class Script class Script
{ {
MainForm Form;
bool WasPlaying;
bool WasPaused;
public Script() public Script()
{ {
Form = MainForm.Instance; mp.Shutdown += Shutdown;
Form.Resize += Form_Resize;
} }
private void Form_Resize(object sender, EventArgs e) private void Shutdown()
{ {
if (Form.WindowState == FormWindowState.Minimized) foreach (string file in Directory.GetFiles(@"C:\Users\frank\Desktop\aaa"))
{ File.Delete(file);
WasPlaying = mp.get_property_string("pause") == "no";
if (WasPlaying)
{
mp.command("set pause yes");
WasPaused = true;
}
}
else
{
if (WasPaused)
{
mp.command("set pause no");
WasPaused = false;
}
}
} }
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 125 KiB

After

Width:  |  Height:  |  Size: 628 KiB

BIN
img/Terminal.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 MiB

View File

@@ -3,6 +3,6 @@
<configSections> <configSections>
</configSections> </configSections>
<startup> <startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2"/> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8"/>
</startup> </startup>
</configuration> </configuration>

View File

@@ -6,16 +6,15 @@ using System.Windows.Forms;
namespace mpvnet namespace mpvnet
{ {
public class App public static class App
{ {
public static string[] VideoTypes { get; } = "264 265 asf avc avi avs flv h264 h265 hevc m2ts m2v m4v mkv mov mp4 mpeg mpg mpv mts ts vob vpy webm webm wmv y4m".Split(' '); public static string[] VideoTypes { get; } = "264 265 asf avc avi avs flv h264 h265 hevc m2ts m2v m4v mkv mov mp4 mpeg mpg mpv mts ts vob vpy webm wmv y4m".Split(' ');
public static string[] AudioTypes { get; } = "mp3 mp2 ac3 ogg opus flac wav w64 m4a dts dtsma dtshr dtshd eac3 thd thd+ac3 mka aac mpa".Split(' '); public static string[] AudioTypes { get; } = "mp3 mp2 ac3 ogg opus flac wav w64 m4a dts dtsma dtshr dtshd eac3 thd thd+ac3 mka aac mpa".Split(' ');
public static string[] ImageTypes { get; } = {"jpg", "bmp", "gif", "png"}; public static string[] ImageTypes { get; } = {"jpg", "bmp", "gif", "png"};
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[] UrlWhitelist { get; set; } = { "tube", "vimeo", "ard", "zdf" };
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 => mp.ConfigFolder + "mpvnet.conf"; }
public static string DarkMode { get; set; } = "always"; public static string DarkMode { get; set; } = "always";
public static string ProcessInstance { get; set; } = "single"; public static string ProcessInstance { get; set; } = "single";
public static string DarkColor { get; set; } public static string DarkColor { get; set; }
@@ -23,16 +22,20 @@ namespace mpvnet
public static bool RememberHeight { get; set; } = true; public static bool RememberHeight { get; set; } = true;
public static bool RememberPosition { get; set; } public static bool RememberPosition { get; set; }
public static bool Maximized { get; set; }
public static bool DebugMode { get; set; } public static bool DebugMode { get; set; }
public static bool IsStartedFromTerminal { get; } = Environment.GetEnvironmentVariable("_started_from_console") == "yes"; public static bool IsStartedFromTerminal { get; } = Environment.GetEnvironmentVariable("_started_from_console") == "yes";
public static bool RememberVolume { get; set; } public static bool RememberVolume { get; set; } = true;
public static bool AutoLoadFolder { get; set; } = true; public static bool AutoLoadFolder { get; set; } = true;
public static bool ThemedMenu { get; set; } public static bool ThemedMenu { get; set; }
public static int StartThreshold { get; set; } = 1500; public static int StartThreshold { get; set; } = 1500;
public static int RecentCount { get; set; } = 15;
public static float MinimumAspectRatio { get; set; } = 1.3f; public static float MinimumAspectRatio { get; set; } = 1.3f;
public static Extension Extension { get; set; }
public static bool IsDarkMode { public static bool IsDarkMode {
get => (DarkMode == "system" && Sys.IsDarkTheme) || DarkMode == "always"; get => (DarkMode == "system" && Sys.IsDarkTheme) || DarkMode == "always";
} }
@@ -49,7 +52,7 @@ namespace mpvnet
{ {
try try
{ {
string filePath = mp.ConfigFolder + "\\mpvnet-debug.log"; string filePath = mp.ConfigFolder + "mpvnet-debug.log";
if (File.Exists(filePath)) File.Delete(filePath); if (File.Exists(filePath)) File.Delete(filePath);
Trace.Listeners.Add(new TextWriterTraceListener(filePath)); Trace.Listeners.Add(new TextWriterTraceListener(filePath));
Trace.AutoFlush = true; Trace.AutoFlush = true;
@@ -69,8 +72,8 @@ namespace mpvnet
{ {
if (RememberVolume) if (RememberVolume)
{ {
mp.set_property_int("volume", RegHelp.GetInt(App.RegPath, "Volume")); mp.set_property_int("volume", RegHelp.GetInt(App.RegPath, "Volume", 70));
mp.set_property_string("mute", RegHelp.GetString(App.RegPath, "Mute")); mp.set_property_string("mute", RegHelp.GetString(App.RegPath, "Mute", "no"));
} }
} }
@@ -105,18 +108,19 @@ namespace mpvnet
switch (name) switch (name)
{ {
case "remember-position": RememberPosition = value == "yes"; return true; case "remember-position": RememberPosition = value == "yes"; return true;
case "maximized": Maximized = value == "yes"; return true;
case "start-size": RememberHeight = value == "previous"; return true; case "start-size": RememberHeight = value == "previous"; return true;
case "process-instance": ProcessInstance = value; return true; case "process-instance": ProcessInstance = value; return true;
case "dark-mode": DarkMode = value; return true; case "dark-mode": DarkMode = value; return true;
case "debug-mode": DebugMode = value == "yes"; return true; case "debug-mode": DebugMode = value == "yes"; return true;
case "dark-color": DarkColor = value.Trim('\'', '"'); return true; case "dark-color": DarkColor = value.Trim('\'', '"'); return true;
case "light-color": LightColor = value.Trim('\'', '"'); return true; case "light-color": LightColor = value.Trim('\'', '"'); return true;
case "url-whitelist": UrlWhitelist = value.Split(' ', ',', ';'); return true;
case "remember-volume": RememberVolume = value == "yes"; return true; case "remember-volume": RememberVolume = value == "yes"; return true;
case "start-threshold": StartThreshold = value.Int(); return true; case "start-threshold": StartThreshold = value.Int(); return true;
case "minimum-aspect-ratio": MinimumAspectRatio = value.Float(); return true; case "minimum-aspect-ratio": MinimumAspectRatio = value.Float(); return true;
case "auto-load-folder": AutoLoadFolder = value == "yes"; return true; case "auto-load-folder": AutoLoadFolder = value == "yes"; return true;
case "themed-menu": ThemedMenu = value == "yes"; return true; case "themed-menu": ThemedMenu = value == "yes"; return true;
case "recent-count": RecentCount = value.Int(); return true;
} }
return false; return false;
} }

View File

@@ -16,11 +16,14 @@ namespace mpvnet
{ {
switch (id) switch (id)
{ {
case "manage-file-associations": ManageFileAssociations(); break; // deprecated 2019 case "open-files": OpenFiles(args); break;
case "open-url": OpenURL(); break;
case "open-optical-media": Open_DVD_Or_BD_Folder(); break;
case "manage-file-associations": // deprecated 2019
case "show-setup-dialog": ShowDialog(typeof(SetupWindow)); break;
case "cycle-audio": CycleAudio(); break; case "cycle-audio": CycleAudio(); break;
case "load-audio": LoadAudio(); break; case "load-audio": LoadAudio(); break;
case "load-sub": LoadSubtitle(); break; case "load-sub": LoadSubtitle(); break;
case "open-url": OpenURL(); break;
case "execute-mpv-command": ExecuteMpvCommand(); break; case "execute-mpv-command": ExecuteMpvCommand(); break;
case "show-history": ShowHistory(); break; case "show-history": ShowHistory(); break;
case "show-media-search": ShowDialog(typeof(EverythingWindow)); break; case "show-media-search": ShowDialog(typeof(EverythingWindow)); break;
@@ -28,14 +31,18 @@ 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 "show-setup-dialog": ShowDialog(typeof(SetupWindow)); break;
case "open-conf-folder": Process.Start(mp.ConfigFolder); break; case "open-conf-folder": Process.Start(mp.ConfigFolder); break;
case "open-files": OpenFiles(args); 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-last": PlaylistLast(); break;
case "add-files-to-playlist": OpenFiles("append"); break; // deprecated 2019 case "add-files-to-playlist": OpenFiles("append"); break; // deprecated 2019
default: Msg.ShowError($"No command '{id}' found."); break; default: Msg.ShowError($"No command '{id}' found."); break;
} }
MainForm.Instance.BeginInvoke(new Action(() => {
Message m = new Message() { Msg = 0x0202 }; // WM_LBUTTONUP
Native.SendMessage(MainForm.Instance.Handle, m.Msg, m.WParam, m.LParam);
}));
} }
public static void InvokeOnMainThread(Action action) => MainForm.Instance.Invoke(action); public static void InvokeOnMainThread(Action action) => MainForm.Instance.Invoke(action);
@@ -67,16 +74,44 @@ namespace mpvnet
})); }));
} }
public static void Open_DVD_Or_BD_Folder()
{
InvokeOnMainThread(new Action(() => {
using (var d = new FolderBrowserDialog())
{
d.Description = "Select a DVD or Blu-ray folder.";
d.ShowNewFolderButton = false;
if (d.ShowDialog() == DialogResult.OK)
{
if (Directory.Exists(d.SelectedPath + "\\BDMV"))
{
mp.set_property_string("bluray-device", d.SelectedPath);
mp.Load(new[] { @"bd://" }, false, false);
}
else
{
mp.set_property_string("dvd-device", d.SelectedPath);
mp.Load(new[] { @"dvd://" }, false, false);
}
}
}
}));
}
public static void PlaylistLast() => mp.set_property_int("playlist-pos", mp.get_property_int("playlist-count") - 1);
public static void ShowHistory() public static void ShowHistory()
{ {
var fp = mp.ConfigFolder + "history.txt"; if (File.Exists(mp.ConfigFolder + "history.txt"))
Process.Start(mp.ConfigFolder + "history.txt");
if (File.Exists(fp))
Process.Start(fp);
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(fp, "");
File.WriteAllText(mp.ConfigFolder + "history.txt", "");
}
} }
public static void ShowInfo() public static void ShowInfo()
@@ -86,6 +121,10 @@ 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 = mp.get_property_string("path");
if (path.Contains("://"))
path = mp.get_property_string("media-title");
int width = mp.get_property_int("video-params/w"); int width = mp.get_property_int("video-params/w");
int height = mp.get_property_int("video-params/h"); int height = mp.get_property_int("video-params/h");
@@ -146,7 +185,7 @@ namespace mpvnet
$"{width} x {height}\n"; $"{width} x {height}\n";
if (fileSize > 0) if (fileSize > 0)
text += Convert.ToInt32(fileSize / 1024.0 / 1024.0).ToString() + " MB\n"; text += Convert.ToInt32(fileSize / 1024.0 / 1024.0) + " MB\n";
text += $"{videoFormat}\n{audioCodec}"; text += $"{videoFormat}\n{audioCodec}";
@@ -230,7 +269,5 @@ namespace mpvnet
mp.commandv("show-text", audTracks[aid - 1].Text.Substring(3), "5000"); mp.commandv("show-text", audTracks[aid - 1].Text.Substring(3), "5000");
} }
} }
public static void ManageFileAssociations() => ShowDialog(typeof(SetupWindow)); // deprecated 2019
} }
} }

View File

@@ -19,7 +19,7 @@ namespace mpvnet
try try
{ {
AggregateCatalog catalog = new AggregateCatalog(); AggregateCatalog catalog = new AggregateCatalog();
string dir = PathHelp.StartupPath + "Extensions"; string dir = Folder.Startup + "Extensions";
if (Directory.Exists(dir)) if (Directory.Exists(dir))
{ {
@@ -34,7 +34,7 @@ namespace mpvnet
} }
} }
dir = mp.ConfigFolder + "Extensions"; dir = mp.ConfigFolder + "extensions";
if (Directory.Exists(dir)) if (Directory.Exists(dir))
foreach (string i in Directory.GetDirectories(dir)) foreach (string i in Directory.GetDirectories(dir))

View File

@@ -111,25 +111,25 @@ namespace mpvnet
rk.SetValue(name, value); rk.SetValue(name, value);
} }
public static string GetString(string path, string name) public static string GetString(string path, string name, string defaultValue = "")
{ {
object val = GetObject(path, name); object val = GetObject(path, name, defaultValue);
if (val == null || !(val is string)) return ""; if (val == null || !(val is string)) return "";
return val.ToString(); return val.ToString();
} }
public static int GetInt(string path, string name) public static int GetInt(string path, string name, int defaultValue = 0)
{ {
object val = GetObject(path, name); object val = GetObject(path, name, defaultValue);
if (val == null || !(val is int)) return 0; if (val == null || !(val is int)) return 0;
return (int)val; return (int)val;
} }
public static object GetObject(string path, string name) public static object GetObject(string path, string name, object defaultValue = null)
{ {
using (RegistryKey rk = GetRootKey(path).OpenSubKey(path.Substring(5))) using (RegistryKey rk = GetRootKey(path).OpenSubKey(path.Substring(5)))
if (rk != null) if (rk != null)
return rk.GetValue(name, ""); return rk.GetValue(name, defaultValue);
else else
return null; return null;
} }
@@ -291,8 +291,34 @@ namespace mpvnet
} }
} }
public class Folder
{
public static string Startup { get; } = Application.StartupPath + "\\";
}
public class PathHelp public class PathHelp
{ {
public static string StartupPath { get; } = Application.StartupPath + "\\"; public static string GetBaseName(string value)
{
if (string.IsNullOrEmpty(value))
return "";
int index = value.IndexOf("/");
if (index > -1)
value = value.Substring(index + 1);
index = value.IndexOf("\\");
if (index > -1)
value = value.Substring(index + 1);
index = value.LastIndexOf(".");
if (index > -1)
value = value.Substring(0, index);
return value;
}
} }
} }

View File

@@ -18,6 +18,8 @@ namespace mpvnet
Application.EnableVisualStyles(); Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false); Application.SetCompatibleTextRenderingDefault(false);
if (mp.ConfigFolder == "") return;
string[] args = Environment.GetCommandLineArgs().Skip(1).ToArray(); string[] args = Environment.GetCommandLineArgs().Skip(1).ToArray();
if (args.Length == 2 && args[0] == "--reg-file-assoc") if (args.Length == 2 && args[0] == "--reg-file-assoc")
@@ -38,7 +40,7 @@ namespace mpvnet
files.Add(App.ProcessInstance); files.Add(App.ProcessInstance);
foreach (string arg in args) foreach (string arg in args)
if (!arg.StartsWith("--") && (arg == "-" || arg.Contains("://") || File.Exists(arg))) if (!arg.StartsWith("--") && (arg == "-" || arg.Contains("://") || arg.Contains(":\\") || arg.StartsWith("\\\\")))
files.Add(arg); files.Add(arg);
Process[] procs = Process.GetProcessesByName("mpvnet"); Process[] procs = Process.GetProcessesByName("mpvnet");
@@ -64,7 +66,9 @@ namespace mpvnet
return; return;
} }
if (App.IsStartedFromTerminal) Native.AttachConsole(-1 /*ATTACH_PARENT_PROCESS*/); if (App.IsStartedFromTerminal)
Native.AttachConsole(-1 /*ATTACH_PARENT_PROCESS*/);
Application.Run(new MainForm()); Application.Run(new MainForm());
if (App.IsStartedFromTerminal) Native.FreeConsole(); if (App.IsStartedFromTerminal) Native.FreeConsole();
mutex.Dispose(); mutex.Dispose();

View File

@@ -10,7 +10,7 @@ public class MediaInfo : IDisposable
{ {
if (!Loaded) if (!Loaded)
{ {
if (LoadLibrary("MediaInfo.dll") == IntPtr.Zero) if (Native.LoadLibrary("MediaInfo.dll") == IntPtr.Zero)
throw new Exception("Failed to load MediaInfo.dll."); throw new Exception("Failed to load MediaInfo.dll.");
Loaded = true; Loaded = true;
@@ -56,21 +56,27 @@ public class MediaInfo : IDisposable
~MediaInfo() { Dispose(); } ~MediaInfo() { Dispose(); }
[DllImport("kernel32.dll", CharSet = CharSet.Unicode)] [DllImport("kernel32.dll")]
static extern IntPtr LoadLibrary(string path); public static extern IntPtr LoadLibrary(string path);
[DllImport("MediaInfo.dll")] [DllImport("MediaInfo.dll")]
static extern IntPtr MediaInfo_New(); static extern IntPtr MediaInfo_New();
[DllImport("MediaInfo.dll")] [DllImport("MediaInfo.dll", CharSet = CharSet.Unicode)]
static extern void MediaInfo_Delete(IntPtr handle); static extern int MediaInfo_Open(IntPtr handle, string path);
[DllImport("MediaInfo.dll", CharSet = CharSet.Unicode)] [DllImport("MediaInfo.dll", CharSet = CharSet.Unicode)]
static extern int MediaInfo_Open(IntPtr handle, string fileName); static extern IntPtr MediaInfo_Option(IntPtr handle, string optionString, string value);
[DllImport("MediaInfo.dll")]
static extern IntPtr MediaInfo_Inform(IntPtr handle, int reserved);
[DllImport("MediaInfo.dll")] [DllImport("MediaInfo.dll")]
static extern int MediaInfo_Close(IntPtr handle); static extern int MediaInfo_Close(IntPtr handle);
[DllImport("MediaInfo.dll")]
static extern void MediaInfo_Delete(IntPtr handle);
[DllImport("MediaInfo.dll", CharSet = CharSet.Unicode)] [DllImport("MediaInfo.dll", CharSet = CharSet.Unicode)]
static extern IntPtr MediaInfo_Get(IntPtr handle, static extern IntPtr MediaInfo_Get(IntPtr handle,
MediaInfoStreamKind streamKind, MediaInfoStreamKind streamKind,

View File

@@ -2,94 +2,94 @@
using System.Drawing; using System.Drawing;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
namespace mpvnet public class Native
{ {
public class Native [DllImport("kernel32.dll")]
public static extern bool AttachConsole(int dwProcessId);
[DllImport("kernel32.dll")]
public static extern bool FreeConsole();
[DllImport("kernel32.dll")]
public static extern IntPtr LoadLibrary(string path);
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
public static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter, string lclassName, string windowTitle);
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
public static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
public static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wParam, ref COPYDATASTRUCT lParam);
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
public static extern IntPtr PostMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
public static extern int RegisterWindowMessage(string id);
[DllImport("user32.dll")]
public static extern bool AllowSetForegroundWindow(int dwProcessId);
[DllImport("user32.dll")]
public static extern void ReleaseCapture();
[DllImport("user32.dll")]
public static extern bool AdjustWindowRect(ref RECT lpRect, uint dwStyle, bool bMenu);
[DllImport("user32.dll")]
public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, int uFlags);
[DllImport("user32.dll", EntryPoint = "GetWindowLong")]
private static extern IntPtr GetWindowLong32(IntPtr hWnd, int nIndex);
[DllImport("user32.dll", EntryPoint = "GetWindowLongPtr")]
private static extern IntPtr GetWindowLong64(IntPtr hWnd, int nIndex);
public static IntPtr GetWindowLong(IntPtr hWnd, int nIndex)
{ {
[DllImport("kernel32.dll")] if (IntPtr.Size == 8)
public static extern bool AttachConsole(int dwProcessId); return GetWindowLong64(hWnd, nIndex);
else
return GetWindowLong32(hWnd, nIndex);
}
[DllImport("kernel32.dll", SetLastError = true)] [StructLayout(LayoutKind.Sequential)]
public static extern bool FreeConsole(); public struct RECT
{
public int Left;
public int Top;
public int Right;
public int Bottom;
[DllImport("kernel32.dll")] public RECT(Rectangle r)
public static extern IntPtr LoadLibrary(string dllToLoad);
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
public static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter, string lclassName, string windowTitle);
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
public static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
public static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wParam, ref COPYDATASTRUCT lParam);
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern IntPtr PostMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll")]
public static extern bool AllowSetForegroundWindow(int dwProcessId);
[DllImport("user32.dll")]
public static extern void ReleaseCapture();
[DllImport("user32.dll")]
public static extern bool AdjustWindowRect(ref RECT lpRect, uint dwStyle, bool bMenu);
[DllImport("user32.dll", SetLastError = true)]
public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, int uFlags);
[DllImport("user32.dll", EntryPoint = "GetWindowLong")]
private static extern IntPtr GetWindowLong32(IntPtr hWnd, int nIndex);
[DllImport("user32.dll", EntryPoint = "GetWindowLongPtr")]
private static extern IntPtr GetWindowLong64(IntPtr hWnd, int nIndex);
public static IntPtr GetWindowLong(IntPtr hWnd, int nIndex)
{ {
if (IntPtr.Size == 8) Left = r.Left;
return GetWindowLong64(hWnd, nIndex); Top = r.Top;
else Right = r.Right;
return GetWindowLong32(hWnd, nIndex); Bottom = r.Bottom;
} }
[StructLayout(LayoutKind.Sequential)] public RECT(int left, int top, int right, int bottom)
public struct RECT
{ {
public int Left; Left = left;
public int Top; Top = top;
public int Right; Right = right;
public int Bottom; Bottom = bottom;
public RECT(Rectangle r)
{
Left = r.Left;
Top = r.Top;
Right = r.Right;
Bottom = r.Bottom;
}
public RECT(int left, int top, int right, int bottom)
{
Left = left;
Top = top;
Right = right;
Bottom = bottom;
}
public Rectangle ToRectangle() { return Rectangle.FromLTRB(Left, Top, Right, Bottom); }
public Size Size => new Size(Right - Left, Bottom - Top);
public int Width => Right - Left;
public int Height => Bottom - Top;
} }
[StructLayout(LayoutKind.Sequential)] public Rectangle ToRectangle() => Rectangle.FromLTRB(Left, Top, Right, Bottom);
public struct COPYDATASTRUCT public Size Size => new Size(Right - Left, Bottom - Top);
{ public int Width => Right - Left;
public IntPtr dwData; public int Height => Bottom - Top;
public int cbData; }
[MarshalAs(UnmanagedType.LPStr)]
public string lpData; [StructLayout(LayoutKind.Sequential)]
} public struct COPYDATASTRUCT
{
public IntPtr dwData;
public int cbData;
[MarshalAs(UnmanagedType.LPTStr)]
public string lpData;
} }
} }

View File

@@ -50,23 +50,23 @@ public class Msg
td.Show(); td.Show();
} }
} }
catch (Exception ex) catch (Exception e)
{ {
MessageBox.Show(ex.GetType().Name + "\n\n" + ex.Message + "\n\n" + ex.ToString(), MessageBox.Show(e.GetType().Name + "\n\n" + e.Message + "\n\n" + e,
Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error); Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
} }
} }
public static void ShowException(Exception e) public static void ShowException(Exception exception)
{ {
try try
{ {
using (TaskDialog<string> td = new TaskDialog<string>()) using (TaskDialog<string> td = new TaskDialog<string>())
{ {
td.MainInstruction = e.GetType().Name; td.MainInstruction = exception.GetType().Name;
td.Content = e.Message; td.Content = exception.Message;
td.MainIcon = MsgIcon.Error; td.MainIcon = MsgIcon.Error;
td.ExpandedInformation = e.ToString(); td.ExpandedInformation = exception.ToString();
td.Footer = "[Copy Message](copymsg)"; td.Footer = "[Copy Message](copymsg)";
if (!string.IsNullOrEmpty(Msg.SupportURL)) if (!string.IsNullOrEmpty(Msg.SupportURL))
@@ -75,9 +75,9 @@ public class Msg
td.Show(); td.Show();
} }
} }
catch (Exception ex) catch (Exception e)
{ {
MessageBox.Show(ex.GetType().Name + "\n\n" + ex.Message + "\n\n" + ex.ToString(), MessageBox.Show(e.GetType().Name + "\n\n" + e.Message + "\n\n" + e,
Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error); Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
} }
} }
@@ -144,9 +144,9 @@ public class Msg
return td.Show(); return td.Show();
} }
} }
catch (Exception ex) catch (Exception e)
{ {
return (MsgResult)MessageBox.Show(ex.GetType().Name + "\n\n" + ex.Message + "\n\n" + ex.ToString(), return (MsgResult)MessageBox.Show(e.GetType().Name + "\n\n" + e.Message + "\n\n" + e,
Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error); Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
} }
} }
@@ -235,6 +235,7 @@ public class TaskDialog<T> : TaskDialogNative, IDisposable
if (Path.GetFileName(lpszFileName.ToString().Replace(".vshost", "")) == if (Path.GetFileName(lpszFileName.ToString().Replace(".vshost", "")) ==
Path.GetFileName(Assembly.GetEntryAssembly().Location)) Path.GetFileName(Assembly.GetEntryAssembly().Location))
return foregroundWindow; return foregroundWindow;
return IntPtr.Zero; return IntPtr.Zero;
@@ -359,7 +360,7 @@ public class TaskDialog<T> : TaskDialogNative, IDisposable
public void AddCommandLink(string text, T value) public void AddCommandLink(string text, T value)
{ {
int n = 1000 + IdValueDic.Count + 1; int n = 1000 + IdValueDic.Count + 1;
IdValueDic[n] = value == null ? (T)(object)text : value; IdValueDic[n] = value;
IdTextDic[n] = text; IdTextDic[n] = text;
Buttons.Add(new TaskDialogNative.TASKDIALOG_BUTTON(n, text)); Buttons.Add(new TaskDialogNative.TASKDIALOG_BUTTON(n, text));
Config.dwFlags |= TaskDialogNative.TASKDIALOG_FLAGS.TDF_USE_COMMAND_LINKS; Config.dwFlags |= TaskDialogNative.TASKDIALOG_FLAGS.TDF_USE_COMMAND_LINKS;

53
mpv.net/Native/Taskbar.cs Normal file
View File

@@ -0,0 +1,53 @@
using System;
using System.Runtime.InteropServices;
public class Taskbar
{
private ITaskbarList3 Instance = (ITaskbarList3)new TaskBarCommunication();
public IntPtr Handle { get; set; }
public Taskbar(IntPtr handle) => Handle = handle;
[ComImportAttribute]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
[GuidAttribute("ea1afb91-9e28-4b86-90e9-9e9f8a5eefaf")]
private interface ITaskbarList3
{
// ITaskbarList
[PreserveSig] void HrInit();
[PreserveSig] void AddTab(IntPtr hwnd);
[PreserveSig] void DeleteTab(IntPtr hwnd);
[PreserveSig] void ActivateTab(IntPtr hwnd);
[PreserveSig] void SetActiveAlt(IntPtr hwnd);
// ITaskbarList2
[PreserveSig] void MarkFullscreenWindow(IntPtr hwnd, [MarshalAs(UnmanagedType.Bool)] bool fFullscreen);
// ITaskbarList3
[PreserveSig] void SetProgressValue(IntPtr hwnd, UInt64 ullCompleted, UInt64 ullTotal);
[PreserveSig] void SetProgressState(IntPtr hwnd, TaskbarStates state);
}
[ComImportAttribute]
[ClassInterfaceAttribute(ClassInterfaceType.None)]
[GuidAttribute("56FDF344-FD6D-11d0-958A-006097C9A090")]
private class TaskBarCommunication { }
public void SetState(TaskbarStates taskbarState)
{
Instance.SetProgressState(Handle, taskbarState);
}
public void SetValue(double progressValue, double progressMax)
{
Instance.SetProgressValue(Handle, (UInt64)progressValue, (UInt64)progressMax);
}
}
public enum TaskbarStates
{
NoProgress = 0,
Indeterminate = 0x1,
Normal = 0x2,
Error = 0x4,
Paused = 0x8
}

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.1.0.0")] [assembly: AssemblyVersion("5.4.2.0")]
[assembly: AssemblyFileVersion("5.1.0.0")] [assembly: AssemblyFileVersion("5.4.2.0")]

View File

@@ -62,19 +62,18 @@ namespace mpvnet.Properties {
/// <summary> /// <summary>
/// Looks up a localized string similar to /// Looks up a localized string similar to
/// # This file defines the input (keys and mouse) bindings of mpv and mpv.net /// # This file defines the key and mouse bindings and the context menu
/// # and it also defines the context menu of mpv.net. mpv.net has an input /// # of mpv.net. A input and config editor can be found in mpv.net&apos;s
/// # editor and an config editor as alternative to editing conf text files. /// # context menu under &apos;Settings&apos;. The defaults of this file can be found at:
/// # The input and config editor can be found in mpv.net&apos;s context menu at:
///
/// # Settings &gt; Show Config Editor
/// # Settings &gt; Show Input Editor
///
/// # The defaults of this file can be found at:
/// ///
/// # https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/inputConf.txt /// # https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/inputConf.txt
/// ///
/// # th [rest of string was truncated]&quot;;. /// # The defaults of mpv can be found at:
///
/// # https://github.com/mpv-player/mpv/blob/master/etc/input.conf
///
/// # mpv.net&apos;s defaults of mpv.conf contain: &apos;input-default-bindings = no&apos;
/// # which disables mpv&apos;s [rest of string was truncated]&quot;;.
/// </summary> /// </summary>
internal static string inputConf { internal static string inputConf {
get { get {
@@ -83,21 +82,21 @@ namespace mpvnet.Properties {
} }
/// <summary> /// <summary>
/// Looks up a localized string similar to /// Looks up a localized string similar to input-default-bindings = no
///# manual: https://mpv.io/manual/master/
///
///# defaults: https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/mpvConf.txt
///
///input-ar-delay = 500 ///input-ar-delay = 500
///input-ar-rate = 20 ///input-ar-rate = 20
///volume = 50
///hwdec = yes
///keep-open = yes ///keep-open = yes
///keep-open-pause = no ///keep-open-pause = no
///osd-playing-msg = &apos;${filename}&apos; ///osd-playing-msg = &apos;${filename}&apos;
///script-opts=osc-scalewindowed=1.5
///screenshot-directory = &apos;~~desktop/&apos; ///screenshot-directory = &apos;~~desktop/&apos;
///input-default-bindings = no ///cscale = spline36
///script-opts=osc-scalewindowed=1.5. ///dscale = spline36
///scale = spline36
///hwdec = yes
///
///[protocol.https]
///osd-playing-msg = &apos;${media-title}&apos;.
/// </summary> /// </summary>
internal static string mpvConf { internal static string mpvConf {
get { get {
@@ -143,24 +142,11 @@ namespace mpvnet.Properties {
/// <summary> /// <summary>
/// Looks up a localized string similar to [[settings]] /// Looks up a localized string similar to [[settings]]
///name = &quot;dark-mode&quot; ///name = &quot;process-instance&quot;
///default = &quot;always&quot; ///default = &quot;single&quot;
///filter = &quot;General&quot; ///filter = &quot;General&quot;
///help = &quot;Enables a dark theme. (mpv.net specific setting)&quot; ///help = &quot;Defines if more then one mpv.net process is allowed. (mpv.net specific setting)\n\nTip: Whenever the control key is pressed when files or URLs are opened, the playlist is not cleared but the files or URLs are appended to the playlist. This not only works on process startup but in all mpv.net features that open files and URLs.&quot;
///options = [{ name = &quot;always&quot; }, ///options = [{ name = &quot;multi&quot;, help = &quot;Create a new process everytime the shell starts mpv.net [rest of string was truncated]&quot;;.
/// { name = &quot;system&quot; , help = &quot;Available on Windows 10 or higher&quot; },
/// { name = &quot;never&quot; }]
///
///[[settings]]
///name = &quot;dark-color&quot;
///type = &quot;color&quot;
///filter = &quot;General&quot;
///help = &quot;Theme color used in dark-mode. Leave empty to use OS theme. (mpv.net specific setting)&quot;
///
///[[settings]]
///name = &quot;light-color&quot;
///type = &quot;color&quot;
///filter = &quot;General&quot; [rest of string was truncated]&quot;;.
/// </summary> /// </summary>
internal static string mpvNetConfToml { internal static string mpvNetConfToml {
get { get {

View File

@@ -12,7 +12,7 @@ namespace mpvnet.Properties {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.0.0.0")] [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.3.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));

View File

@@ -1,17 +1,11 @@
# This file defines the input (keys and mouse) bindings of mpv and mpv.net # This file defines the key and mouse bindings and the context menu
# and it also defines the context menu of mpv.net. mpv.net has an input # of mpv.net. A input and config editor can be found in mpv.net's
# editor and an config editor as alternative to editing conf text files. # context menu under 'Settings'. The defaults of this file can be found at:
# The input and config editor can be found in mpv.net's context menu at:
# Settings > Show Config Editor
# Settings > Show Input Editor
# The defaults of this file can be found at:
# https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/inputConf.txt # https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/inputConf.txt
# the defaults of mpv can be found at: # The defaults of mpv can be found at:
# https://github.com/mpv-player/mpv/blob/master/etc/input.conf # https://github.com/mpv-player/mpv/blob/master/etc/input.conf
@@ -26,16 +20,17 @@
# run mpv.net in input test mode with: mpvnet --input-test # run mpv.net in input test mode with: mpvnet --input-test
o script-message mpv.net open-files #menu: Open > Open Files... o script-message mpv.net open-files #menu: Open > Open Files...
u script-message mpv.net open-url #menu: Open > Open URL or file path from clipboard u script-message mpv.net open-url #menu: Open > Open URL or file path from clipboard
_ ignore #menu: Open > - _ script-message mpv.net open-optical-media #menu: Open > Open DVD/Blu-ray Drive/Folder...
Alt+a script-message mpv.net load-audio #menu: Open > Load external audio files... _ ignore #menu: Open > -
Alt+s script-message mpv.net load-sub #menu: Open > Load external subtitle files... Alt+a script-message mpv.net load-audio #menu: Open > Load external audio files...
_ ignore #menu: Open > - Alt+s script-message mpv.net load-sub #menu: Open > Load external subtitle files...
_ script-message mpv.net open-files append #menu: Open > Add files to playlist... _ ignore #menu: Open > -
F3 script-message mpv.net show-media-search #menu: Open > Show media search... _ script-message mpv.net open-files append #menu: Open > Add files to playlist...
_ ignore #menu: Open > - F3 script-message mpv.net show-media-search #menu: Open > Show media search...
_ ignore #menu: Open > Recent _ ignore #menu: Open > -
_ ignore #menu: Open > Recent
_ ignore #menu: - _ ignore #menu: -
Space cycle pause #menu: Play/Pause Space cycle pause #menu: Play/Pause
@@ -46,6 +41,9 @@
F11 playlist-prev #menu: Navigate > Previous File F11 playlist-prev #menu: Navigate > Previous File
F12 playlist-next #menu: Navigate > Next File F12 playlist-next #menu: Navigate > Next File
_ ignore #menu: Navigate > - _ ignore #menu: Navigate > -
Home set playlist-pos 0 #menu: Navigate > First File
End script-message mpv.net playlist-last #menu: Navigate > Last File
_ ignore #menu: Navigate > -
PGUP add chapter 1 #menu: Navigate > Next Chapter PGUP add chapter 1 #menu: Navigate > Next Chapter
PGDWN add chapter -1 #menu: Navigate > Previous Chapter PGDWN add chapter -1 #menu: Navigate > Previous Chapter
_ ignore #menu: Navigate > - _ ignore #menu: Navigate > -
@@ -153,6 +151,7 @@
Ctrl+r script-message-to repl type "" #menu: Tools > Show REPL Ctrl+r script-message-to repl type "" #menu: Tools > Show REPL
l ab-loop #menu: Tools > Set/clear A-B loop points l ab-loop #menu: Tools > Set/clear A-B loop points
L cycle-values loop-file "inf" "no" #menu: Tools > Toggle infinite file looping L cycle-values loop-file "inf" "no" #menu: Tools > Toggle infinite file looping
_ cycle shuffle #menu: Tools > Toggle Shuffle
Ctrl+h cycle-values hwdec "auto" "no" #menu: Tools > Toggle Hardware Decoding Ctrl+h cycle-values hwdec "auto" "no" #menu: Tools > Toggle Hardware Decoding
_ script-message mpv.net show-setup-dialog #menu: Tools > OS Setup... _ script-message mpv.net show-setup-dialog #menu: Tools > OS Setup...
@@ -199,4 +198,3 @@
Ctrl+Wheel_Down no-osd seek -7 Ctrl+Wheel_Down no-osd seek -7
MBTN_Left_DBL cycle fullscreen MBTN_Left_DBL cycle fullscreen
KP_Enter cycle fullscreen KP_Enter cycle fullscreen
MBTN_Left ignore

View File

@@ -1,10 +1,15 @@
input-ar-delay = 500 input-default-bindings = no
input-ar-delay = 500
input-ar-rate = 20 input-ar-rate = 20
volume = 50
hwdec = yes
keep-open = yes keep-open = yes
keep-open-pause = no keep-open-pause = no
osd-playing-msg = '${filename}' osd-playing-msg = '${filename}'
screenshot-directory = '~~desktop/'
input-default-bindings = no
script-opts=osc-scalewindowed=1.5 script-opts=osc-scalewindowed=1.5
screenshot-directory = '~~desktop/'
cscale = spline36
dscale = spline36
scale = spline36
hwdec = yes
[protocol.https]
osd-playing-msg = '${media-title}'

View File

@@ -23,10 +23,10 @@ options = [{ name = "no", help = "always use software decoding" },
name = "gpu-api" name = "gpu-api"
default = "auto" default = "auto"
filter = "Video" filter = "Video"
help = "Controls which type of graphics APIs will be accepted." help = "Controls which type of graphics APIs will be accepted. Auto uses d3d11, it should only be changed in case of problems, Vulkan is not recommended."
options = [{ name = "auto", help = "Use any available API" }, options = [{ name = "auto", help = "Use any available API" },
{ name = "opengl", help = "Allow only OpenGL (requires OpenGL 2.1+ or GLES 2.0+)" }, { name = "opengl", help = "Allow only OpenGL (requires OpenGL 2.1+ or GLES 2.0+)" },
{ name = "vulkan", help = "Allow only Vulkan (requires a valid/working spirv-compiler)" }, { name = "vulkan", help = "Allow only Vulkan (not recommended). " },
{ name = "d3d11", help = "Allow only gpu-context=d3d11" }] { name = "d3d11", help = "Allow only gpu-context=d3d11" }]
[[settings]] [[settings]]
@@ -241,6 +241,14 @@ default = "55"
filter = "Screen" filter = "Screen"
help = "Specify the OSD font size. See sub-font-size for details. Default: 55" help = "Specify the OSD font size. See sub-font-size for details. Default: 55"
[[settings]]
name = "osd-scale-by-window"
default = "yes"
filter = "Screen"
help = "Whether to scale the OSD with the window size. If this is disabled, osd-font-size and other OSD options that use scaled pixels are always in actual pixels. The effect is that changing the window size won't change the OSD font size."
options = [{ name = "yes" },
{ name = "no" }]
[[settings]] [[settings]]
name = "autofit" name = "autofit"
filter = "Screen" filter = "Screen"
@@ -283,7 +291,7 @@ options = [{ name = "yes" },
name = "screenshot-high-bit-depth" name = "screenshot-high-bit-depth"
default = "yes" default = "yes"
filter = "Screen" filter = "Screen"
help = "If possible, write screenshots with a bit depth similar to the source video (default: yes). This is interesting in particular for PNG, as this sometimes triggers writing 16 bit PNGs with huge file sizes. This will also include an unused alpha channel in the resulting files if 16 bit is used." help = "If possible, write screenshots with a bit depth similar to the source video. This is interesting in particular for PNG, as this sometimes triggers writing 16 bit PNGs with huge file sizes. This will also include an unused alpha channel in the resulting files if 16 bit is used."
options = [{ name = "yes" }, options = [{ name = "yes" },
{ name = "no" }] { name = "no" }]
@@ -291,7 +299,7 @@ options = [{ name = "yes" },
name = "screenshot-jpeg-source-chroma" name = "screenshot-jpeg-source-chroma"
default = "yes" default = "yes"
filter = "Screen" filter = "Screen"
help = "Write JPEG files with the same chroma subsampling as the video (default: yes). If disabled, the libjpeg default is used." help = "Write JPEG files with the same chroma subsampling as the video. If disabled, the libjpeg default is used."
options = [{ name = "yes" }, options = [{ name = "yes" },
{ name = "no" }] { name = "no" }]
@@ -317,6 +325,14 @@ name = "screenshot-png-filter"
filter = "Screen" filter = "Screen"
help = "<0-5> Set the filter applied prior to PNG compression. 0 is none, 1 is 'sub', 2 is 'up', 3 is 'average', 4 is 'Paeth', and 5 is 'mixed'. This affects the level of compression that can be achieved. For most images, 'mixed' achieves the best compression ratio, hence it is the default." help = "<0-5> Set the filter applied prior to PNG compression. 0 is none, 1 is 'sub', 2 is 'up', 3 is 'average', 4 is 'Paeth', and 5 is 'mixed'. This affects the level of compression that can be achieved. For most images, 'mixed' achieves the best compression ratio, hence it is the default."
[[settings]]
name = "taskbar-progress"
default = "yes"
filter = "Playback"
help = "Show progress in taskbar."
options = [{ name = "yes" },
{ name = "no" }]
[[settings]] [[settings]]
name = "keep-open-pause" name = "keep-open-pause"
default = "yes" default = "yes"
@@ -329,10 +345,10 @@ options = [{ name = "yes" },
name = "keep-open" name = "keep-open"
default = "no" default = "no"
filter = "Playback" filter = "Playback"
help = "Do not terminate when playing or seeking beyond the end of the file, and there is not next file to be played (and loop is not used). Instead, pause the player. When trying to seek beyond end of the file, the player will attempt to seek to the last frame.\n\nNormally, this will act like set pause yes on EOF, unless the keep-open-pause=no option is set." help = "Using no, mpv would terminate after the last file but mpv.net never terminates automatically."
options = [{ name = "yes", help = "Don't terminate if the current file is the last playlist entry. Equivalent to keep-open without arguments."}, options = [{ name = "yes", help = "If the current file ends, go to the next file, keep the last file open."},
{ name = "no", help = "If the current file ends, go to the next file or terminate." }, { name = "no", help = "If the current file ends, go to the next file." },
{ name = "always", help = "Like yes, but also applies to files before the last playlist entry. This means playback will never automatically advance to the next file."}] { name = "always", help = "Playback will never automatically advance to the next file."}]
[[settings]] [[settings]]
name = "loop-file" name = "loop-file"

View File

@@ -1,26 +1,16 @@
[[settings]] [[settings]]
name = "url-whitelist"
filter = "General"
type = "string"
help = "Whitelist setting to monitor the clipboard for URLs to play. (mpv.net specific setting)\n\nDefault: tube vimeo ard zdf\n\nHow to start mpv.net directly from Google Chrome is described in the manual:"
url = "https://github.com/stax76/mpv.net/blob/master/Manual.md#chrome-extension"
[[settings]]
name = "process-instance" name = "process-instance"
default = "single" default = "single"
filter = "General" filter = "General"
help = "Defines if more then one mpv.net process is allowed. (mpv.net specific setting)\n\nTip: Whenever the control key is pressed when files or URLs are opened, the playlist is not cleared but the files or URLs are appended to the playlist. This not only works on process startup but in all mpv.net features that open files." help = "Defines if more then one mpv.net process is allowed. (mpv.net specific setting)\n\nTip: Whenever the control key is pressed when files or URLs are opened, the playlist is not cleared but the files or URLs are appended to the playlist. This not only works on process startup but in all mpv.net features that open files and URLs."
options = [{ name = "multi", help = "Create a new process everytime the shell starts mpv.net" }, options = [{ name = "multi", help = "Create a new process everytime the shell starts mpv.net" },
{ name = "single", help = "Force a single process everytime the shell starts mpv.net" }, { name = "single", help = "Force a single process everytime the shell starts mpv.net" },
{ name = "queue", help = "Force a single process and add files to playlist" }] { name = "queue", help = "Force a single process and add files to playlist" }]
[[settings]] [[settings]]
name = "debug-mode" name = "recent-count"
default = "no"
filter = "General" filter = "General"
help = "Enable this only when a developer asks for it. (mpv.net specific setting)" help = "<int> Amount of recent files to be remembered. Default: 15 (mpv.net specific setting)"
options = [{ name = "yes" },
{ name = "no" }]
[[settings]] [[settings]]
name = "start-size" name = "start-size"
@@ -33,12 +23,12 @@ options = [{ name = "video", help = "Window size is set to native video resoluti
[[settings]] [[settings]]
name = "start-threshold" name = "start-threshold"
filter = "Screen" filter = "Screen"
help = "Threshold in milliseconds to wait for libmpv returning the video resolution before the window is shown, otherwise default dimensions are used as defined by autofit and start-size. (mpv.net specific setting) Default: 1500" help = "Threshold in milliseconds to wait for libmpv returning the video resolution before the window is shown, otherwise default dimensions are used as defined by autofit and start-size. Default: 1500 (mpv.net specific setting)"
[[settings]] [[settings]]
name = "minimum-aspect-ratio" name = "minimum-aspect-ratio"
filter = "Screen" filter = "Screen"
help = "<float> Minimum aspect ratio for the window. Default: 1.3" help = "<float> Minimum aspect ratio for the window. Default: 1.3 (mpv.net specific setting)"
[[settings]] [[settings]]
name = "remember-position" name = "remember-position"
@@ -49,8 +39,16 @@ options = [{ name = "yes" },
{ name = "no" }] { name = "no" }]
[[settings]] [[settings]]
name = "remember-volume" name = "maximized"
default = "no" default = "no"
filter = "Screen"
help = "Start with a maximized window. (mpv.net specific setting)"
options = [{ name = "yes" },
{ name = "no" }]
[[settings]]
name = "remember-volume"
default = "yes"
filter = "Audio" filter = "Audio"
help = "Save volume and mute on exit and restore it on start. (mpv.net specific setting)" help = "Save volume and mute on exit and restore it on start. (mpv.net specific setting)"
options = [{ name = "yes" }, options = [{ name = "yes" },
@@ -92,3 +90,11 @@ filter = "UI"
help = "Follow theme color in context menu. (mpv.net specific setting)" help = "Follow theme color in context menu. (mpv.net specific setting)"
options = [{ name = "yes" }, options = [{ name = "yes" },
{ name = "no" }] { name = "no" }]
[[settings]]
name = "debug-mode"
default = "no"
filter = "General"
help = "Enable this only when a developer asks for it. (mpv.net specific setting)"
options = [{ name = "yes" },
{ name = "no" }]

View File

@@ -3,13 +3,13 @@ using System.IO;
using System.Threading; using System.Threading;
using System.Management.Automation.Runspaces; using System.Management.Automation.Runspaces;
using System.Reflection; using System.Reflection;
using System.Threading.Tasks; using System.Management.Automation;
namespace mpvnet namespace mpvnet
{ {
public class PowerShellScript public class PowerShellScript
{ {
public static object Execute(string code, string[] parameters) public static void Execute(string filepath, params string[] parameters)
{ {
using (Runspace runspace = RunspaceFactory.CreateRunspace()) using (Runspace runspace = RunspaceFactory.CreateRunspace())
{ {
@@ -23,57 +23,53 @@ namespace mpvnet
"Using namespace System\n" + "Using namespace System\n" +
"[System.Reflection.Assembly]::LoadWithPartialName(\"mpvnet\")\n"); "[System.Reflection.Assembly]::LoadWithPartialName(\"mpvnet\")\n");
pipeline.Commands.AddScript(code); pipeline.Commands.AddScript(File.ReadAllText(filepath));
if (parameters != null) if (parameters != null)
foreach (var i in parameters) foreach (string i in parameters)
pipeline.Commands[1].Parameters.Add(null, i); pipeline.Commands[1].Parameters.Add(null, i);
try PowerShellOutput output = new PowerShellOutput();
{ output.ModuleName = Path.GetFileName(filepath);
var ret = pipeline.Invoke();
if (ret.Count > 0) return ret[0];
}
catch (Exception e)
{
try
{
using (Pipeline pipeline2 = runspace.CreatePipeline())
{
pipeline2.Commands.AddScript("$PSVersionTable.PSVersion.Major * 10 +" +
"$PSVersionTable.PSVersion.Minor");
if (Convert.ToInt32(pipeline2.Invoke()[0].ToString()) < 51) pipeline.Output.DataReady += output.Output_DataReady;
throw new Exception(); pipeline.Error.DataReady += output.Error_DataReady;
}
} runspace.SessionStateProxy.SetVariable("Output", output);
catch (Exception e2)
{ try {
Msg.ShowError("PowerShell Setup Problem\n\nEnsure you have at least PowerShell 5.1 installed.", e2.ToString()); pipeline.Invoke();
return null; }
} catch (RuntimeException e) {
Msg.ShowError("PowerShell Exception", e.Message + "\n\n" +
e.ErrorRecord.ScriptStackTrace.Replace(" <ScriptBlock>, <No file>", "") +
"\n\n" + Path.GetFileName(filepath));
}
catch (Exception e) {
Msg.ShowException(e); Msg.ShowException(e);
} }
pipeline.Output.DataReady -= output.Output_DataReady;
pipeline.Error.DataReady -= output.Error_DataReady;
} }
} }
return null;
} }
public static void Init(string filePath) public static void Init(string filepath)
{ {
foreach (var eventInfo in typeof(mp).GetEvents()) foreach (var eventInfo in typeof(mp).GetEvents())
{ {
if (eventInfo.Name.ToLower() == if (eventInfo.Name.ToLower() ==
Path.GetFileNameWithoutExtension(filePath).ToLower().Replace("-", "")) Path.GetFileNameWithoutExtension(filepath).ToLower().Replace("-", ""))
{ {
PowerShellEventObject eventObject = new PowerShellEventObject(); PowerShellEventObject eventObject = new PowerShellEventObject();
MethodInfo mi; MethodInfo mi;
eventObject.FilePath = filePath; eventObject.Filepath = filepath;
if (eventInfo.EventHandlerType == typeof(Action)) if (eventInfo.EventHandlerType == typeof(Action))
mi = eventObject.GetType().GetMethod(nameof(PowerShellEventObject.Invoke)); mi = eventObject.GetType().GetMethod(nameof(PowerShellEventObject.Invoke));
else if (eventInfo.EventHandlerType == typeof(Action<EndFileEventMode>)) else if (eventInfo.EventHandlerType == typeof(Action<EndFileEventMode>))
mi = eventObject.GetType().GetMethod(nameof(PowerShellEventObject.InvokeEndFileEventMode)); mi = eventObject.GetType().GetMethod(nameof(PowerShellEventObject.InvokeEndFile));
else if (eventInfo.EventHandlerType == typeof(Action<string[]>)) else if (eventInfo.EventHandlerType == typeof(Action<string[]>))
mi = eventObject.GetType().GetMethod(nameof(PowerShellEventObject.InvokeStrings)); mi = eventObject.GetType().GetMethod(nameof(PowerShellEventObject.InvokeStrings));
else else
@@ -86,7 +82,33 @@ namespace mpvnet
return; return;
} }
} }
Task.Run(() => PowerShellScript.Execute(File.ReadAllText(filePath), null)); Execute(filepath);
}
class PowerShellOutput
{
public string ModuleName { get; set; }
public bool WriteStandard { get; set; } = true;
public bool WriteError { get; set; } = true;
public void Output_DataReady(object sender, EventArgs e)
{
if (!WriteStandard) return;
var output = sender as PipelineReader<PSObject>;
while (output.Count > 0)
Console.WriteLine("[" + ModuleName + "] " + output.Read().ToString());
}
public void Error_DataReady(object sender, EventArgs e)
{
if (!WriteError) return;
var output = sender as PipelineReader<Object>;
Console.ForegroundColor = ConsoleColor.Red;
while (output.Count > 0)
Console.WriteLine("[" + ModuleName + "] " + output.Read().ToString());
Console.ResetColor();
}
} }
} }
@@ -94,18 +116,10 @@ namespace mpvnet
{ {
public EventInfo EventInfo { get; set; } public EventInfo EventInfo { get; set; }
public Delegate Delegate { get; set; } public Delegate Delegate { get; set; }
public string FilePath { get; set; } public string Filepath { get; set; }
public void Invoke() => Task.Run(() => { PowerShellScript.Execute(File.ReadAllText(FilePath), null); }); public void Invoke() => PowerShellScript.Execute(Filepath);
public void InvokeEndFile(EndFileEventMode arg) => PowerShellScript.Execute(Filepath, arg.ToString());
public void InvokeEndFileEventMode(EndFileEventMode arg) public void InvokeStrings(string[] args) => PowerShellScript.Execute(Filepath, args);
{
Task.Run(() => PowerShellScript.Execute(File.ReadAllText(FilePath), new [] { arg.ToString() }));
}
public void InvokeStrings(string[] args)
{
Task.Run(() => PowerShellScript.Execute(File.ReadAllText(FilePath), args));
}
} }
} }

View File

@@ -1,4 +1,5 @@
using System; using System;
using System.IO;
using System.Reflection; using System.Reflection;
using Microsoft.Scripting; using Microsoft.Scripting;
@@ -15,7 +16,7 @@ namespace mpvnet
ScriptEngine engine; ScriptEngine engine;
ScriptScope scope; ScriptScope scope;
public PythonScript(string code) public PythonScript(string scriptPath)
{ {
try try
{ {
@@ -26,14 +27,14 @@ namespace mpvnet
engine.Execute("clr.AddReference(\"mpvnet\")", scope); engine.Execute("clr.AddReference(\"mpvnet\")", scope);
engine.Execute("import mpvnet", scope); engine.Execute("import mpvnet", scope);
engine.Execute("from mpvnet import *", scope); engine.Execute("from mpvnet import *", scope);
engine.Execute(code, scope); engine.Execute(File.ReadAllText(scriptPath), scope);
} }
catch (Exception ex) catch (Exception ex)
{ {
if (ex is SyntaxErrorException e) if (ex is SyntaxErrorException e)
Msg.ShowError($"{e.Line}, {e.Column}: " + ex.Message); Msg.ShowError(e.GetType().Name,$"{e.Line}, {e.Column}: " + e.Message + "\n\n" + Path.GetFileName(scriptPath));
else else
Msg.ShowException(ex); Msg.ShowError(ex.GetType().Name, ex.Message + "\n\n" + Path.GetFileName(scriptPath));
} }
} }
} }

View File

@@ -4,13 +4,14 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" mc:Ignorable="d"
Title="About mpv.net" Height="230" Width="420" FontSize="16" ShowInTaskbar="False" Title="About mpv.net" Height="230" Width="400" FontSize="16" ShowInTaskbar="False"
WindowStartupLocation="CenterOwner" ResizeMode="NoResize"> WindowStartupLocation="CenterOwner" ResizeMode="NoResize">
<Grid> <Grid>
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center"> <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
<TextBlock FontSize="48" HorizontalAlignment="Center" Margin="0,0,0,10">mpv.net</TextBlock> <TextBlock FontSize="48" HorizontalAlignment="Center" Margin="0,0,0,10">mpv.net</TextBlock>
<TextBlock HorizontalAlignment="Center">Copyright (c) 2017-2019 Frank Skare (stax76)</TextBlock> <TextBlock HorizontalAlignment="Center">Copyright (c) 2017-2019 Frank Skare (stax76)</TextBlock>
<TextBlock Name="Version" HorizontalAlignment="Center" /> <TextBlock Name="Version" HorizontalAlignment="Center" />
<TextBlock Name="mpvVersion" HorizontalAlignment="Center" />
<TextBlock HorizontalAlignment="Center" Margin="0,0,0,20">MIT License</TextBlock> <TextBlock HorizontalAlignment="Center" Margin="0,0,0,20">MIT License</TextBlock>
</StackPanel> </StackPanel>
</Grid> </Grid>

View File

@@ -1,6 +1,6 @@
using System.Windows; using System.IO;
using System.Windows;
using System.Windows.Input; using System.Windows.Input;
using System.Windows.Media;
namespace mpvnet namespace mpvnet
{ {
@@ -9,7 +9,8 @@ namespace mpvnet
public AboutWindow() public AboutWindow()
{ {
InitializeComponent(); InitializeComponent();
Version.Text = $"Version {System.Windows.Forms.Application.ProductVersion}"; 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()})";
} }
protected override void OnPreviewKeyDown(KeyEventArgs e) => Close(); protected override void OnPreviewKeyDown(KeyEventArgs e) => Close();

View File

@@ -193,14 +193,14 @@ namespace mpvnet
{ {
SearchControl.SearchTextBox.SelectAll(); SearchControl.SearchTextBox.SelectAll();
Keyboard.Focus(SearchControl.SearchTextBox); Keyboard.Focus(SearchControl.SearchTextBox);
foreach (var i in MainStackPanel.Children.OfType<StringSettingControl>()) foreach (var i in MainStackPanel.Children.OfType<StringSettingControl>())
i.Update(); i.Update();
} }
private void FilterListBox_SelectionChanged(object sender, SelectionChangedEventArgs e) private void FilterListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{ {
if (e.AddedItems.Count > 0) if (e.AddedItems.Count > 0) SearchControl.Text = e.AddedItems[0] + ":";
SearchControl.Text = e.AddedItems[0].ToString() + ":";
} }
private void OpenSettingsTextBlock_MouseUp(object sender, MouseButtonEventArgs e) private void OpenSettingsTextBlock_MouseUp(object sender, MouseButtonEventArgs e)

View File

@@ -134,7 +134,6 @@ namespace mpvnet
StringBuilder buf = new StringBuilder(bufsize); StringBuilder buf = new StringBuilder(bufsize);
Everything_SetSearch(searchtext); Everything_SetSearch(searchtext);
Everything_SetRequestFlags(EVERYTHING_REQUEST_FILE_NAME | EVERYTHING_REQUEST_PATH); Everything_SetRequestFlags(EVERYTHING_REQUEST_FILE_NAME | EVERYTHING_REQUEST_PATH);
Everything_SetSort(EVERYTHING_SORT_SIZE_DESCENDING);
Everything_Query(true); Everything_Query(true);
for (i = 0; i < Everything_GetNumResults(); i++) for (i = 0; i < Everything_GetNumResults(); i++)

View File

@@ -44,7 +44,7 @@ namespace mpvnet
} catch {} } catch {}
for (int i = 0; i < 13; i++) for (int i = 0; i < 13; i++)
if ("D" + i.ToString() == text) if ("D" + i == text)
text = text.Substring(1); text = text.Substring(1);
switch (e.KeyCode) switch (e.KeyCode)
@@ -59,7 +59,7 @@ namespace mpvnet
case WF.Keys.NumPad7: case WF.Keys.NumPad7:
case WF.Keys.NumPad8: case WF.Keys.NumPad8:
case WF.Keys.NumPad9: case WF.Keys.NumPad9:
text = "KP" + e.KeyCode.ToString()[6].ToString(); break; text = "KP" + e.KeyCode.ToString()[6]; break;
case WF.Keys.Space: case WF.Keys.Space:
text = "Space"; break; text = "Space"; break;
case WF.Keys.Enter: case WF.Keys.Enter:

View File

@@ -30,14 +30,19 @@
{ {
this.components = new System.ComponentModel.Container(); this.components = new System.ComponentModel.Container();
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm)); System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm));
this.Timer = new System.Windows.Forms.Timer(this.components); this.CursorTimer = new System.Windows.Forms.Timer(this.components);
this.ProgressTimer = new System.Windows.Forms.Timer(this.components);
this.SuspendLayout(); this.SuspendLayout();
// //
// Timer // CursorTimer
// //
this.Timer.Enabled = true; this.CursorTimer.Enabled = true;
this.Timer.Interval = 1000; this.CursorTimer.Interval = 1000;
this.Timer.Tick += new System.EventHandler(this.Timer_Tick); this.CursorTimer.Tick += new System.EventHandler(this.CursorTimer_Tick);
//
// ProgressTimer
//
this.ProgressTimer.Tick += new System.EventHandler(this.ProgressTimer_Tick);
// //
// MainForm // MainForm
// //
@@ -45,7 +50,7 @@
this.AutoScaleDimensions = new System.Drawing.SizeF(288F, 288F); this.AutoScaleDimensions = new System.Drawing.SizeF(288F, 288F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi; this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi;
this.BackColor = System.Drawing.Color.Black; this.BackColor = System.Drawing.Color.Black;
this.ClientSize = new System.Drawing.Size(542, 0); this.ClientSize = new System.Drawing.Size(348, 0);
this.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); this.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
this.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4); this.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4);
@@ -57,6 +62,7 @@
#endregion #endregion
private System.Windows.Forms.Timer Timer; private System.Windows.Forms.Timer CursorTimer;
private System.Windows.Forms.Timer ProgressTimer;
} }
} }

View File

@@ -16,12 +16,12 @@ namespace mpvnet
{ {
public static MainForm Instance { get; set; } public static MainForm Instance { get; set; }
public static IntPtr Hwnd { get; set; } public static IntPtr Hwnd { get; set; }
public new ContextMenuStripEx ContextMenu { get; set; } public new ContextMenuStripEx ContextMenu { get; set; }
Point LastCursorPosChanged; Point LastCursorPosChanged;
int LastCursorChangedTickCount; int LastCursorChangedTickCount;
int TaskbarButtonCreatedMessage;
bool WasShown; bool WasShown;
Taskbar Taskbar;
List<string> RecentFiles; List<string> RecentFiles;
public MainForm() public MainForm()
@@ -33,10 +33,30 @@ namespace mpvnet
Instance = this; Instance = this;
Hwnd = Handle; Hwnd = Handle;
mp.Init(); mp.Init();
mp.Shutdown += Shutdown;
mp.VideoSizeChanged += VideoSizeChanged;
mp.FileLoaded += FileLoaded;
mp.Idle += Idle;
mp.Seek += () => UpdateProgressBar();
mp.observe_property_bool("pause", PropChangePause);
mp.observe_property_bool("fullscreen", PropChangeFullscreen);
mp.observe_property_bool("ontop", PropChangeOnTop);
mp.observe_property_bool("border", PropChangeBorder);
mp.observe_property_string("sid", PropChangeSid);
mp.observe_property_string("aid", PropChangeAid);
mp.observe_property_string("vid", PropChangeVid);
mp.observe_property_int("edition", PropChangeEdition);
if (mp.GPUAPI != "vulkan")
mp.ProcessCommandLine(false);
AppDomain.CurrentDomain.UnhandledException += (sender, e) => Msg.ShowError(e.ExceptionObject.ToString()); AppDomain.CurrentDomain.UnhandledException += (sender, e) => Msg.ShowError(e.ExceptionObject.ToString());
Application.ThreadException += (sender, e) => Msg.ShowException(e.Exception); Application.ThreadException += (sender, e) => Msg.ShowException(e.Exception);
Msg.SupportURL = "https://github.com/stax76/mpv.net#support"; Msg.SupportURL = "https://github.com/stax76/mpv.net#support";
Text = "mpv.net " + Application.ProductVersion; Text = "mpv.net " + Application.ProductVersion;
TaskbarButtonCreatedMessage = Native.RegisterWindowMessage("TaskbarButtonCreated");
object recent = RegHelp.GetObject(App.RegPath, "Recent"); object recent = RegHelp.GetObject(App.RegPath, "Recent");
@@ -49,11 +69,18 @@ namespace mpvnet
ContextMenu.Opened += ContextMenu_Opened; ContextMenu.Opened += ContextMenu_Opened;
ContextMenu.Opening += ContextMenu_Opening; ContextMenu.Opening += ContextMenu_Opening;
if (mp.Screen == -1) mp.Screen = Array.IndexOf(Screen.AllScreens, Screen.PrimaryScreen); if (mp.Screen == -1)
mp.Screen = Array.IndexOf(Screen.AllScreens, Screen.PrimaryScreen);
int targetIndex = mp.Screen; int targetIndex = mp.Screen;
Screen[] screens = Screen.AllScreens; Screen[] screens = Screen.AllScreens;
if (targetIndex < 0) targetIndex = 0;
if (targetIndex > screens.Length - 1) targetIndex = screens.Length - 1; if (targetIndex < 0)
targetIndex = 0;
if (targetIndex > screens.Length - 1)
targetIndex = screens.Length - 1;
Screen screen = screens[Array.IndexOf(screens, screens[targetIndex])]; Screen screen = screens[Array.IndexOf(screens, screens[targetIndex])];
Rectangle target = screen.Bounds; Rectangle target = screen.Bounds;
Left = target.X + (target.Width - Width) / 2; Left = target.X + (target.Width - Width) / 2;
@@ -68,21 +95,8 @@ namespace mpvnet
Top = posY - Height / 2; Top = posY - Height / 2;
} }
mp.Shutdown += Shutdown; if (App.Maximized)
mp.VideoSizeChanged += VideoSizeChanged; WindowState = FormWindowState.Maximized;
mp.FileLoaded += FileLoaded;
mp.Idle += Idle;
mp.observe_property_bool("fullscreen", PropChangeFullscreen);
mp.observe_property_bool("ontop", PropChangeOnTop);
mp.observe_property_bool("border", PropChangeBorder);
mp.observe_property_string("sid", PropChangeSid);
mp.observe_property_string("aid", PropChangeAid);
mp.observe_property_string("vid", PropChangeVid);
mp.observe_property_int("edition", PropChangeEdition);
if (mp.GPUAPI != "vulkan") mp.VideoSizeAutoResetEvent.WaitOne(App.StartThreshold);
if (Height < FontHeight * 4) SetFormPosAndSize();
} }
catch (Exception ex) catch (Exception ex)
{ {
@@ -92,19 +106,22 @@ namespace mpvnet
public MenuItem FindMenuItem(string text) => FindMenuItem(text, ContextMenu.Items); public MenuItem FindMenuItem(string text) => FindMenuItem(text, ContextMenu.Items);
void Idle() => BeginInvoke(new Action(() => Text = "mpv.net " + Application.ProductVersion)); void Shutdown() => BeginInvoke(new Action(() => Close()));
void Idle()
{
BeginInvoke(new Action(() => Text = "mpv.net " + Application.ProductVersion));
}
void CM_Popup(object sender, EventArgs e) => CursorHelp.Show(); void CM_Popup(object sender, EventArgs e) => CursorHelp.Show();
void VideoSizeChanged() => BeginInvoke(new Action(() => SetFormPosAndSize())); void VideoSizeChanged() => BeginInvoke(new Action(() => SetFormPosAndSize()));
void Shutdown() => BeginInvoke(new Action(() => Close()));
void PropChangeFullscreen(bool value) => BeginInvoke(new Action(() => CycleFullscreen(value))); void PropChangeFullscreen(bool value) => BeginInvoke(new Action(() => CycleFullscreen(value)));
void ContextMenu_Opened(object sender, EventArgs e) => CursorHelp.Show(); void ContextMenu_Opened(object sender, EventArgs e) => CursorHelp.Show();
bool IsFullscreen => WindowState == FormWindowState.Maximized; bool IsFullscreen => WindowState == FormWindowState.Maximized && FormBorderStyle == FormBorderStyle.None;
bool IsMouseInOSC() => PointToClient(Control.MousePosition).Y > ClientSize.Height * 0.9; bool IsMouseInOSC() => PointToClient(Control.MousePosition).Y > ClientSize.Height * 0.9;
@@ -126,7 +143,7 @@ namespace mpvnet
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 = () => mp.commandv("set", "vid", track.ID.ToString());
mi.Checked = mp.Vid == track.ID.ToString(); mi.Checked = mp.Vid == track.ID.ToString();
trackMenuItem.DropDownItems.Add(mi); trackMenuItem.DropDownItems.Add(mi);
} }
@@ -137,7 +154,7 @@ 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 = () => mp.commandv("set", "aid", track.ID.ToString());
mi.Checked = mp.Aid == track.ID.ToString(); mi.Checked = mp.Aid == track.ID.ToString();
trackMenuItem.DropDownItems.Add(mi); trackMenuItem.DropDownItems.Add(mi);
} }
@@ -148,7 +165,7 @@ 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 = () => mp.commandv("set", "sid", track.ID.ToString());
mi.Checked = mp.Sid == track.ID.ToString(); mi.Checked = mp.Sid == track.ID.ToString();
trackMenuItem.DropDownItems.Add(mi); trackMenuItem.DropDownItems.Add(mi);
} }
@@ -156,7 +173,7 @@ namespace mpvnet
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 = () => mp.commandv("set", "sid", "no");
mi.Checked = mp.Sid == "no"; mi.Checked = mp.Sid == "no";
trackMenuItem.DropDownItems.Add(mi); trackMenuItem.DropDownItems.Add(mi);
} }
@@ -167,7 +184,7 @@ 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 = () => mp.commandv("set", "edition", track.ID.ToString());
mi.Checked = mp.Edition == track.ID; mi.Checked = mp.Edition == track.ID;
trackMenuItem.DropDownItems.Add(mi); trackMenuItem.DropDownItems.Add(mi);
} }
@@ -186,7 +203,7 @@ namespace mpvnet
{ {
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 = () => mp.commandv("seek", i.Value.ToString(CultureInfo.InvariantCulture), "absolute");
chaptersMenuItem.DropDownItems.Add(mi); chaptersMenuItem.DropDownItems.Add(mi);
} }
} }
@@ -197,8 +214,10 @@ namespace mpvnet
if (recent != null) if (recent != null)
{ {
recent.DropDownItems.Clear(); recent.DropDownItems.Clear();
foreach (string path in RecentFiles) foreach (string path in RecentFiles)
MenuItem.Add(recent.DropDownItems, path, () => mp.Load(new[] { path }, true, Control.ModifierKeys.HasFlag(Keys.Control))); MenuItem.Add(recent.DropDownItems, path, () => mp.Load(new[] { path }, true, Control.ModifierKeys.HasFlag(Keys.Control)));
recent.DropDownItems.Add(new ToolStripSeparator()); recent.DropDownItems.Add(new ToolStripSeparator());
MenuItem mi = new MenuItem("Clear List"); MenuItem mi = new MenuItem("Clear List");
mi.Action = () => RecentFiles.Clear(); mi.Action = () => RecentFiles.Clear();
@@ -228,6 +247,9 @@ namespace mpvnet
void SetFormPosAndSize() void SetFormPosAndSize()
{ {
if (WindowState == FormWindowState.Maximized)
return;
if (mp.Fullscreen) if (mp.Fullscreen)
{ {
CycleFullscreen(true); CycleFullscreen(true);
@@ -320,7 +342,7 @@ namespace mpvnet
} }
else else
{ {
if (WindowState == FormWindowState.Maximized) if (WindowState == FormWindowState.Maximized && FormBorderStyle == FormBorderStyle.None)
{ {
WindowState = FormWindowState.Normal; WindowState = FormWindowState.Normal;
@@ -367,15 +389,25 @@ namespace mpvnet
private void FileLoaded() private void FileLoaded()
{ {
string path = mp.get_property_string("path"); string path = mp.get_property_string("path");
BeginInvoke(new Action(() => { BeginInvoke(new Action(() => {
if (File.Exists(path) || path.Contains("://")) if (path.Contains("://"))
Text = mp.get_property_string("media-title") + " - mpv.net " + Application.ProductVersion;
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);
if (interval < 100) interval = 100;
if (interval > 1000) interval = 1000;
ProgressTimer.Interval = interval;
UpdateProgressBar();
})); }));
if (RecentFiles.Contains(path)) RecentFiles.Remove(path); if (RecentFiles.Contains(path)) RecentFiles.Remove(path);
RecentFiles.Insert(0, path); RecentFiles.Insert(0, path);
if (RecentFiles.Count > 15) RecentFiles.RemoveAt(15); while (RecentFiles.Count > App.RecentCount) RecentFiles.RemoveAt(App.RecentCount);
} }
protected override CreateParams CreateParams { protected override CreateParams CreateParams {
@@ -388,7 +420,7 @@ namespace mpvnet
protected override void WndProc(ref Message m) protected override void WndProc(ref Message m)
{ {
//Debug.WriteLine(m); Debug.WriteLine(m);
switch (m.Msg) switch (m.Msg)
{ {
@@ -424,24 +456,31 @@ namespace mpvnet
} }
break; break;
case 0x02E0: // WM_DPICHANGED case 0x02E0: // WM_DPICHANGED
if (!WasShown) break; if (!WasShown)
break;
var r2 = Marshal.PtrToStructure<Native.RECT>(m.LParam); var r2 = Marshal.PtrToStructure<Native.RECT>(m.LParam);
Native.SetWindowPos(Handle, IntPtr.Zero, r2.Left, r2.Top, r2.Width, r2.Height, 0); Native.SetWindowPos(Handle, IntPtr.Zero, r2.Left, r2.Top, r2.Width, r2.Height, 0);
break; break;
case 0x112: // WM_SYSCOMMAND
if (m.WParam.ToInt32() == 0xf120) // SC_RESTORE
SetFormPosAndSize();
break;
case 0x0214: // WM_SIZING case 0x0214: // WM_SIZING
var rc = Marshal.PtrToStructure<Native.RECT>(m.LParam); var rc = Marshal.PtrToStructure<Native.RECT>(m.LParam);
var r = rc; var r = rc;
NativeHelp.SubtractWindowBorders(Handle, ref r); NativeHelp.SubtractWindowBorders(Handle, ref r);
int c_w = r.Right - r.Left, c_h = r.Bottom - r.Top; int c_w = r.Right - r.Left, c_h = r.Bottom - r.Top;
Size s = mp.VideoSize; Size s = mp.VideoSize;
if (s == Size.Empty) s = new Size(16, 9); if (s == Size.Empty)
s = new Size(16, 9);
float aspect = s.Width / (float)s.Height; float aspect = s.Width / (float)s.Height;
int d_w = Convert.ToInt32(c_h * aspect - c_w); int d_w = Convert.ToInt32(c_h * aspect - c_w);
int d_h = Convert.ToInt32(c_w / aspect - c_h); int d_h = Convert.ToInt32(c_w / aspect - c_h);
int[] d_corners = { d_w, d_h, -d_w, -d_h }; int[] d_corners = { d_w, d_h, -d_w, -d_h };
int[] corners = { rc.Left, rc.Top, rc.Right, rc.Bottom }; int[] corners = { rc.Left, rc.Top, rc.Right, rc.Bottom };
int corner = NativeHelp.GetResizeBorder(m.WParam.ToInt32()); int corner = NativeHelp.GetResizeBorder(m.WParam.ToInt32());
if (corner >= 0) corners[corner] -= d_corners[corner]; if (corner >= 0)
corners[corner] -= d_corners[corner];
Marshal.StructureToPtr<Native.RECT>(new Native.RECT(corners[0], corners[1], corners[2], corners[3]), m.LParam, false); Marshal.StructureToPtr<Native.RECT>(new Native.RECT(corners[0], corners[1], corners[2], corners[3]), m.LParam, false);
m.Result = new IntPtr(1); m.Result = new IntPtr(1);
return; return;
@@ -466,10 +505,16 @@ namespace mpvnet
return; return;
} }
if (m.Msg == TaskbarButtonCreatedMessage && mp.TaskbarProgress)
{
Taskbar = new Taskbar(Handle);
ProgressTimer.Start();
}
base.WndProc(ref m); base.WndProc(ref m);
} }
void Timer_Tick(object sender, EventArgs e) void CursorTimer_Tick(object sender, EventArgs e)
{ {
if (CursorHelp.IsPosDifferent(LastCursorPosChanged)) if (CursorHelp.IsPosDifferent(LastCursorPosChanged))
{ {
@@ -483,6 +528,14 @@ namespace mpvnet
CursorHelp.Hide(); CursorHelp.Hide();
} }
private void ProgressTimer_Tick(object sender, EventArgs e) => UpdateProgressBar();
void UpdateProgressBar()
{
if (mp.TaskbarProgress && Taskbar != null)
Taskbar.SetValue(mp.get_property_number("time-pos"), mp.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) => mp.Aid = value;
@@ -507,10 +560,28 @@ namespace mpvnet
})); }));
} }
void PropChangePause(bool enabled)
{
if (Taskbar != null && mp.TaskbarProgress)
{
if (enabled)
Taskbar.SetState(TaskbarStates.Paused);
else
Taskbar.SetState(TaskbarStates.Normal);
}
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
if (mp.GPUAPI != "vulkan") mp.VideoSizeAutoResetEvent.WaitOne(App.StartThreshold);
SetFormPosAndSize();
}
protected override void OnShown(EventArgs e) protected override void OnShown(EventArgs e)
{ {
base.OnShown(e); base.OnShown(e);
if (mp.GPUAPI == "vulkan") mp.ProcessCommandLine(); if (mp.GPUAPI == "vulkan") mp.ProcessCommandLine(false);
var wpfColor = WPF.WPF.ThemeColor; var wpfColor = WPF.WPF.ThemeColor;
Color color = Color.FromArgb(wpfColor.A, wpfColor.R, wpfColor.G, wpfColor.B); Color color = Color.FromArgb(wpfColor.A, wpfColor.R, wpfColor.G, wpfColor.B);
ToolStripRendererEx.InitColors(color, App.IsDarkMode, App.ThemedMenu); ToolStripRendererEx.InitColors(color, App.IsDarkMode, App.ThemedMenu);
@@ -518,25 +589,18 @@ namespace mpvnet
ContextMenuStrip = ContextMenu; ContextMenuStrip = ContextMenu;
WPF.WPF.Init(); WPF.WPF.Init();
System.Windows.Application.Current.ShutdownMode = System.Windows.ShutdownMode.OnExplicitShutdown; System.Windows.Application.Current.ShutdownMode = System.Windows.ShutdownMode.OnExplicitShutdown;
CheckClipboardForURL();
Cursor.Position = new Point(Cursor.Position.X + 1, Cursor.Position.Y); Cursor.Position = new Point(Cursor.Position.X + 1, Cursor.Position.Y);
WasShown = true; WasShown = true;
Task.Run(() => { mp.LoadScripts(); }); mp.LoadScripts();
Task.Run(() => { mp.Extension = new Extension(); }); Task.Run(() => App.Extension = new Extension());
}
protected override void OnActivated(EventArgs e)
{
base.OnActivated(e);
CheckClipboardForURL();
Message m = new Message() { Msg = 0x0202 }; // WM_LBUTTONUP
Native.SendMessage(Handle, m.Msg, m.WParam, m.LParam);
} }
protected override void OnResize(EventArgs e) protected override void OnResize(EventArgs e)
{ {
base.OnResize(e); base.OnResize(e);
if (mp.IsLogoVisible) mp.ShowLogo();
if (mp.IsLogoVisible)
mp.ShowLogo();
} }
protected override void OnFormClosing(FormClosingEventArgs e) protected override void OnFormClosing(FormClosingEventArgs e)
@@ -596,23 +660,5 @@ namespace mpvnet
base.OnLostFocus(e); base.OnLostFocus(e);
CursorHelp.Show(); CursorHelp.Show();
} }
void CheckClipboardForURL()
{
string clipboard = Clipboard.GetText();
foreach (string url in App.UrlWhitelist)
{
if (clipboard.Contains("://") && ! clipboard.Contains("\n") &&
! clipboard.Contains(" ") && clipboard.Contains(url.ToLower().Trim()) &&
RegHelp.GetString(App.RegPath, "LastURL") != clipboard && Visible)
{
RegHelp.SetObject(App.RegPath, "LastURL", clipboard);
if (Msg.ShowQuestion("Play URL?", clipboard) == MsgResult.OK)
mp.Load(new[] { clipboard }, true, Control.ModifierKeys.HasFlag(Keys.Control));
}
}
}
} }
} }

View File

@@ -117,9 +117,12 @@
<resheader name="writer"> <resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader> </resheader>
<metadata name="Timer.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"> <metadata name="CursorTimer.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>30, 12</value> <value>30, 12</value>
</metadata> </metadata>
<metadata name="ProgressTimer.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>321, 12</value>
</metadata>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" /> <assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> <data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value> <value>

View File

@@ -3,7 +3,6 @@ using System.Linq;
using System.ComponentModel; using System.ComponentModel;
using System.Drawing.Drawing2D; using System.Drawing.Drawing2D;
using System.Drawing.Text; using System.Drawing.Text;
using Microsoft.Win32;
using System.Windows.Forms; using System.Windows.Forms;
using System.Drawing; using System.Drawing;

View File

@@ -9,7 +9,7 @@
<AppDesignerFolder>Properties</AppDesignerFolder> <AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>mpvnet</RootNamespace> <RootNamespace>mpvnet</RootNamespace>
<AssemblyName>mpvnet</AssemblyName> <AssemblyName>mpvnet</AssemblyName>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion> <TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment> <FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects> <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<TargetFrameworkProfile /> <TargetFrameworkProfile />
@@ -153,6 +153,7 @@
<Compile Include="DynamicGUI\Tommy.cs" /> <Compile Include="DynamicGUI\Tommy.cs" />
<Compile Include="Misc\ExtensionMethods.cs" /> <Compile Include="Misc\ExtensionMethods.cs" />
<Compile Include="Native\MediaInfo.cs" /> <Compile Include="Native\MediaInfo.cs" />
<Compile Include="Native\Taskbar.cs" />
<Compile Include="WinForms\Menu.cs"> <Compile Include="WinForms\Menu.cs">
<SubType>Component</SubType> <SubType>Component</SubType>
</Compile> </Compile>

View File

@@ -16,7 +16,7 @@ using System.Windows.Forms;
using WinForms = System.Windows.Forms; using WinForms = System.Windows.Forms;
using static mpvnet.libmpv; using static mpvnet.libmpv;
using static mpvnet.Native; using static Native;
namespace mpvnet namespace mpvnet
{ {
@@ -61,17 +61,16 @@ namespace mpvnet
public static List<KeyValuePair<string, Action<string>>> StringPropChangeActions { get; set; } = new List<KeyValuePair<string, Action<string>>>(); public static List<KeyValuePair<string, Action<string>>> StringPropChangeActions { get; set; } = new List<KeyValuePair<string, Action<string>>>();
public static List<MediaTrack> MediaTracks { get; set; } = new List<MediaTrack>(); public static List<MediaTrack> MediaTracks { get; set; } = new List<MediaTrack>();
public static List<KeyValuePair<string, double>> Chapters { get; set; } = new List<KeyValuePair<string, double>>(); public static List<KeyValuePair<string, double>> Chapters { get; set; } = new List<KeyValuePair<string, double>>();
public static IntPtr Handle { get; set; } public static IntPtr Handle { get; set; }
public static IntPtr WindowHandle { get; set; } public static IntPtr WindowHandle { get; set; }
public static Extension Extension { get; set; }
public static List<PythonScript> PythonScripts { get; set; } = new List<PythonScript>(); public static List<PythonScript> PythonScripts { get; set; } = new List<PythonScript>();
public static Size VideoSize { get; set; } public static Size VideoSize { get; set; }
public static TimeSpan Duration;
public static AutoResetEvent ShutdownAutoResetEvent { get; set; } = new AutoResetEvent(false); public static AutoResetEvent ShutdownAutoResetEvent { get; set; } = new AutoResetEvent(false);
public static AutoResetEvent VideoSizeAutoResetEvent { get; set; } = new AutoResetEvent(false); public static AutoResetEvent VideoSizeAutoResetEvent { get; set; } = new AutoResetEvent(false);
public static string InputConfPath { get; } = ConfigFolder + "\\input.conf"; public static string InputConfPath { get => ConfigFolder + "input.conf"; }
public static string ConfPath { get; } = ConfigFolder + "\\mpv.conf"; public static string ConfPath { get => ConfigFolder + "mpv.conf"; }
public static string Sid { get; set; } = ""; public static string Sid { get; set; } = "";
public static string Aid { get; set; } = ""; public static string Aid { get; set; } = "";
public static string Vid { get; set; } = ""; public static string Vid { get; set; } = "";
@@ -81,6 +80,7 @@ namespace mpvnet
public static bool IsQuitNeeded { set; get; } = true; public static bool IsQuitNeeded { set; get; } = true;
public static bool Fullscreen { get; set; } public static bool Fullscreen { get; set; }
public static bool Border { get; set; } = true; public static bool Border { get; set; } = true;
public static bool TaskbarProgress { get; set; } = true;
public static int Screen { get; set; } = -1; public static int Screen { get; set; } = -1;
public static int Edition { get; set; } public static int Edition { get; set; }
@@ -93,26 +93,26 @@ namespace mpvnet
{ {
LoadLibrary("mpv-1.dll"); LoadLibrary("mpv-1.dll");
Handle = mpv_create(); Handle = mpv_create();
Task.Run(() => { EventLoop(); }); Task.Run(() => EventLoop());
if (App.IsStartedFromTerminal) if (App.IsStartedFromTerminal)
{ {
set_property_string("terminal", "yes"); set_property_string("terminal", "yes");
set_property_string("input-terminal", "yes");
set_property_string("msg-level", "osd/libass=fatal"); set_property_string("msg-level", "osd/libass=fatal");
} }
set_property_string("wid", MainForm.Hwnd.ToString()); set_property_string("wid", MainForm.Hwnd.ToString());
set_property_string("osc", "yes"); set_property_string("osc", "yes");
set_property_string("force-window", "yes");
set_property_string("input-media-keys", "yes"); set_property_string("input-media-keys", "yes");
set_property_string("force-window", "yes");
set_property_string("config-dir", ConfigFolder); set_property_string("config-dir", ConfigFolder);
set_property_string("config", "yes"); set_property_string("config", "yes");
ProcessCommandLine(true);
mpv_initialize(Handle); mpv_initialize(Handle);
Initialized?.Invoke(); Initialized?.Invoke();
ShowLogo();
LoadMpvScripts(); LoadMpvScripts();
if (GPUAPI != "vulkan") ProcessCommandLine();
} }
public static void ProcessProperty(string name, string value) public static void ProcessProperty(string name, string value)
@@ -136,6 +136,7 @@ namespace mpvnet
case "fs": case "fs":
case "fullscreen": Fullscreen = value == "yes"; break; case "fullscreen": Fullscreen = value == "yes"; break;
case "border": Border = value == "yes"; break; case "border": Border = value == "yes"; break;
case "taskbar-progress": TaskbarProgress = value == "yes"; break;
case "screen": Screen = Convert.ToInt32(value); break; case "screen": Screen = Convert.ToInt32(value); break;
case "gpu-api": GPUAPI = value; break; case "gpu-api": GPUAPI = value; break;
} }
@@ -147,7 +148,7 @@ namespace mpvnet
get { get {
if (_ConfigFolder == null) if (_ConfigFolder == null)
{ {
string portableFolder = PathHelp.StartupPath + "portable_config\\"; string portableFolder = Folder.Startup + "portable_config\\";
_ConfigFolder = portableFolder; _ConfigFolder = portableFolder;
if (!Directory.Exists(_ConfigFolder)) if (!Directory.Exists(_ConfigFolder))
@@ -165,10 +166,15 @@ namespace mpvnet
td.AddCommandLink(@"AppData\Roaming\mpv", appdataFolderMpv, appdataFolderMpv); td.AddCommandLink(@"AppData\Roaming\mpv", appdataFolderMpv, appdataFolderMpv);
td.AddCommandLink("<startup>\\portable_config", portableFolder, portableFolder); td.AddCommandLink("<startup>\\portable_config", portableFolder, portableFolder);
td.AddCommandLink("Choose custom folder", "custom"); td.AddCommandLink("Choose custom folder", "custom");
td.AllowCancel = false;
_ConfigFolder = td.Show(); _ConfigFolder = td.Show();
} }
if (_ConfigFolder == null)
{
_ConfigFolder = "";
return "";
}
if (_ConfigFolder == "custom") if (_ConfigFolder == "custom")
{ {
using (var d = new WinForms.FolderBrowserDialog()) using (var d = new WinForms.FolderBrowserDialog())
@@ -183,7 +189,7 @@ namespace mpvnet
} }
} }
if (PathHelp.StartupPath == _ConfigFolder) if (Folder.Startup == _ConfigFolder)
{ {
Msg.ShowError("Startup folder and config folder cannot be identical, using portable_config instead."); Msg.ShowError("Startup folder and config folder cannot be identical, using portable_config instead.");
_ConfigFolder = portableFolder; _ConfigFolder = portableFolder;
@@ -195,14 +201,14 @@ namespace mpvnet
if (!_ConfigFolder.Contains("portable_config")) if (!_ConfigFolder.Contains("portable_config"))
RegHelp.SetObject(App.RegPath, "ConfigFolder", _ConfigFolder); RegHelp.SetObject(App.RegPath, "ConfigFolder", _ConfigFolder);
if (!File.Exists(_ConfigFolder + "\\input.conf")) if (!File.Exists(_ConfigFolder + "input.conf"))
File.WriteAllText(_ConfigFolder + "\\input.conf", Properties.Resources.inputConf); File.WriteAllText(_ConfigFolder + "input.conf", Properties.Resources.inputConf);
if (!File.Exists(_ConfigFolder + "\\mpv.conf")) if (!File.Exists(_ConfigFolder + "mpv.conf"))
File.WriteAllText(_ConfigFolder + "\\mpv.conf", Properties.Resources.mpvConf); File.WriteAllText(_ConfigFolder + "mpv.conf", Properties.Resources.mpvConf);
if (!File.Exists(_ConfigFolder + "\\mpvnet.conf")) if (!File.Exists(_ConfigFolder + "mpvnet.conf"))
File.WriteAllText(_ConfigFolder + "\\mpvnet.conf", Properties.Resources.mpvNetConf); File.WriteAllText(_ConfigFolder + "mpvnet.conf", Properties.Resources.mpvNetConf);
} }
return _ConfigFolder; return _ConfigFolder;
} }
@@ -230,9 +236,9 @@ namespace mpvnet
public static void LoadMpvScripts() public static void LoadMpvScripts()
{ {
if (Directory.Exists(PathHelp.StartupPath + "Scripts")) if (Directory.Exists(Folder.Startup + "Scripts"))
{ {
string[] startupScripts = Directory.GetFiles(PathHelp.StartupPath + "Scripts"); string[] startupScripts = Directory.GetFiles(Folder.Startup + "Scripts");
foreach (string path in startupScripts) foreach (string path in startupScripts)
if ((path.EndsWith(".lua") || path.EndsWith(".js")) && KnownScripts.Contains(Path.GetFileName(path))) if ((path.EndsWith(".lua") || path.EndsWith(".js")) && KnownScripts.Contains(Path.GetFileName(path)))
@@ -244,28 +250,28 @@ namespace mpvnet
public static void LoadScripts() public static void LoadScripts()
{ {
if (Directory.Exists(PathHelp.StartupPath + "Scripts")) if (Directory.Exists(Folder.Startup + "Scripts"))
{ {
foreach (string path in Directory.GetFiles(PathHelp.StartupPath + "Scripts")) foreach (string scriptPath in Directory.GetFiles(Folder.Startup + "Scripts"))
{ {
if (KnownScripts.Contains(Path.GetFileName(path))) if (KnownScripts.Contains(Path.GetFileName(scriptPath)))
{ {
if (path.EndsWith(".py")) if (scriptPath.EndsWith(".py"))
PythonScripts.Add(new PythonScript(File.ReadAllText(path))); Task.Run(() => PythonScripts.Add(new PythonScript(scriptPath)));
else if (path.EndsWith(".ps1")) else if (scriptPath.EndsWith(".ps1"))
PowerShellScript.Init(path); Task.Run(() => PowerShellScript.Init(scriptPath));
} }
else else
Msg.ShowError("Failed to load script", path + "\n\nOnly scripts that ship with mpv.net are allowed in <startup>\\scripts\n\nUser scripts have to use <config folder>\\scripts\n\nNever copy or install a new mpv.net version over a old mpv.net version."); Msg.ShowError("Failed to load script", scriptPath + "\n\nOnly scripts that ship with mpv.net are allowed in <startup>\\scripts\n\nUser scripts have to use <config folder>\\scripts\n\nNever copy or install a new mpv.net version over a old mpv.net version.");
} }
} }
if (Directory.Exists(ConfigFolder + "Scripts")) if (Directory.Exists(ConfigFolder + "scripts"))
foreach (string scriptPath in Directory.GetFiles(ConfigFolder + "Scripts")) foreach (string scriptPath in Directory.GetFiles(ConfigFolder + "scripts"))
if (scriptPath.EndsWith(".py")) if (scriptPath.EndsWith(".py"))
PythonScripts.Add(new PythonScript(File.ReadAllText(scriptPath))); Task.Run(() => PythonScripts.Add(new PythonScript(scriptPath)));
else if (scriptPath.EndsWith(".ps1")) else if (scriptPath.EndsWith(".ps1"))
PowerShellScript.Init(scriptPath); Task.Run(() => PowerShellScript.Init(scriptPath));
} }
public static void EventLoop() public static void EventLoop()
@@ -312,7 +318,7 @@ namespace mpvnet
break; break;
case mpv_event_id.MPV_EVENT_FILE_LOADED: case mpv_event_id.MPV_EVENT_FILE_LOADED:
HideLogo(); HideLogo();
FileLoaded?.Invoke(); Duration = TimeSpan.FromSeconds(get_property_number("duration"));
Size vidSize = new Size(get_property_int("width"), get_property_int("height")); Size vidSize = new Size(get_property_int("width"), get_property_int("height"));
if (vidSize.Width == 0 || vidSize.Height == 0) if (vidSize.Width == 0 || vidSize.Height == 0)
vidSize = new Size(1, 1); vidSize = new Size(1, 1);
@@ -323,7 +329,11 @@ namespace mpvnet
} }
VideoSizeAutoResetEvent.Set(); VideoSizeAutoResetEvent.Set();
Task.Run(new Action(() => ReadMetaData())); Task.Run(new Action(() => ReadMetaData()));
WriteHistory(get_property_string("path")); string path = mp.get_property_string("path");
if (path.Contains("://"))
path = mp.get_property_string("media-title");
WriteHistory(path);
FileLoaded?.Invoke();
break; break;
case mpv_event_id.MPV_EVENT_TRACKS_CHANGED: case mpv_event_id.MPV_EVENT_TRACKS_CHANGED:
TracksChanged?.Invoke(); TracksChanged?.Invoke();
@@ -333,7 +343,7 @@ namespace mpvnet
break; break;
case mpv_event_id.MPV_EVENT_IDLE: case mpv_event_id.MPV_EVENT_IDLE:
Idle?.Invoke(); Idle?.Invoke();
if (get_property_int("playlist-count") == 0) ShowLogo(); ShowLogo();
break; break;
case mpv_event_id.MPV_EVENT_PAUSE: case mpv_event_id.MPV_EVENT_PAUSE:
Pause?.Invoke(); Pause?.Invoke();
@@ -371,19 +381,22 @@ namespace mpvnet
var propData = (mpv_event_property)Marshal.PtrToStructure(evt.data, typeof(mpv_event_property)); var propData = (mpv_event_property)Marshal.PtrToStructure(evt.data, typeof(mpv_event_property));
if (propData.format == mpv_format.MPV_FORMAT_FLAG) if (propData.format == mpv_format.MPV_FORMAT_FLAG)
foreach (var i in BoolPropChangeActions) lock (BoolPropChangeActions)
if (i.Key== propData.name) foreach (var i in BoolPropChangeActions)
i.Value.Invoke(Marshal.PtrToStructure<int>(propData.data) == 1); if (i.Key== propData.name)
i.Value.Invoke(Marshal.PtrToStructure<int>(propData.data) == 1);
if (propData.format == mpv_format.MPV_FORMAT_STRING) if (propData.format == mpv_format.MPV_FORMAT_STRING)
foreach (var i in StringPropChangeActions) lock (StringPropChangeActions)
if (i.Key == propData.name) foreach (var i in StringPropChangeActions)
i.Value.Invoke(StringFromNativeUtf8(Marshal.PtrToStructure<IntPtr>(propData.data))); if (i.Key == propData.name)
i.Value.Invoke(StringFromNativeUtf8(Marshal.PtrToStructure<IntPtr>(propData.data)));
if (propData.format == mpv_format.MPV_FORMAT_INT64) if (propData.format == mpv_format.MPV_FORMAT_INT64)
foreach (var i in IntPropChangeActions) lock (IntPropChangeActions)
if (i.Key == propData.name) foreach (var i in IntPropChangeActions)
i.Value.Invoke(Marshal.PtrToStructure<int>(propData.data)); if (i.Key == propData.name)
i.Value.Invoke(Marshal.PtrToStructure<int>(propData.data));
break; break;
case mpv_event_id.MPV_EVENT_PLAYBACK_RESTART: case mpv_event_id.MPV_EVENT_PLAYBACK_RESTART:
PlaybackRestart?.Invoke(); PlaybackRestart?.Invoke();
@@ -408,11 +421,8 @@ namespace mpvnet
static void HideLogo() static void HideLogo()
{ {
if (IsLogoVisible) command("overlay-remove 0");
{ IsLogoVisible = false;
commandv("overlay-remove", "0");
IsLogoVisible = false;
}
} }
static List<PythonEventObject> PythonEventObjects = new List<PythonEventObject>(); static List<PythonEventObject> PythonEventObjects = new List<PythonEventObject>();
@@ -542,7 +552,8 @@ namespace mpvnet
if (err < 0) if (err < 0)
throw new Exception($"{name}: {(mpv_error)err}"); throw new Exception($"{name}: {(mpv_error)err}");
else else
IntPropChangeActions.Add(new KeyValuePair<string, Action<int>>(name, action)); lock (IntPropChangeActions)
IntPropChangeActions.Add(new KeyValuePair<string, Action<int>>(name, action));
} }
public static void observe_property_bool(string name, Action<bool> action) public static void observe_property_bool(string name, Action<bool> action)
@@ -552,7 +563,8 @@ namespace mpvnet
if (err < 0) if (err < 0)
throw new Exception($"{name}: {(mpv_error)err}"); throw new Exception($"{name}: {(mpv_error)err}");
else else
BoolPropChangeActions.Add(new KeyValuePair<string, Action<bool>>(name, action)); lock (BoolPropChangeActions)
BoolPropChangeActions.Add(new KeyValuePair<string, Action<bool>>(name, action));
} }
public static void observe_property_string(string name, Action<string> action) public static void observe_property_string(string name, Action<string> action)
@@ -562,43 +574,47 @@ namespace mpvnet
if (err < 0) if (err < 0)
throw new Exception($"{name}: {(mpv_error)err}"); throw new Exception($"{name}: {(mpv_error)err}");
else else
StringPropChangeActions.Add(new KeyValuePair<string, Action<string>>(name, action)); lock (StringPropChangeActions)
StringPropChangeActions.Add(new KeyValuePair<string, Action<string>>(name, action));
} }
public static void ProcessCommandLine() public static void ProcessCommandLine(bool preInit)
{ {
var args = Environment.GetCommandLineArgs().Skip(1); var args = Environment.GetCommandLineArgs().Skip(1);
List<string> files = new List<string>();
//Msg.Show(string.Join("\n", args));
string[] preInitProperties = { "input-terminal", "terminal", "input-file", "config", "config-dir", "input-conf", "load-scripts", "scripts", "player-operation-mode" };
foreach (string i in args) foreach (string i in args)
{ {
if (!i.StartsWith("--") && (i == "-" || i.Contains("://") || File.Exists(i))) string arg = i;
{
files.Add(i);
if (i.Contains("://")) RegHelp.SetObject(App.RegPath, "LastURL", i);
}
}
foreach (string i in args) if (arg.StartsWith("--"))
{
if (i.StartsWith("--"))
{ {
try try
{ {
if (i.Contains("=")) if (!arg.Contains("=")) arg += "=yes";
string left = arg.Substring(2, arg.IndexOf("=") - 2);
string right = arg.Substring(left.Length + 3);
if (left == "script") left = "scripts";
if (preInit && preInitProperties.Contains(left))
{ {
string left = i.Substring(2, i.IndexOf("=") - 2);
string right = i.Substring(left.Length + 3);
mp.ProcessProperty(left, right); mp.ProcessProperty(left, right);
if (!App.ProcessProperty(left, right)) if (!App.ProcessProperty(left, right))
set_property_string(left, right, true); set_property_string(left, right, true);
} }
else else if (!preInit && !preInitProperties.Contains(left))
{ {
string name = i.Substring(2); if (!PrintCommandLineArgument(arg))
mp.ProcessProperty(name, "yes"); {
if (!App.ProcessProperty(name, "yes")) mp.ProcessProperty(left, right);
set_property_string(name, "yes", true); if (!App.ProcessProperty(left, right))
set_property_string(left, right, true);
}
} }
} }
catch (Exception e) catch (Exception e)
@@ -608,15 +624,43 @@ namespace mpvnet
} }
} }
Load(files.ToArray(), App.ProcessInstance != "queue", Control.ModifierKeys.HasFlag(Keys.Control)); if (!preInit)
if (files.Count == 0 || files[0].Contains("://"))
{ {
VideoSizeAutoResetEvent.Set(); List<string> files = new List<string>();
VideoSizeChanged?.Invoke();
foreach (string i in args)
{
if (!i.StartsWith("--") && (i == "-" || i.Contains("://") ||
i.Contains(":\\") || i.StartsWith("\\\\") || File.Exists(i)))
{
files.Add(i);
}
}
Load(files.ToArray(), App.ProcessInstance != "queue", Control.ModifierKeys.HasFlag(Keys.Control));
if (files.Count == 0 || files[0].Contains("://"))
{
VideoSizeChanged?.Invoke();
VideoSizeAutoResetEvent.Set();
}
} }
} }
static bool PrintCommandLineArgument(string argument)
{
switch (argument)
{
case "--list-properties=yes":
var list = get_property_string("property-list").Split(',').ToList();
list.Sort();
Console.WriteLine(string.Join("\r\n", list.ToArray()));
return true;
}
return false;
}
public static DateTime LastLoad; public static DateTime LastLoad;
public static void Load(string[] files, bool loadFolder, bool append) public static void Load(string[] files, bool loadFolder, bool append)
@@ -651,7 +695,7 @@ namespace mpvnet
string path = get_property_string("path"); string path = get_property_string("path");
if (!File.Exists(path) || get_property_int("playlist-count") != 1) return; if (!File.Exists(path) || get_property_int("playlist-count") != 1) return;
List<string> files = Directory.GetFiles(Path.GetDirectoryName(path)).ToList(); List<string> files = Directory.GetFiles(Path.GetDirectoryName(path)).ToList();
files = files.Where((file) => files = files.Where(file =>
App.VideoTypes.Contains(file.ShortExt()) || App.VideoTypes.Contains(file.ShortExt()) ||
App.AudioTypes.Contains(file.ShortExt()) || App.AudioTypes.Contains(file.ShortExt()) ||
App.ImageTypes.Contains(file.ShortExt())).ToList(); App.ImageTypes.Contains(file.ShortExt())).ToList();
@@ -709,17 +753,14 @@ namespace mpvnet
static void WriteHistory(string path) static void WriteHistory(string path)
{ {
if (!File.Exists(path)) return; if (!File.Exists(ConfigFolder + "history.txt"))
return;
int totalMinutes = Convert.ToInt32((DateTime.Now - LastHistoryStartDateTime).TotalMinutes); int totalMinutes = Convert.ToInt32((DateTime.Now - LastHistoryStartDateTime).TotalMinutes);
if (File.Exists(LastHistoryPath) && totalMinutes > 1) if (PathHelp.GetBaseName(LastHistoryPath) != "" && totalMinutes > 1)
{ File.AppendAllText(ConfigFolder + "history.txt", DateTime.Now.ToString().Substring(0, 16) +
string historyFilepath = ConfigFolder + "history.txt"; " " + totalMinutes.ToString().PadLeft(3) + " " + PathHelp.GetBaseName(LastHistoryPath) + "\r\n");
File.AppendAllText(historyFilepath, DateTime.Now.ToString().Substring(0, 16) +
" " + totalMinutes.ToString().PadLeft(3) + " " +
Path.GetFileNameWithoutExtension(LastHistoryPath) + "\r\n");
}
LastHistoryPath = path; LastHistoryPath = path;
LastHistoryStartDateTime = DateTime.Now; LastHistoryStartDateTime = DateTime.Now;