Compare commits

..

15 Commits
1.9 ... 2.1

Author SHA1 Message Date
Frank Skare
7fa4418e1f - 2019-03-30 05:43:46 +01:00
Frank Skare
c89bbe319d - 2019-03-30 05:33:00 +01:00
Frank Skare
08089b0fc7 - 2019-03-30 05:28:38 +01:00
Frank Skare
4116aeb65a - 2019-03-28 12:14:07 +01:00
Frank Skare
bfeb041d08 - 2019-03-28 02:27:52 +01:00
Frank Skare
2dca7eb599 - 2019-03-28 02:25:12 +01:00
Frank Skare
87213f9610 - 2019-03-28 02:22:52 +01:00
Frank Skare
8a6f00bdf2 - 2019-03-28 02:07:05 +01:00
Frank Skare
448add600b - 2019-03-28 02:04:55 +01:00
Frank Skare
6669a42dcd - 2019-03-28 01:42:36 +01:00
Frank Skare
3df26a4b90 - 2019-03-28 00:46:57 +01:00
Frank Skare
3ccb80f359 - 2019-03-27 21:41:44 +01:00
Frank Skare
636e36583d - 2019-03-27 02:40:31 +01:00
Frank Skare
d7617bda6d 1.9 2019-03-27 02:38:56 +01:00
Frank Skare
12f1d70969 - 2019-03-27 02:35:46 +01:00
67 changed files with 1774 additions and 627 deletions

View File

@@ -3,7 +3,6 @@ Imports System.IO
Imports System.Windows.Forms Imports System.Windows.Forms
Imports mpvnet Imports mpvnet
Imports mpvnet.StaticUsing
Imports CSScriptLibrary Imports CSScriptLibrary

View File

@@ -18,7 +18,7 @@
<DebugType>full</DebugType> <DebugType>full</DebugType>
<DefineDebug>true</DefineDebug> <DefineDebug>true</DefineDebug>
<DefineTrace>true</DefineTrace> <DefineTrace>true</DefineTrace>
<OutputPath>..\mpv.net\bin\Debug\Addons\CSScriptAddon\</OutputPath> <OutputPath>..\mpv.net\bin\Addons\CSScriptAddon\</OutputPath>
<DocumentationFile> <DocumentationFile>
</DocumentationFile> </DocumentationFile>
<NoWarn>42105,42106,42107,42353,42354,42355</NoWarn> <NoWarn>42105,42106,42107,42353,42354,42355</NoWarn>
@@ -29,7 +29,7 @@
<DefineDebug>false</DefineDebug> <DefineDebug>false</DefineDebug>
<DefineTrace>true</DefineTrace> <DefineTrace>true</DefineTrace>
<Optimize>true</Optimize> <Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath> <OutputPath>..\mpv.net\bin\Addons\CSScriptAddon\</OutputPath>
<DocumentationFile> <DocumentationFile>
</DocumentationFile> </DocumentationFile>
<NoWarn>42105,42106,42107,42353,42354,42355</NoWarn> <NoWarn>42105,42106,42107,42353,42354,42355</NoWarn>

174
README.md
View File

@@ -1,31 +1,34 @@
# mpv.net # mpv.net
mpv.net is a libmpv based media player for Windows, it looks and works like mpv, even shares the settings and therefore the mpv documentation applies. mpv.net is a libmpv based media player for Windows, it looks and works like mpv and also shares the same settings as mpv and therefore the mpv documentation applies.
mpv and mpv.net have a learning curve and are only suitable for experienced users. mpv and mpv.net have a learning curve.
mpv manual: https://mpv.io/manual/master/ mpv manual: <https://mpv.io/manual/master/>
Table of contents Table of contents
------- -----------------
- [Features](#features) - [Features](#features)
- [Screenshots](#screenshots)
- [Context Menu](#context-menu) - [Context Menu](#context-menu)
- [Settings](#settings) - [Settings](#settings)
- [C# Scripting](#cs-scripting) - [Scripting](#scripting)
- [Python Scripting](#python-scripting) - [Support](#support)
- [PowerShell Scripting](#powershell-scripting)
- [Support](#Support)
- [Changelog](#changelog) - [Changelog](#changelog)
### Features ### Features
- Customizable context menu defined in the same file as the keybindings - Customizable context menu defined in the same file as the keybindings
- Addon API for .NET languages - Addon API for .NET languages
- 5 different scripting languages are supported, Python scripting implemented with IronPython, C# implemented with CS-Script, Lua and JavaScript implemented in libmpv and PowerShell - Scripting API for Python, C#, Lua, JavaScript and PowerShell
- mpv's OSC, IPC, conf files and more - mpv's OSC, IPC, conf files and more
![](https://raw.githubusercontent.com/stax76/mpv.net/master/screenshot.png) ### Screenshots
![](https://raw.githubusercontent.com/stax76/mpv.net/master/screenshots/screenshot.png)
![](https://raw.githubusercontent.com/stax76/mpv.net/master/screenshots/mpvSettingsEditor.png)
### Context Menu ### Context Menu
@@ -35,101 +38,23 @@ C:\Users\username\AppData\Roaming\mpv\input.conf
``` ```
if it's missing mpv.net generates it with the following defaults: if it's missing mpv.net generates it with the following defaults:
https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/input.conf.txt <https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/input.conf.txt>
### Settings ### Settings
mpv.net shares the settings with mpv, settings have to be edited in a config file called mpv.conf located at: mpv.net shares the settings with mpv, settings can be edited in a settings dialog or in a config file called mpv.conf located at:
``` ```
C:\Users\username\AppData\Roaming\mpv\mpv.conf C:\Users\user\AppData\Roaming\mpv\mpv.conf
``` ```
if it's missing mpv.net generates it with the following defaults: if it's missing mpv.net generates it with the following defaults:
https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/mpv.conf.txt <https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/mpv.conf.txt>
### C# Scripting ### Scripting
A simple C# script located at: Scripting is supported for Python, C#, Lua, JavaScript and PowerShell
```
C:\Users\username\AppData\Roaming\mpv\scripts\fullscreen.cs
```
or
```
startup\scripts\fullscreen.cs
```
```
using mpvnet;
class Script https://github.com/stax76/mpv.net/wiki/Scripting-(CSharp,-Python,-JavaScript,-Lua,-PowerShell)
{
public Script()
{
var fs = mp.get_property_string("fullscreen");
mp.commandv("show-text", "fullscreen: " + fs);
mp.observe_property_bool("fullscreen", FullscreenChange);
}
void FullscreenChange(bool val)
{
mp.commandv("show-text", "fullscreen: " + val.ToString());
}
}
```
### Python Scripting
A simple Python script located at:
```
C:\Users\user\AppData\Roaming\mpv\scripts\seek-show-position.py
```
or
```
startup\scripts\seek-show-position.py
```
```
# when seeking displays position and
# duration like so: 70:00 / 80:00
# which is different from mpv which
# uses 01:10:00 / 01:20:00
import math
def seek():
mp.commandv('show-text',
format(mp.get_property_number("time-pos")) + " / " + format(mp.get_property_number("duration")))
def format(f):
sec = round(f)
if sec < 0:
sec = 0
pos_min_floor = math.floor(sec / 60)
sec_rest = sec - pos_min_floor * 60
return add_zero(pos_min_floor) + ":" + add_zero(sec_rest)
def add_zero(val):
val = round(val)
return "" + str(int(val)) if (val > 9) else "0" + str(int(val))
mp.register_event("seek", seek) # or use: mp.Seek += seek
```
### PowerShell Scripting
A simple PowerShell script located at:
```
C:\Users\user\AppData\Roaming\mpv\scripts\seek.ps1
```
or
```
startup\scripts\seek.ps1
```
```
$position = [mp]::get_property_number("time-pos");
[mp]::commandv("show-text", $position.ToString() + " seconds")
```
Please note that PowerShell don't allow assigning to events and mpv.net uses as workaround a matching script filename, a list of available events can be found in the mpv manual or in the file mp.cs in the mpv.net source code.
### Support ### Support
@@ -141,53 +66,14 @@ Please note that PowerShell don't allow assigning to events and mpv.net uses as
### Changelog ### Changelog
### soon ### 2.0 (2019-03-28)
- all info and error messages are shown now on the main window thread having the main window as parent - setting track-auto-selection added to settings editor (<https://mpv.io/manual/master/#options-track-auto-selection>)
- setting loop-playlist added to settings editor (<https://mpv.io/manual/master/#options-loop-playlist>)
### 1.8 - setting audio-file-auto added to settings editor (<https://mpv.io/manual/master/#options-audio-file-auto>)
- setting video-sync added to settings editor (<https://mpv.io/manual/master/#options-video-sync>)
- new config editor added - command execute-mpv-command added to menu: Tools > Enter a mpv command for execution
- added youtube-dl.exe, please note this will only work when a certain Visual C++ runtime is installed
### 1.7 - added drag & drop support to drag & drop a youtube URL on mpv.net
- added support to open a youtube URL from command line
- showing the conf files mpv.net uses now the app that is registered for txt files, before it just shell executed the conf file which only worked if conf files were associated with an application - added support for opening a URL from the menu: Open > Open URL
- leaving fullscreen mode the previous window size and position wasn't restored
- when the source video aspect ratio changes the height is kept and the width is adjusted and a check is performed to assure the window is within screen bounds
### 1.6
- a crash caused by WM_APPCOMMAND (multimedia keyboards) commands was fixed
- support for the 'screen' property was added, it should work both from mpv.conf (screen = 1) and from command line (--screen=1)
- per monitor DPI awareness and better multi monitor support was added
### 1.5
- the info command supports now info for music files instead of showing an exception on music files
- added support for WM_APPCOMMAND API to support media keyboards
- fixed Alt key input not working
- mpv.net API methods renamed to match the names used in the Lua/JS API
### 1.4
- the last thread sync fix wasn't working well, the delayed shutdown should be gone for good now
- libmpv updated
### 1.3
- besides Lua/JavaScript/C#/Python there is now PowerShell supported as fifth scripting language
- in case there isn't yet a mpv.conf file mpv.net creates the file with certain default settings that were previously set on every mpv.net start. This was changed to provide transparency on which settings mpv.net uses. These default settings can be seen here: https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/mpv.conf.txt
### 1.2
- a thread synchonisation bug which caused the shutdown to be delayed or frozen was fixed, it also caused the Shutdown event not to fire which caused the rating plugin not to work
### 1.1
- added support for Python scripting via IronPython
- show tracks and show playlist didn't work because the duration wasn't defined in the key bindings
### 1.0
- much more feature packed context menu

View File

@@ -17,7 +17,7 @@
<DebugSymbols>true</DebugSymbols> <DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType> <DebugType>full</DebugType>
<Optimize>false</Optimize> <Optimize>false</Optimize>
<OutputPath>..\mpv.net\bin\Debug\Addons\RatingAddon\</OutputPath> <OutputPath>..\mpv.net\bin\Addons\RatingAddon\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants> <DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
@@ -25,7 +25,7 @@
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType> <DebugType>pdbonly</DebugType>
<Optimize>true</Optimize> <Optimize>true</Optimize>
<OutputPath>..\mpv.net\bin\Release\</OutputPath> <OutputPath>..\mpv.net\bin\Addons\RatingAddon\</OutputPath>
<DefineConstants>TRACE</DefineConstants> <DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>

View File

@@ -58,19 +58,14 @@ namespace mpvnet
Process.Start(mp.mpvConfFolderPath); Process.Start(mp.mpvConfFolderPath);
} }
public static void show_keys(string[] args) public static void show_input_editor(string[] args)
{ {
Process.Start(NativeHelp.GetAssociatedApplication(".txt"), mp.InputConfPath); Process.Start(Application.StartupPath + "\\mpvInputEdit.exe");
}
public static void show_prefs(string[] args)
{
Process.Start(NativeHelp.GetAssociatedApplication(".txt"), mp.mpvConfPath);
} }
public static void show_conf_editor(string[] args) public static void show_conf_editor(string[] args)
{ {
Process.Start(Application.StartupPath + "\\mpvSettingsEditor.exe"); Process.Start(Application.StartupPath + "\\mpvConfEdit.exe");
} }
public static void history(string[] args) public static void history(string[] args)
@@ -114,59 +109,83 @@ namespace mpvnet
public static void show_info(string[] args) public static void show_info(string[] args)
{ {
var fileInfo = new FileInfo(mp.get_property_string("path")); try
using (var mediaInfo = new MediaInfo(fileInfo.FullName))
{ {
string width = mediaInfo.GetInfo(MediaInfoStreamKind.Video, "Width"); var fileInfo = new FileInfo(mp.get_property_string("path"));
if (width == "") using (var mediaInfo = new MediaInfo(fileInfo.FullName))
{ {
string performer = mediaInfo.GetInfo(MediaInfoStreamKind.General, "Performer"); string width = mediaInfo.GetInfo(MediaInfoStreamKind.Video, "Width");
string title = mediaInfo.GetInfo(MediaInfoStreamKind.General, "Title");
string album = mediaInfo.GetInfo(MediaInfoStreamKind.General, "Album");
string genre = mediaInfo.GetInfo(MediaInfoStreamKind.General, "Genre");
string date = mediaInfo.GetInfo(MediaInfoStreamKind.General, "Recorded_Date");
string duration = mediaInfo.GetInfo(MediaInfoStreamKind.Audio, "Duration/String");
string text = ""; if (width == "")
{
string performer = mediaInfo.GetInfo(MediaInfoStreamKind.General, "Performer");
string title = mediaInfo.GetInfo(MediaInfoStreamKind.General, "Title");
string album = mediaInfo.GetInfo(MediaInfoStreamKind.General, "Album");
string genre = mediaInfo.GetInfo(MediaInfoStreamKind.General, "Genre");
string date = mediaInfo.GetInfo(MediaInfoStreamKind.General, "Recorded_Date");
string duration = mediaInfo.GetInfo(MediaInfoStreamKind.Audio, "Duration/String");
if (performer != "") text += "Artist: " + performer + "\n"; string text = "";
if (title != "") text += "Title: " + title + "\n";
if (album != "") text += "Album: " + album + "\n";
if (genre != "") text += "Genre: " + genre + "\n";
if (date != "") text += "Year: " + date + "\n";
if (duration != "") text += "Length: " + duration + "\n";
mp.commandv("show-text", text, "5000"); if (performer != "") text += "Artist: " + performer + "\n";
if (title != "") text += "Title: " + title + "\n";
if (album != "") text += "Album: " + album + "\n";
if (genre != "") text += "Genre: " + genre + "\n";
if (date != "") text += "Year: " + date + "\n";
if (duration != "") text += "Length: " + duration + "\n";
mp.commandv("show-text", text, "5000");
}
else
{
string height = mediaInfo.GetInfo(MediaInfoStreamKind.Video, "Height");
TimeSpan position = TimeSpan.FromSeconds(mp.get_property_number("time-pos"));
TimeSpan duration = TimeSpan.FromSeconds(mp.get_property_number("duration"));
string bitrate = mediaInfo.GetInfo(MediaInfoStreamKind.Video, "BitRate");
if (bitrate == "")
bitrate = "0";
var bitrate2 = Convert.ToDouble(bitrate) / 1000.0 / 1000.0;
var videoCodec = mp.get_property_string("video-format").ToUpper();
var filename = fileInfo.Name;
var text =
FormatTime(position.TotalMinutes) + ":" +
FormatTime(position.Seconds) + " / " +
FormatTime(duration.TotalMinutes) + ":" +
FormatTime(duration.Seconds) + "\n" +
Convert.ToInt32(fileInfo.Length / 1024 / 1024).ToString() +
$" MB - {width} x {height}\n{videoCodec} - {bitrate2.ToString("f1")} Mb/s" + "\n" + filename;
mp.commandv("show-text", text, "5000");
}
string FormatTime(double value) => ((int)value).ToString("00");
} }
else
{
string height = mediaInfo.GetInfo(MediaInfoStreamKind.Video, "Height");
TimeSpan position = TimeSpan.FromSeconds(mp.get_property_number("time-pos"));
TimeSpan duration = TimeSpan.FromSeconds(mp.get_property_number("duration"));
string bitrate = mediaInfo.GetInfo(MediaInfoStreamKind.Video, "BitRate");
if (bitrate == "")
bitrate = "0";
var bitrate2 = Convert.ToDouble(bitrate) / 1000.0 / 1000.0;
var videoCodec = mp.get_property_string("video-format").ToUpper();
var filename = fileInfo.Name;
var text =
FormatTime(position.TotalMinutes) + ":" +
FormatTime(position.Seconds) + " / " +
FormatTime(duration.TotalMinutes) + ":" +
FormatTime(duration.Seconds) + "\n" +
Convert.ToInt32(fileInfo.Length / 1024 / 1024).ToString() +
$" MB - {width} x {height}\n{videoCodec} - {bitrate2.ToString("f1")} Mb/s" + "\n" + filename;
mp.commandv("show-text", text, "5000");
}
string FormatTime(double value) => ((int)value).ToString("00");
} }
catch (Exception)
{
}
}
public static void execute_mpv_command(string[] args)
{
MainForm.Instance.Invoke(new Action(() => {
string command = Microsoft.VisualBasic.Interaction.InputBox("Enter a mpv command to be executed.");
if (string.IsNullOrEmpty(command)) return;
mp.command_string(command, false);
}));
}
public static void open_url(string[] args)
{
MainForm.Instance.Invoke(new Action(() => {
string command = Microsoft.VisualBasic.Interaction.InputBox("Enter URL to be opened.");
if (string.IsNullOrEmpty(command)) return;
mp.LoadURL(command);
}));
} }
} }
} }

View File

@@ -1,30 +0,0 @@
using System.Collections.Generic;
using System.Linq;
namespace mpvnet
{
public static class Extensions
{
public static string Join(this IEnumerable<string> instance, string delimiter, bool removeEmpty = false)
{
if (instance == null)
return null;
bool containsEmpty = false;
foreach (var i in instance)
{
if (string.IsNullOrEmpty(i))
{
containsEmpty = true;
break;
}
}
if (containsEmpty && removeEmpty)
instance = instance.Where(arg => !string.IsNullOrEmpty(arg));
return string.Join(delimiter, instance);
}
}
}

View File

@@ -4,7 +4,6 @@ using System.IO;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Threading; using System.Threading;
using System.Windows.Forms; using System.Windows.Forms;
using System.Diagnostics;
using System.Linq; using System.Linq;
namespace mpvnet namespace mpvnet
@@ -143,11 +142,11 @@ namespace mpvnet
if (left.StartsWith("#")) continue; if (left.StartsWith("#")) continue;
var cmd = left.Substring(left.IndexOf(" ") + 1).Trim(); var cmd = left.Substring(left.IndexOf(" ") + 1).Trim();
var menu = i.Substring(i.IndexOf("#menu:") + "#menu:".Length).Trim(); var menu = i.Substring(i.IndexOf("#menu:") + "#menu:".Length).Trim();
var key = menu.Substring(0, menu.IndexOf(";")).Trim(); var key = left.Substring(0, left.IndexOf(" "));
var path = menu.Substring(menu.IndexOf(";") + 1).Trim(); if (key == "_") key = "";
if (menu.Contains(";")) key = menu.Substring(0, menu.IndexOf(";")).Trim();
if (path == "" || cmd == "") var path = menu.Substring(menu.IndexOf(";") + 1).Trim().Replace("&", "&&");
continue; if (path == "" || cmd == "") continue;
var menuItem = CMS.Add(path, () => { var menuItem = CMS.Add(path, () => {
try try
@@ -296,16 +295,17 @@ namespace mpvnet
{ {
base.OnDragEnter(e); base.OnDragEnter(e);
if (e.Data.GetDataPresent(DataFormats.FileDrop)) if (e.Data.GetDataPresent(DataFormats.FileDrop) || e.Data.GetDataPresent(DataFormats.Text))
e.Effect = DragDropEffects.Copy; e.Effect = DragDropEffects.Copy;
} }
protected override void OnDragDrop(DragEventArgs e) protected override void OnDragDrop(DragEventArgs e)
{ {
base.OnDragDrop(e); base.OnDragDrop(e);
if (e.Data.GetDataPresent(DataFormats.FileDrop)) if (e.Data.GetDataPresent(DataFormats.FileDrop))
mp.LoadFiles(e.Data.GetData(DataFormats.FileDrop) as String[]); mp.LoadFiles(e.Data.GetData(DataFormats.FileDrop) as String[]);
if (e.Data.GetDataPresent(DataFormats.Text))
mp.LoadURL(e.Data.GetData(DataFormats.Text).ToString());
} }
protected override void OnMouseDown(MouseEventArgs e) protected override void OnMouseDown(MouseEventArgs e)
@@ -396,5 +396,11 @@ namespace mpvnet
mp.commandv("quit"); mp.commandv("quit");
mp.AutoResetEvent.WaitOne(3000); mp.AutoResetEvent.WaitOne(3000);
} }
protected override void OnLostFocus(EventArgs e)
{
base.OnLostFocus(e);
CursorHelp.Show();
}
} }
} }

View File

@@ -10,10 +10,8 @@ namespace mpvnet
{ {
public static readonly string[] FileTypes = "264 265 3gp aac ac3 avc avi avs bmp divx dts dtshd dtshr dtsma eac3 evo flac flv h264 h265 hevc hvc jpg jpeg m2t m2ts m2v m4a m4v mka mkv mlp mov mp2 mp3 mp4 mpa mpeg mpg mpv mts ogg ogm opus pcm png pva raw rmvb thd thd+ac3 true-hd truehd ts vdr vob vpy w64 wav webm wmv y4m".Split(' '); public static readonly string[] FileTypes = "264 265 3gp aac ac3 avc avi avs bmp divx dts dtshd dtshr dtsma eac3 evo flac flv h264 h265 hevc hvc jpg jpeg m2t m2ts m2v m4a m4v mka mkv mlp mov mp2 mp3 mp4 mpa mpeg mpg mpv mts ogg ogm opus pcm png pva raw rmvb thd thd+ac3 true-hd truehd ts vdr vob vpy w64 wav webm wmv y4m".Split(' ');
public static string GetFilter(IEnumerable<string> values) public static string GetFilter(IEnumerable<string> values) => "*." +
{ String.Join(";*.", values) + "|*." + String.Join(";*.", values) + "|All Files|*.*";
return "*." + values.Join(";*.") + "|*." + values.Join(";*.") + "|All Files|*.*";
}
} }
public class StringLogicalComparer : IComparer, IComparer<string> public class StringLogicalComparer : IComparer, IComparer<string>
@@ -27,13 +25,13 @@ namespace mpvnet
int IComparer<string>.Compare(string x, string y) => IComparerOfString_Compare(x, y); int IComparer<string>.Compare(string x, string y) => IComparerOfString_Compare(x, y);
} }
//public class OSVersion public class OSVersion
//{ {
// public static float Windows7 { get; } = 6.1f; public static float Windows7 { get; } = 6.1f;
// public static float Windows8 { get; } = 6.2f; public static float Windows8 { get; } = 6.2f;
// public static float Windows81 { get; } = 6.3f; public static float Windows81 { get; } = 6.3f;
// public static float Windows10 { get; } = 10f; public static float Windows10 { get; } = 10f;
// public static float Current => Environment.OSVersion.Version.Major + Environment.OSVersion.Version.Minor / 10f; public static float Current => Environment.OSVersion.Version.Major + Environment.OSVersion.Version.Minor / 10f;
//} }
} }

View File

@@ -32,9 +32,6 @@ namespace mpvnet
[DllImport("user32.dll", SetLastError = true)] [DllImport("user32.dll", SetLastError = true)]
public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, int uFlags); public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, int uFlags);
[DllImport("Shlwapi.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern uint AssocQueryString(uint flags, uint str, string pszAssoc, string pszExtra, StringBuilder pszOut, ref uint pcchOut);
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Sequential)]
public struct RECT public struct RECT
{ {

View File

@@ -1,6 +1,4 @@
using System; using System;
using System.IO;
using System.Text;
namespace mpvnet namespace mpvnet
{ {
@@ -36,25 +34,5 @@ namespace mpvnet
{ {
Native.AdjustWindowRect(ref rc, (uint)Native.GetWindowLongPtrW(hwnd, -16 /* GWL_STYLE */), false); Native.AdjustWindowRect(ref rc, (uint)Native.GetWindowLongPtrW(hwnd, -16 /* GWL_STYLE */), false);
} }
public static string GetAssociatedApplication(string ext)
{
uint returnValue = 0U;
// ASSOCF_VERIFY, ASSOCSTR_EXECUTABLE
if (1 == Native.AssocQueryString(0x40, 2, ext, null, null, ref returnValue))
{
if (returnValue > 0)
{
StringBuilder sb = new StringBuilder(Convert.ToInt32(returnValue));
// ASSOCF_VERIFY, ASSOCSTR_EXECUTABLE
if (0 == Native.AssocQueryString(0x40, 2, ext, null, sb, ref returnValue))
{
var ret = sb.ToString();
if (File.Exists(ret)) return ret;
}
}
}
return "";
}
} }
} }

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("1.8.0.0")] [assembly: AssemblyVersion("2.1.0.0")]
[assembly: AssemblyFileVersion("1.8.0.0")] [assembly: AssemblyFileVersion("2.1.0.0")]

View File

@@ -1,137 +1,124 @@
# mpv.net key bindings, mouse bindings and context menu configuration o script-message mpv.net open-files #menu: Open > Open Files...
u script-message mpv.net open-url #menu: Open > Open URL...
_ ignore #menu: -
Space cycle pause #menu: Play/Pause
s stop #menu: Stop
_ ignore #menu: -
f cycle fullscreen #menu: Toggle Fullscreen
o script-message mpv.net open-files #menu: O ; Open Files... F11 playlist-prev #menu: Navigate > Previous
_ ignore #menu: _ ; - F12 playlist-next #menu: Navigate > Next
Space cycle pause #menu: Space, Enter ; Play/Pause _ ignore #menu: Navigate > -
Enter cycle pause PGUP add chapter 1 #menu: Navigate > Next Chapter
s stop #menu: S ; Stop PGDWN add chapter -1 #menu: Navigate > Previous Chapter
_ ignore #menu: _ ; -
f cycle fullscreen #menu: F ; Toggle Fullscreen
F11 playlist-prev #menu: F11 ; Navigate > Previous . frame-step #menu: Seek > Next Frame
F12 playlist-next #menu: F12 ; Navigate > Next , frame-back-step #menu: Seek > Previous Frame
_ ignore #menu: _ ; Navigate > - _ ignore #menu: Seek > -
PGUP add chapter 1 #menu: Page Up ; Navigate > Next Chapter Right no-osd seek 7 #menu: Seek > 7 sec forward
PGDWN add chapter -1 #menu: Page Down ; Navigate > Previous Chapter Left no-osd seek -7 #menu: Seek > 7 sec backward
_ ignore #menu: Seek > -
. frame-step #menu: . ; Seek > Next Frame Up no-osd seek 40 #menu: Seek > 40 sec forward
, frame-back-step #menu: , ; Seek > Previous Frame Down no-osd seek -40 #menu: Seek > 40 sec backward
_ ignore #menu: _ ; Seek > - _ ignore #menu: Seek > -
Right no-osd seek 7 #menu: Right ; Seek > 7 sec forward Ctrl+Right no-osd seek 300 #menu: Seek > 5 min forward
Left no-osd seek -7 #menu: Left ; Seek > 7 sec backward Ctrl+Left no-osd seek -300 #menu: Seek > 5 min backward
_ ignore #menu: _ ; Seek > - Ctrl++ add video-zoom 0.1 #menu: Pan & Scan > Increase Size
Up no-osd seek 40 #menu: Up ; Seek > 40 sec forward Ctrl+- add video-zoom -0.1 #menu: Pan & Scan > Decrease Size
Down no-osd seek -40 #menu: Down ; Seek > 40 sec backward _ ignore #menu: Pan & Scan > -
_ ignore #menu: _ ; Seek > - Ctrl+KP4 add video-pan-x -0.01 #menu: Pan & Scan > Move Left
Ctrl+Right no-osd seek 300 #menu: Ctrl+Right ; Seek > 5 min forward Ctrl+KP6 add video-pan-x 0.01 #menu: Pan & Scan > Move Right
Ctrl+Left no-osd seek -300 #menu: Ctrl+Left ; Seek > 5 min backward _ ignore #menu: Pan & Scan > -
Ctrl+KP8 add video-pan-y -0.01 #menu: Pan & Scan > Move Up
Ctrl++ add video-zoom 0.1 #menu: Ctrl++ ; Pan && Scan > Increase Size Ctrl+KP2 add video-pan-y 0.01 #menu: Pan & Scan > Move Down
Ctrl+- add video-zoom -0.1 #menu: Ctrl+- ; Pan && Scan > Decrease Size _ ignore #menu: Pan & Scan > -
_ ignore #menu: _ ; Pan && Scan > - w add panscan -0.1 #menu: Pan & Scan > Decrease Height
Ctrl+KP4 add video-pan-x -0.01 #menu: Ctrl+Numpad 4 ; Pan && Scan > Move Left W add panscan +0.1 #menu: Pan & Scan > Increase Height
Ctrl+KP6 add video-pan-x 0.01 #menu: Ctrl+Numpad 6 ; Pan && Scan > Move Right _ ignore #menu: Pan & Scan > -
_ ignore #menu: _ ; Pan && Scan > - Ctrl+BS set video-zoom 0 ; set video-pan-x 0 ; set video-pan-y 0 #menu: Pan & Scan > Reset
Ctrl+KP8 add video-pan-y -0.01 #menu: Ctrl+Numpad 8 ; Pan && Scan > Move Up Ctrl+1 add contrast -1 #menu: Video > Decrease Contrast
Ctrl+KP2 add video-pan-y 0.01 #menu: Ctrl+Numpad 2 ; Pan && Scan > Move Down Ctrl+2 add contrast 1 #menu: Video > Increase Contrast
_ ignore #menu: _ ; Pan && Scan > - _ ignore #menu: Video > -
w add panscan -0.1 #menu: W ; Pan && Scan > Decrease Height Ctrl+3 add brightness -1 #menu: Video > Decrease Brightness
W add panscan +0.1 #menu: Shift+W ; Pan && Scan > Increase Height Ctrl+4 add brightness 1 #menu: Video > Increase Brightness
_ ignore #menu: _ ; Pan && Scan > - _ ignore #menu: Video > -
Ctrl+BS set video-zoom 0 ; set video-pan-x 0 ; set video-pan-y 0 #menu: Ctrl+Backspace ; Pan && Scan > Reset Ctrl+5 add gamma -1 #menu: Video > Decrease Gamma
Ctrl+6 add gamma 1 #menu: Video > Increase Gamma
Ctrl+1 add contrast -1 #menu: Ctrl+1 ; Video > Decrease Contrast _ ignore #menu: Video > -
Ctrl+2 add contrast 1 #menu: Ctrl+2 ; Video > Increase Contrast Ctrl+7 add saturation -1 #menu: Video > Decrease Saturation
_ ignore #menu: _ ; Video > - Ctrl+8 add saturation 1 #menu: Video > Increase Saturation
Ctrl+3 add brightness -1 #menu: Ctrl+3 ; Video > Decrease Brightness _ ignore #menu: Video > -
Ctrl+4 add brightness 1 #menu: Ctrl+4 ; Video > Increase Brightness Ctrl+s async screenshot #menu: Video > Take Screenshot
_ ignore #menu: _ ; Video > - d cycle deinterlace #menu: Video > Toggle Deinterlace
Ctrl+5 add gamma -1 #menu: Ctrl+5 ; Video > Decrease Gamma a cycle-values video-aspect "16:9" "4:3" "2.35:1" "-1" #menu: Video > Cycle Aspect Ratio
Ctrl+6 add gamma 1 #menu: Ctrl+6 ; Video > Increase Gamma KP7 cycle audio #menu: Audio > Cycle/Next
_ ignore #menu: _ ; Video > - _ ignore #menu: Audio > -
Ctrl+7 add saturation -1 #menu: Ctrl+7 ; Video > Decrease Saturation KP6 add audio-delay 0.100 #menu: Audio > Delay +0.1
Ctrl+8 add saturation 1 #menu: Ctrl+8 ; Video > Increase Saturation KP9 add audio-delay -0.100 #menu: Audio > Delay -0.1
_ ignore #menu: _ ; Video > - KP8 cycle sub #menu: Subtitle > Cycle/Next
Ctrl+S async screenshot #menu: Ctrl+S ; Video > Take Screenshot v cycle sub-visibility #menu: Subtitle > Toggle Visibility
d cycle deinterlace #menu: D ; Video > Toggle Deinterlace _ ignore #menu: Subtitle > -
a cycle-values video-aspect "16:9" "4:3" "2.35:1" "-1" #menu: A ; Video > Cycle Aspect Ratio z add sub-delay -0.1 #menu: Subtitle > Delay -0.1
Z add sub-delay +0.1 #menu: Subtitle > Delay +0.1
KP7 cycle audio #menu: Keypad 7 ; Audio > Cycle/Next _ ignore #menu: Subtitle > -
_ ignore #menu: _ ; Audio > - r add sub-pos -1 #menu: Subtitle > Move Up
KP6 add audio-delay 0.100 #menu: Keypad 6 ; Audio > Delay +0.1 R add sub-pos +1 #menu: Subtitle > Move Down
KP9 add audio-delay -0.100 #menu: Keypad 9 ; Audio > Delay -0.1 _ ignore #menu: Subtitle > -
_ add sub-scale -0.1 #menu: Subtitle > Decrease Subtitle Font Size
KP8 cycle sub #menu: Keypad 8 ; Subtitle > Cycle/Next _ add sub-scale +0.1 #menu: Subtitle > Increase Subtitle Font Size
v cycle sub-visibility #menu: V ; Subtitle > Toggle Visibility + add volume 10 #menu: Volume > Up
_ ignore #menu: _ ; Subtitle > - - add volume -10 #menu: Volume > Down
z add sub-delay -0.1 #menu: Z ; Subtitle > Delay -0.1 _ ignore #menu: Volume > -
Z add sub-delay +0.1 #menu: Shift+Z ; Subtitle > Delay +0.1 m cycle mute #menu: Volume > Mute
_ ignore #menu: _ ; Subtitle > - [ multiply speed 0.9 #menu: Speed > -10%
r add sub-pos -1 #menu: R ; Subtitle > Move Up ] multiply speed 1.1 #menu: Speed > +10%
R add sub-pos +1 #menu: Shift+R ; Subtitle > Move Down _ ignore #menu: Speed > -
_ ignore #menu: _ ; Subtitle > - { multiply speed 0.5 #menu: Speed > Half
_ add sub-scale -0.1 #menu: _ ; Subtitle > Decrease Subtitle Font Size } multiply speed 2.0 #menu: Speed > Double
_ add sub-scale +0.1 #menu: _ ; Subtitle > Increase Subtitle Font Size _ ignore #menu: Speed > -
BS set speed 1 #menu: Speed > Reset
+ add volume 10 #menu: + ; Volume > Up KP0 script-message rate-file 0 #menu: Addons > Rating > 0stars
- add volume -10 #menu: - ; Volume > Down KP1 script-message rate-file 1 #menu: Addons > Rating > 1stars
WHEEL_UP add volume 10 KP2 script-message rate-file 2 #menu: Addons > Rating > 2stars
WHEEL_DOWN add volume -10 KP3 script-message rate-file 3 #menu: Addons > Rating > 3stars
_ ignore #menu: _ ; Volume > - KP4 script-message rate-file 4 #menu: Addons > Rating > 4stars
m cycle mute #menu: M ; Volume > Mute KP5 script-message rate-file 5 #menu: Addons > Rating > 5stars
_ script-message mpv.net set-setting hwdec yes #menu: Settings > Hardware Decoding > Enable
[ multiply speed 0.9 #menu: [ ; Speed > -10% _ script-message mpv.net set-setting hwdec no #menu: Settings > Hardware Decoding > Disable
] multiply speed 1.1 #menu: ] ; Speed > +10% e script-message mpv.net show-conf-editor #menu: Settings > Show Config Editor
_ ignore #menu: _ ; Speed > - Ctrl+i script-message mpv.net show-input-editor #menu: Settings > Show Input Editor
{ multiply speed 0.5 #menu: { ; Speed > Half c script-message mpv.net open-config-folder #menu: Settings > Open Config Folder
} multiply speed 2.0 #menu: } ; Speed > Double i script-message mpv.net show-info #menu: Tools > Info
_ ignore #menu: _ ; Speed > - t script-binding stats/display-stats #menu: Tools > Show Statistics
BS set speed 1 #menu: Backspace ; Speed > Reset T script-binding stats/display-stats-toggle #menu: Tools > Toggle Statistics
_ ignore #menu: Tools > -
KP0 script-message rate-file 0 #menu: Keypad 0 ; Addons > Rating > 0stars h script-message mpv.net history #menu: Tools > Show History
KP1 script-message rate-file 1 #menu: Keypad 1 ; Addons > Rating > 1stars l ab-loop #menu: Tools > Set/clear A-B loop points
KP2 script-message rate-file 2 #menu: Keypad 2 ; Addons > Rating > 2stars L cycle-values loop-file "inf" "no" #menu: Tools > Toggle Infinite Looping
KP3 script-message rate-file 3 #menu: Keypad 3 ; Addons > Rating > 3stars Del script-binding osc/visibility #menu: Tools > Toggle OSC Visibility
KP4 script-message rate-file 4 #menu: Keypad 4 ; Addons > Rating > 4stars Ctrl+h cycle-values hwdec "auto" "no" #menu: Tools > Cycle Hardware Decoding
KP5 script-message rate-file 5 #menu: Keypad 5 ; Addons > Rating > 5stars F8 show-text ${playlist} 5000 #menu: Tools > Show Playlist
F9 show-text ${track-list} 5000 #menu: Tools > Show Audio/Video/Subtitle List
_ script-message mpv.net set-setting hwdec yes #menu: _ ; Settings > Hardware Decoding > Enable _ script-message mpv.net execute-mpv-command #menu: Tools > Execute mpv command...
_ script-message mpv.net set-setting hwdec no #menu: _ ; Settings > Hardware Decoding > Disable _ script-message mpv.net shell-execute https://mpv.io/manual/stable/ #menu: Help > Show mpv manual
p script-message mpv.net show-prefs #menu: P ; Settings > Show mpv config file _ script-message mpv.net shell-execute https://github.com/mpv-player/mpv/blob/master/etc/input.conf #menu: Help > Show mpv default keys
e script-message mpv.net show-conf-editor #menu: E ; Settings > Show mpv config editor _ script-message mpv.net shell-execute https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/input.conf.txt #menu: Help > Show mpv.net default keys
k script-message mpv.net show-keys #menu: K ; Settings > Show Keys _ script-message mpv.net shell-execute https://github.com/stax76/mpvnet #menu: Help > Show mpv.net web site
c script-message mpv.net open-config-folder #menu: C ; Settings > Open Config Folder _ ignore #menu: -
Esc quit #menu: Exit
i script-message mpv.net show-info #menu: I ; Tools | Info Q quit-watch-later #menu: Exit Watch Later
t script-binding stats/display-stats #menu: T ; Tools > Show Statistics
T script-binding stats/display-stats-toggle #menu: Shift+T ; Tools > Toggle Statistics
_ ignore #menu: _ ; Tools > -
h script-message mpv.net history #menu: H ; Tools > Show History
l ab-loop #menu: L ; Tools > Set/clear A-B loop points
L cycle-values loop-file "inf" "no" #menu: Shift+L ; Tools > Toggle Infinite Looping
DEL script-binding osc/visibility #menu: Delete ; Tools > Toggle OSC Visibility
Ctrl+H cycle-values hwdec "auto" "no" #menu: Ctrl+H ; Tools > Cycle Hardware Decoding
F8 show-text ${playlist} 5000 #menu: F8 ; Tools > Show Playlist
F9 show-text ${track-list} 5000 #menu: F9 ; Tools > Show Audio/Video/Subtitle List
_ script-message mpv.net shell-execute https://mpv.io/manual/stable/ #menu: _ ; Help > Show mpv manual
_ script-message mpv.net shell-execute https://github.com/mpv-player/mpv/blob/master/etc/input.conf #menu: _ ; Help > Show mpv default keys
_ script-message mpv.net shell-execute https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/input.conf.txt #menu: _ ; Help > Show mpv.net default keys
_ script-message mpv.net shell-execute https://github.com/stax76/mpvnet #menu: _ ; Help > Show mpv.net web site
_ ignore #menu: _ ; -
Esc quit #menu: Escape ; Exit
Q quit-watch-later #menu: Shift+Q ; Exit Watch Later
> playlist-next > playlist-next
< playlist-prev < playlist-prev
Enter cycle pause
POWER quit Power quit
PLAY cycle pause Play cycle pause
PAUSE cycle pause Pause cycle pause
PLAYPAUSE cycle pause PlayPause cycle pause
STOP quit Stop quit
FORWARD seek 60 Forward seek 60
REWIND seek -60 Rewind seek -60
VOLUME_UP add volume 2 Mute cycle mute
VOLUME_DOWN add volume -2 Volume_Up add volume 10
MUTE cycle mute Volume_Down add volume -10
Wheel_Up add volume 10
Wheel_Down add volume -10

View File

@@ -9,4 +9,5 @@ vo = direct3d
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/ screenshot-directory = ~~desktop/
input-default-bindings = no

View File

@@ -418,6 +418,8 @@ namespace mpvnet
foreach (string i in args) foreach (string i in args)
if (!i.StartsWith("--") && File.Exists(i)) if (!i.StartsWith("--") && File.Exists(i))
mp.commandv("loadfile", i, "append"); mp.commandv("loadfile", i, "append");
else if (!i.StartsWith("--") && i.StartsWith("http"))
mp.LoadURL(i);
mp.set_property_string("playlist-pos", "0"); mp.set_property_string("playlist-pos", "0");
@@ -437,6 +439,15 @@ namespace mpvnet
} }
} }
public static void LoadURL(string url)
{
int count = mp.get_property_int("playlist-count");
mp.commandv("loadfile", url, "append");
mp.set_property_int("playlist-pos", count);
for (int i = 0; i < count; i++)
mp.commandv("playlist-remove", "0");
}
public static void LoadFiles(string[] files) public static void LoadFiles(string[] files)
{ {
int count = mp.get_property_int("playlist-count"); int count = mp.get_property_int("playlist-count");

View File

@@ -19,7 +19,7 @@
<DebugSymbols>true</DebugSymbols> <DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType> <DebugType>full</DebugType>
<Optimize>false</Optimize> <Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath> <OutputPath>bin\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants> <DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
@@ -30,7 +30,7 @@
<PlatformTarget>AnyCPU</PlatformTarget> <PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType> <DebugType>pdbonly</DebugType>
<Optimize>true</Optimize> <Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath> <OutputPath>bin\</OutputPath>
<DefineConstants>TRACE</DefineConstants> <DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
@@ -118,6 +118,7 @@
<SpecificVersion>False</SpecificVersion> <SpecificVersion>False</SpecificVersion>
<HintPath>IronPython\Microsoft.Scripting.dll</HintPath> <HintPath>IronPython\Microsoft.Scripting.dll</HintPath>
</Reference> </Reference>
<Reference Include="Microsoft.VisualBasic" />
<Reference Include="System" /> <Reference Include="System" />
<Reference Include="System.ComponentModel.Composition" /> <Reference Include="System.ComponentModel.Composition" />
<Reference Include="System.Core" /> <Reference Include="System.Core" />
@@ -131,7 +132,6 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="Addon.cs" /> <Compile Include="Addon.cs" />
<Compile Include="Extensions.cs" />
<Compile Include="MediaInfo.cs" /> <Compile Include="MediaInfo.cs" />
<Compile Include="Menu.cs"> <Compile Include="Menu.cs">
<SubType>Component</SubType> <SubType>Component</SubType>
@@ -157,6 +157,7 @@
<Compile Include="NativeHelp.cs" /> <Compile Include="NativeHelp.cs" />
<Compile Include="Program.cs" /> <Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="trash.cs" />
<Compile Include="UI.cs" /> <Compile Include="UI.cs" />
<EmbeddedResource Include="MainForm.resx"> <EmbeddedResource Include="MainForm.resx">
<DependentUpon>MainForm.cs</DependentUpon> <DependentUpon>MainForm.cs</DependentUpon>

22
mpv.net/trash.cs Normal file
View File

@@ -0,0 +1,22 @@
//public static string GetAssociatedApplication(string ext)
//{
// uint returnValue = 0U;
// // ASSOCF_VERIFY, ASSOCSTR_EXECUTABLE
// if (1 == Native.AssocQueryString(0x40, 2, ext, null, null, ref returnValue))
// {
// if (returnValue > 0)
// {
// StringBuilder sb = new StringBuilder(Convert.ToInt32(returnValue));
// // ASSOCF_VERIFY, ASSOCSTR_EXECUTABLE
// if (0 == Native.AssocQueryString(0x40, 2, ext, null, sb, ref returnValue))
// {
// var ret = sb.ToString();
// if (File.Exists(ret)) return ret;
// }
// }
// }
// return "";
//}
//[DllImport("Shlwapi.dll", SetLastError = true, CharSet = CharSet.Unicode)]
//public static extern uint AssocQueryString(uint flags, uint str, string pszAssoc, string pszExtra, StringBuilder pszOut, ref uint pcchOut);

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<configuration> <configuration>
<startup> <startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8"/> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2"/>
</startup> </startup>
</configuration> </configuration>

View File

@@ -1,6 +1,9 @@
using System.Collections.Generic; using System;
using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.IO; using System.IO;
using System.Windows.Documents;
using System.Windows.Navigation;
using Tommy; using Tommy;
namespace DynamicGUI namespace DynamicGUI
@@ -33,6 +36,8 @@ namespace DynamicGUI
opt.Help = option["help"]; opt.Help = option["help"];
if (option.HasKey("text")) if (option.HasKey("text"))
opt.Text = option["text"]; opt.Text = option["text"];
else if (opt.Name == optionSetting.Default)
opt.Text = opt.Name + " (Default)";
opt.OptionSetting = optionSetting; opt.OptionSetting = optionSetting;
optionSetting.Options.Add(opt); optionSetting.Options.Add(opt);
} }
@@ -105,4 +110,27 @@ namespace DynamicGUI
} }
} }
} }
interface ISettingControl
{
bool Contains(string searchString);
SettingBase SettingBase { get; }
}
public class HyperlinkEx : Hyperlink
{
private void HyperLinkEx_RequestNavigate(object sender, RequestNavigateEventArgs e)
{
Process.Start(e.Uri.AbsoluteUri);
}
public void SetURL(string url)
{
if (string.IsNullOrEmpty(url)) return;
NavigateUri = new Uri(url);
RequestNavigate += HyperLinkEx_RequestNavigate;
Inlines.Clear();
Inlines.Add(url);
}
}
} }

View File

@@ -1,4 +1,4 @@
<Window x:Name="MainWindow1" x:Class="mpvSettingsEditor.MainWindow" <Window xmlns:Controls="clr-namespace:Controls" x:Name="MainWindow1" x:Class="mpvConfEdit.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
@@ -14,12 +14,8 @@
<ColumnDefinition Width="10*" /> <ColumnDefinition Width="10*" />
<ColumnDefinition Width="60*" /> <ColumnDefinition Width="60*" />
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<Grid x:Name="SearchGrid" Background="White" Width="300" Margin="0,0,0,10" Grid.ColumnSpan="2"> <Controls:SearchTextBoxUserControl x:Name="SearchControl" Width="300" Margin="0,0,0,10" Grid.ColumnSpan="2" />
<TextBlock x:Name="SearchTextBlock" Margin="5,2" Text="Find a setting" Foreground="LightSteelBlue" VerticalAlignment="Center" /> <ScrollViewer x:Name="MainScrollViewer" VerticalScrollBarVisibility="Auto" Grid.Row="1" Grid.Column="1">
<TextBox Name="SearchTextBox" Padding="1,2,0,0" BorderThickness="2" Background="Transparent" TextChanged="SearchTextBox_TextChanged" Height="25" />
<Button x:Name="SearchClearButton" Background="Transparent" HorizontalAlignment="Right" Margin="2,0,4,0" FontSize="6" Width="16" Height="16" Visibility="Hidden" Click="SearchClearButton_Click"></Button>
</Grid>
<ScrollViewer VerticalScrollBarVisibility="Auto" Grid.Row="1" Grid.Column="1">
<StackPanel x:Name="MainStackPanel"></StackPanel> <StackPanel x:Name="MainStackPanel"></StackPanel>
</ScrollViewer> </ScrollViewer>
<StackPanel Margin="20,0,0,0" Grid.Row="1"> <StackPanel Margin="20,0,0,0" Grid.Row="1">
@@ -34,6 +30,7 @@
</ListBox> </ListBox>
<TextBlock x:Name="OpenSettingsTextBlock" Margin="0,30,0,0" Cursor="Hand" TextWrapping="WrapWithOverflow" Foreground="{x:Static SystemParameters.WindowGlassBrush}" MouseUp="OpenSettingsTextBlock_MouseUp">Open settings folder</TextBlock> <TextBlock x:Name="OpenSettingsTextBlock" Margin="0,30,0,0" Cursor="Hand" TextWrapping="WrapWithOverflow" Foreground="{x:Static SystemParameters.WindowGlassBrush}" MouseUp="OpenSettingsTextBlock_MouseUp">Open settings folder</TextBlock>
<TextBlock x:Name="ShowManualTextBlock" Margin="0,15,0,0" Cursor="Hand" TextWrapping="WrapWithOverflow" Foreground="{x:Static SystemParameters.WindowGlassBrush}" MouseUp="ShowManualTextBlock_MouseUp">Show mpv manual</TextBlock> <TextBlock x:Name="ShowManualTextBlock" Margin="0,15,0,0" Cursor="Hand" TextWrapping="WrapWithOverflow" Foreground="{x:Static SystemParameters.WindowGlassBrush}" MouseUp="ShowManualTextBlock_MouseUp">Show mpv manual</TextBlock>
<TextBlock x:Name="SupportTextBlock" Margin="0,15,0,0" Cursor="Hand" TextWrapping="WrapWithOverflow" Foreground="{x:Static SystemParameters.WindowGlassBrush}" MouseUp="SupportTextBlock_MouseUp">Show support forum</TextBlock>
</StackPanel> </StackPanel>
</Grid> </Grid>
</Window> </Window>

View File

@@ -1,5 +1,4 @@
using DynamicGUI; using System;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Diagnostics; using System.Diagnostics;
@@ -10,18 +9,21 @@ using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
using System.Windows.Input; using System.Windows.Input;
namespace mpvSettingsEditor using DynamicGUI;
namespace mpvConfEdit
{ {
public partial class MainWindow : Window public partial class MainWindow : Window
{ {
public string mpvConfPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\mpv\\mpv.conf"; public string mpvConfPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\mpv\\mpv.conf";
private List<SettingBase> DynamicSettings = Settings.LoadSettings(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location) + "\\Definitions.toml"); private List<SettingBase> DynamicSettings = Settings.LoadSettings(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location) + "\\mpvConfEdit.toml");
public MainWindow() public MainWindow()
{ {
InitializeComponent(); InitializeComponent();
DataContext = this; DataContext = this;
Title = (Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyProductAttribute), true)[0] as AssemblyProductAttribute).Product + " " + Assembly.GetExecutingAssembly().GetName().Version.ToString(); Title = (Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyProductAttribute), true)[0] as AssemblyProductAttribute).Product + " " + Assembly.GetExecutingAssembly().GetName().Version.ToString();
SearchControl.SearchTextBox.TextChanged += SearchTextBox_TextChanged;
foreach (var setting in DynamicSettings) foreach (var setting in DynamicSettings)
{ {
@@ -149,7 +151,7 @@ namespace mpvSettingsEditor
File.WriteAllText(mpvConfPath, String.Join(Environment.NewLine, lines)); File.WriteAllText(mpvConfPath, String.Join(Environment.NewLine, lines));
foreach (Process process in Process.GetProcesses()) foreach (Process process in Process.GetProcesses())
if (process.ProcessName == "mpv.net") if (process.ProcessName == "mpvnet")
MessageBox.Show("Restart mpv.net in order to apply changed settings.", Title, MessageBoxButton.OK, MessageBoxImage.Information); MessageBox.Show("Restart mpv.net in order to apply changed settings.", Title, MessageBoxButton.OK, MessageBoxImage.Information);
else if (process.ProcessName == "mpv") else if (process.ProcessName == "mpv")
MessageBox.Show("Restart mpv in order to apply changed settings.", Title, MessageBoxButton.OK, MessageBoxImage.Information); MessageBox.Show("Restart mpv in order to apply changed settings.", Title, MessageBoxButton.OK, MessageBoxImage.Information);
@@ -157,23 +159,16 @@ namespace mpvSettingsEditor
private void SearchTextBox_TextChanged(object sender, TextChangedEventArgs e) private void SearchTextBox_TextChanged(object sender, TextChangedEventArgs e)
{ {
SearchTextBlock.Text = SearchTextBox.Text == "" ? "Find a setting" : "";
if (SearchTextBox.Text == "")
SearchClearButton.Visibility = Visibility.Hidden;
else
SearchClearButton.Visibility = Visibility.Visible;
string activeFilter = ""; string activeFilter = "";
foreach (var i in FilterStrings) foreach (var i in FilterStrings)
if (SearchTextBox.Text == i + ":") if (SearchControl.Text == i + ":")
activeFilter = i; activeFilter = i;
if (activeFilter == "") if (activeFilter == "")
{ {
foreach (UIElement i in MainStackPanel.Children) foreach (UIElement i in MainStackPanel.Children)
if ((i as ISettingControl).Contains(SearchTextBox.Text)) if ((i as ISettingControl).Contains(SearchControl.Text))
i.Visibility = Visibility.Visible; i.Visibility = Visibility.Visible;
else else
i.Visibility = Visibility.Collapsed; i.Visibility = Visibility.Collapsed;
@@ -186,23 +181,19 @@ namespace mpvSettingsEditor
i.Visibility = Visibility.Visible; i.Visibility = Visibility.Visible;
else else
i.Visibility = Visibility.Collapsed; i.Visibility = Visibility.Collapsed;
MainScrollViewer.ScrollToTop();
} }
private void MainWindow1_Loaded(object sender, RoutedEventArgs e) private void MainWindow1_Loaded(object sender, RoutedEventArgs e)
{ {
Keyboard.Focus(SearchTextBox); Keyboard.Focus(SearchControl.SearchTextBox);
} }
private void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e) private void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{ {
if (e.AddedItems.Count > 0) if (e.AddedItems.Count > 0)
SearchTextBox.Text = e.AddedItems[0].ToString() + ":"; SearchControl.Text = e.AddedItems[0].ToString() + ":";
}
private void SearchClearButton_Click(object sender, RoutedEventArgs e)
{
SearchTextBox.Text = "";
Keyboard.Focus(SearchTextBox);
} }
private void OpenSettingsTextBlock_MouseUp(object sender, MouseButtonEventArgs e) private void OpenSettingsTextBlock_MouseUp(object sender, MouseButtonEventArgs e)
@@ -214,5 +205,10 @@ namespace mpvSettingsEditor
{ {
Process.Start("https://mpv.io/manual/master/"); Process.Start("https://mpv.io/manual/master/");
} }
private void SupportTextBlock_MouseUp(object sender, MouseButtonEventArgs e)
{
Process.Start("https://github.com/stax76/mpv.net#Support");
}
} }
} }

View File

@@ -0,0 +1,55 @@
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Windows;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("mpv(.net) conf edit")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("mpv(.net) conf edit")]
[assembly: AssemblyCopyright("Copyright © stax76")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
//In order to begin building localizable applications, set
//<UICulture>CultureYouAreCodingWith</UICulture> in your .csproj file
//inside a <PropertyGroup>. For example, if you are using US english
//in your source files, set the <UICulture> to en-US. Then uncomment
//the NeutralResourceLanguage attribute below. Update the "en-US" in
//the line below to match the UICulture setting in the project file.
//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
[assembly: ThemeInfo(
ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
//(used if a resource is not found in the page,
// or application resource dictionaries)
ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
//(used if a resource is not found in the page,
// app, or any theme specific resource dictionaries)
)]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.1.0.0")]
[assembly: AssemblyFileVersion("1.1.0.0")]

View File

@@ -8,7 +8,7 @@
// </auto-generated> // </auto-generated>
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
namespace DynamicGUI.Properties { namespace mpvConfEdit.Properties {
using System; using System;
@@ -39,7 +39,7 @@ namespace DynamicGUI.Properties {
internal static global::System.Resources.ResourceManager ResourceManager { internal static global::System.Resources.ResourceManager ResourceManager {
get { get {
if (object.ReferenceEquals(resourceMan, null)) { if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("mpvSettingsEditor.Properties.Resources", typeof(Resources).Assembly); global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("mpvConfEdit.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp; resourceMan = temp;
} }
return resourceMan; return resourceMan;

View File

@@ -8,7 +8,7 @@
// </auto-generated> // </auto-generated>
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
namespace DynamicGUI.Properties { namespace mpvConfEdit.Properties {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]

View File

@@ -0,0 +1,13 @@
<UserControl x:Class="Controls.SearchTextBoxUserControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Grid x:Name="SearchTextBoxUserControl1" Background="White">
<TextBlock x:Name="SearchTextBlock" Margin="5,2" Text="Find a setting" Foreground="LightSteelBlue" VerticalAlignment="Center" />
<TextBox Name="SearchTextBox" Height="25" Padding="1,2,0,0" BorderThickness="2" Background="Transparent" TextChanged="SearchTextBox_TextChanged" />
<Button x:Name="SearchClearButton" Background="Transparent" HorizontalAlignment="Right" Margin="2,0,4,0" FontSize="5" Width="17" Height="17" Visibility="Hidden" Click="SearchClearButton_Click"></Button>
</Grid>
</UserControl>

View File

@@ -0,0 +1,32 @@
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
namespace Controls
{
public partial class SearchTextBoxUserControl : UserControl
{
public SearchTextBoxUserControl()
{
InitializeComponent();
}
public string Text { get => SearchTextBox.Text; set => SearchTextBox.Text = value; }
private void SearchClearButton_Click(object sender, RoutedEventArgs e)
{
SearchTextBox.Text = "";
Keyboard.Focus(SearchTextBox);
}
private void SearchTextBox_TextChanged(object sender, TextChangedEventArgs e)
{
SearchTextBlock.Text = SearchTextBox.Text == "" ? "Find a setting" : "";
if (SearchTextBox.Text == "")
SearchClearButton.Visibility = Visibility.Hidden;
else
SearchClearButton.Visibility = Visibility.Visible;
}
}
}

View File

Before

Width:  |  Height:  |  Size: 264 KiB

After

Width:  |  Height:  |  Size: 264 KiB

View File

@@ -6,9 +6,9 @@
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{C4FEAA45-001D-4DC8-8BFA-621527326D09}</ProjectGuid> <ProjectGuid>{C4FEAA45-001D-4DC8-8BFA-621527326D09}</ProjectGuid>
<OutputType>WinExe</OutputType> <OutputType>WinExe</OutputType>
<RootNamespace>mpvSettingsEditor</RootNamespace> <RootNamespace>mpvConfEdit</RootNamespace>
<AssemblyName>mpvSettingsEditor</AssemblyName> <AssemblyName>mpvConfEdit</AssemblyName>
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion> <TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment> <FileAlignment>512</FileAlignment>
<ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> <ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
@@ -21,7 +21,7 @@
<DebugSymbols>true</DebugSymbols> <DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType> <DebugType>full</DebugType>
<Optimize>false</Optimize> <Optimize>false</Optimize>
<OutputPath>bin\</OutputPath> <OutputPath>..\mpv.net\bin\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants> <DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
@@ -34,7 +34,7 @@
<PlatformTarget>AnyCPU</PlatformTarget> <PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType> <DebugType>pdbonly</DebugType>
<Optimize>true</Optimize> <Optimize>true</Optimize>
<OutputPath>bin\</OutputPath> <OutputPath>..\mpv.net\bin\</OutputPath>
<DefineConstants>TRACE</DefineConstants> <DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
@@ -66,7 +66,6 @@
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType> <SubType>Designer</SubType>
</ApplicationDefinition> </ApplicationDefinition>
<Compile Include="DynamicGUI\Controls.cs" />
<Compile Include="DynamicGUI\DynamicGUI.cs" /> <Compile Include="DynamicGUI\DynamicGUI.cs" />
<Compile Include="DynamicGUI\OptionSettingControl.xaml.cs"> <Compile Include="DynamicGUI\OptionSettingControl.xaml.cs">
<DependentUpon>OptionSettingControl.xaml</DependentUpon> <DependentUpon>OptionSettingControl.xaml</DependentUpon>
@@ -75,6 +74,9 @@
<DependentUpon>StringSettingControl.xaml</DependentUpon> <DependentUpon>StringSettingControl.xaml</DependentUpon>
</Compile> </Compile>
<Compile Include="DynamicGUI\Tommy.cs" /> <Compile Include="DynamicGUI\Tommy.cs" />
<Compile Include="SearchTextBoxUserControl.xaml.cs">
<DependentUpon>SearchTextBoxUserControl.xaml</DependentUpon>
</Compile>
<Page Include="DynamicGUI\OptionSettingControl.xaml"> <Page Include="DynamicGUI\OptionSettingControl.xaml">
<SubType>Designer</SubType> <SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>
@@ -95,9 +97,12 @@
<DependentUpon>MainWindow.xaml</DependentUpon> <DependentUpon>MainWindow.xaml</DependentUpon>
<SubType>Code</SubType> <SubType>Code</SubType>
</Compile> </Compile>
<Page Include="SearchTextBoxUserControl.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="DynamicGUI\Misc.cs" />
<Compile Include="Properties\AssemblyInfo.cs"> <Compile Include="Properties\AssemblyInfo.cs">
<SubType>Code</SubType> <SubType>Code</SubType>
</Compile> </Compile>
@@ -124,7 +129,7 @@
<None Include="App.config" /> <None Include="App.config" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="Definitions.toml"> <None Include="mpvConfEdit.toml">
<CopyToOutputDirectory>Always</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None> </None>
</ItemGroup> </ItemGroup>

View File

@@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16 # Visual Studio Version 16
VisualStudioVersion = 16.0.28714.193 VisualStudioVersion = 16.0.28714.193
MinimumVisualStudioVersion = 10.0.40219.1 MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "mpvSettingsEditor", "mpvSettingsEditor.csproj", "{C4FEAA45-001D-4DC8-8BFA-621527326D09}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "mpvConfEdit", "mpvConfEdit.csproj", "{C4FEAA45-001D-4DC8-8BFA-621527326D09}"
EndProject EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution

View File

@@ -0,0 +1,181 @@
[[settings]]
name = "hwdec"
default = "no"
filter = "Video"
helpurl = "https://mpv.io/manual/master/#options-hwdec"
help = "--hwdec=<mode> Specify the hardware video decoding API that should be used if possible. Whether hardware decoding is actually done depends on the video codec. If hardware decoding is not possible, mpv will fall back on software decoding.\n\nFor more information visit:"
options = [{ name = "no", help = "always use software decoding (Default)" },
{ name = "auto", help = "enable best hw decoder (see below)" },
{ name = "yes", help = "exactly the same as auto" },
{ name = "auto-copy", help = "enable best hw decoder with copy-back (see below)" },
{ name = "dxva2", help = "requires --vo=gpu with --gpu-context=d3d11, --gpu-context=angle or --gpu-context=dxinterop (Windows only)" },
{ name = "dxva2-copy", help = "copies video back to system RAM (Windows only)" },
{ name = "d3d11va", help = "requires --vo=gpu with --gpu-context=d3d11 or --gpu-context=angle (Windows 8+ only)" },
{ name = "d3d11va-copy", help = "copies video back to system RAM (Windows 8+ only)" },
{ name = "cuda", help = "requires --vo=gpu (Any platform CUDA is available)" },
{ name = "cuda-copy", help = "copies video back to system RAM (Any platform CUDA is available)" },
{ name = "nvdec", help = "requires --vo=gpu (Any platform CUDA is available)" },
{ name = "nvdec-copy", help = "copies video back to system RAM (Any platform CUDA is available)" },
{ name = "crystalhd", help = "copies video back to system RAM (Any platform supported by hardware)" },
{ name = "rkmpp", help = "requires --vo=gpu (some RockChip devices only)" }]
[[settings]]
name = "vo"
default = "gpu"
filter = "Video"
helpurl = "https://mpv.io/manual/master/#video-output-drivers-vo"
help = "--gpu=<mode> Video output drivers to be used. Default = gpu.\n\nFor more information visit:"
options = [{ name = "gpu", help = "General purpose, customizable, GPU-accelerated video output driver. It supports extended scaling methods, dithering, color management, custom shaders, HDR, and more. (Default)" },
{ name = "direct3d", help = "Video output driver that uses the Direct3D interface" }]
[[settings]]
name = "volume"
default = "100"
filter = "Audio"
help = "--volume=<integer> Set the startup volume. 0 means silence, 100 means no volume reduction or amplification. Negative values can be passed for compatibility, but are treated as 0. Since mpv 0.18.1, this always controls the internal mixer (aka \"softvol\"). Default: 100"
[[settings]]
name = "slang"
default = ""
filter = "Subtitle"
help = "--slang=<languagecode[,languagecode,...]> Specify a priority list of subtitle languages to use. Different container formats employ different language codes. DVDs use ISO 639-1 two letter language codes, Matroska uses ISO 639-2 three letter language codes while OGM uses a free-form identifier. See also --sid."
[[settings]]
name = "screen"
default = ""
filter = "Screen"
help = "--screen=<default|0-32> In multi-monitor configurations (i.e. a single desktop that spans across multiple displays), this option tells mpv which screen to display the video on. Default: default."
[[settings]]
name = "osd-playing-msg"
default = ""
width = 300
filter = "Screen"
help = "--osd-playing-msg=<value> Show a message on OSD when playback starts. The string is expanded for properties, e.g. --osd-playing-msg='file: ${filename}' will show the message file: followed by a space and the currently played filename.\n\nFor more information visit:"
helpurl = "https://mpv.io/manual/master/#property-expansion"
[[settings]]
name = "fullscreen"
alias = "fs"
default = "no"
filter = "Screen"
help = "--fullscreen=<yes|no>, fs=<yes|no> Start the player in fullscreen mode. Default: no."
options = [{ name = "yes" },
{ name = "no" }]
[[settings]]
name = "keep-open-pause"
default = "yes"
filter = "Playback"
help = "--keep-open-pause=<yes|no> If set to no, instead of pausing when --keep-open is active, just stop at end of file and continue playing forward when you seek backwards until end where it stops again. Default: yes."
options = [{ name = "yes" },
{ name = "no" }]
[[settings]]
name = "keep-open"
default = "no"
filter = "Playback"
help = "--keep-open=<yes|no|always> 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."
options = [{ name = "yes", help = "Don't terminate if the current file is the last playlist entry. Equivalent to --keep-open without arguments."},
{ name = "no", help = "If the current file ends, go to the next file or terminate. (Default.)" },
{ 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."}]
[[settings]]
name = "loop-file"
alias = "loop"
default = ""
filter = "Playback"
help = "--loop-file=<N|inf|no>, loop=<N|inf|no> Loop a single file N times. inf means forever, no means normal playback. For compatibility, --loop-file and --loop-file=yes are also accepted, and are the same as --loop-file=inf.\n\nThe difference to --loop-playlist is that this doesn't loop the playlist, just the file itself. If the playlist contains only a single file, the difference between the two option is that this option performs a seek on loop, instead of reloading the file.\n\n--loop is an alias for this option."
[[settings]]
name = "save-position-on-quit"
default = "no"
filter = "Playback"
help = "--save-position-on-quit=<yes|no> Always save the current playback position on quit. When this file is played again later, the player will seek to the old playback position on start. This does not happen if playback of a file is stopped in any other way than quitting. For example, going to the next file in the playlist will not save the position, and start playback at beginning the next time the file is played.\n\nThis behavior is disabled by default, but is always available when quitting the player with Shift+Q."
options = [{ name = "yes" },
{ name = "no" }]
[[settings]]
name = "screenshot-directory"
default = ""
width = 500
folder = true
filter = "Screen"
help = "--screenshot-directory=<value> Store screenshots in this directory. This path is joined with the filename generated by --screenshot-template. If the template filename is already absolute, the directory is ignored.\n\nIf the directory does not exist, it is created on the first screenshot. If it is not a directory, an error is generated when trying to write a screenshot.\n\nThis option is not set by default, and thus will write screenshots to the directory from which mpv was started. In pseudo-gui mode (see PSEUDO GUI MODE), this is set to the desktop."
[[settings]]
name = "input-ar-delay"
default = ""
filter = "Input"
help = "--input-ar-delay=<integer> Delay in milliseconds before we start to autorepeat a key (0 to disable)."
[[settings]]
name = "input-ar-rate"
default = ""
filter = "Input"
help = "--input-ar-rate=<integer> Number of key presses to generate per second on autorepeat."
[[settings]]
name = "alang"
default = ""
filter = "Audio"
help = "--alang=<languagecode[,languagecode,...]> Specify a priority list of audio languages to use. Different container formats employ different language codes. DVDs use ISO 639-1 two-letter language codes, Matroska, MPEG-TS and NUT use ISO 639-2 three-letter language codes, while OGM uses a free-form identifier. See also --aid.\n\nExamples\n\nmpv dvd://1 --alang=hu,en chooses the Hungarian language track on a DVD and falls back on English if Hungarian is not available.\n\nmpv --alang=jpn example.mkv plays a Matroska file with Japanese audio."
[[settings]]
name = "hr-seek"
default = "absolute"
filter = "Playback"
help = "--hr-seek=<no|absolute|yes> Select when to use precise seeks that are not limited to keyframes. Such seeks require decoding video from the previous keyframe up to the target position and so can take some time depending on decoding performance. For some video formats, precise seeks are disabled. This option selects the default choice to use for seeks; it is possible to explicitly override that default in the definition of key bindings and in input commands."
options = [{ name = "yes", help = "Use precise seeks whenever possible." },
{ name = "no", help = "Never use precise seeks." },
{ name = "absolute", help = "Use precise seeks if the seek is to an absolute position in the file, such as a chapter seek, but not for relative seeks like the default behavior of arrow keys (default)." },
{ name = "always", help = "Same as yes (for compatibility)." }]
[[settings]]
name = "track-auto-selection"
default = "yes"
filter = "Playback"
help = "--track-auto-selection=<yes|no> Enable the default track auto-selection (default: yes). Enabling this will make the player select streams according to --aid, --alang, and others. If it is disabled, no tracks are selected. In addition, the player will not exit if no tracks are selected, and wait instead (this wait mode is similar to pausing, but the pause option is not set).\n\nThis is useful with --lavfi-complex: you can start playback in this mode, and then set select tracks at runtime by setting the filter graph. Note that if --lavfi-complex is set before playback is started, the referenced tracks are always selected."
options = [{ name = "yes" },
{ name = "no" }]
[[settings]]
name = "loop-playlist"
default = ""
filter = "Playback"
help = "--loop-playlist=<N|inf|force|no>, --loop-playlist Loops playback N times. A value of 1 plays it one time (default), 2 two times, etc. inf means forever. no is the same as 1 and disables looping. If several files are specified on command line, the entire playlist is looped. --loop-playlist is the same as --loop-playlist=inf.\n\nThe force mode is like inf, but does not skip playlist entries which have been marked as failing. This means the player might waste CPU time trying to loop a file that doesn't exist. But it might be useful for playing webradios under very bad network conditions."
[[settings]]
name = "video-sync"
default = "audio"
filter = "Video"
help = "--video-sync=<audio|...> How the player synchronizes audio and video.\n\nFor more information visit:"
helpurl = "https://mpv.io/manual/master/#options-video-sync"
options = [{ name = "audio" },
{ name = "display-resample" },
{ name = "display-resample-vdrop" },
{ name = "display-resample-desync" },
{ name = "display-vdrop" },
{ name = "display-adrop" },
{ name = "display-desync" },
{ name = "desync" }]
[[settings]]
name = "audio-file-auto"
default = "no"
filter = "Audio"
help = "--audio-file-auto=<no|exact|fuzzy|all>, --no-audio-file-auto Load additional audio files matching the video filename. The parameter specifies how external audio files are matched."
options = [{ name = "no", help = "Don't automatically load external audio files (default)." },
{ name = "exact", help = "Load the media filename with audio file extension." },
{ name = "fuzzy", help = "Load all audio files containing media filename." },
{ name = "all", help = "Load all audio files in the current and --audio-file-paths directories." }]
[[settings]]
name = "sub-auto"
default = "exact"
filter = "Subtitle"
help = "--sub-auto=<no|exact|fuzzy|all>, --no-sub-auto Load additional subtitle files matching the video filename. The parameter specifies how external subtitle files are matched. exact is enabled by default."
options = [{ name = "no", help = "Don't automatically load external subtitle files." },
{ name = "exact", help = "Load the media filename with subtitle file extension (Default)." },
{ name = "fuzzy", help = "Load all subs containing media filename." },
{ name = "all", help = "Load all subs in the current and --sub-file-paths directories." }]

6
mpvInputEdit/App.config Normal file
View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
</startup>
</configuration>

42
mpvInputEdit/App.xaml Normal file
View File

@@ -0,0 +1,42 @@
<Application x:Class="mpvInputEdit.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:mpvInputEdit"
StartupUri="MainWindow.xaml">
<Application.Resources>
<Style TargetType="TextBox">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBox}">
<Border x:Name="border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
<ScrollViewer x:Name="PART_ContentHost" Focusable="false" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Opacity" TargetName="border" Value="0.56"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="BorderBrush" TargetName="border" Value="#FF7EB4EA"/>
</Trigger>
<Trigger Property="IsFocused" Value="true">
<Setter Property="BorderBrush" TargetName="border" Value="{x:Static SystemParameters.WindowGlassBrush}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="DataGrid_Font_Centering"
TargetType="{x:Type DataGridCell}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridCell}">
<Grid Background="{TemplateBinding Background}">
<ContentPresenter VerticalAlignment="Center" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Application.Resources>
</Application>

56
mpvInputEdit/App.xaml.cs Normal file
View File

@@ -0,0 +1,56 @@
using System;
using System.Collections.ObjectModel;
using System.IO;
using System.Windows;
namespace mpvInputEdit
{
public partial class App : Application
{
public static string InputConfPath { get; } = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\mpv\\input.conf";
private static ObservableCollection<InputItem> _InputItems;
public static ObservableCollection<InputItem> InputItems
{
get
{
if (_InputItems is null)
{
_InputItems = new ObservableCollection<InputItem>();
if (File.Exists(InputConfPath))
{
foreach (string line in File.ReadAllLines(InputConfPath))
{
string l = line.Trim();
if (l.StartsWith("#")) continue;
if (!l.Contains(" ")) continue;
InputItem item = new InputItem();
item.Key = l.Substring(0, l.IndexOf(" "));
if (item.Key == "") continue;
l = l.Substring(l.IndexOf(" ") + 1);
if (l.Contains("#menu:"))
{
item.Menu = l.Substring(l.IndexOf("#menu:") + 6).Trim();
l = l.Substring(0, l.IndexOf("#menu:"));
if (item.Menu.Contains(";"))
item.Menu = item.Menu.Substring(item.Menu.IndexOf(";") + 1).Trim();
}
item.Command = l.Trim();
if (item.Command == "")
continue;
if (item.Command.ToLower() == "ignore")
item.Command = "";
_InputItems.Add(item);
}
}
}
return _InputItems;
}
}
}
}

View File

@@ -0,0 +1,24 @@
<Window x:Class="mpvInputEdit.InputWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Title="Learn Input" Height="200" Width="400" WindowStartupLocation="CenterOwner"
ResizeMode="NoResize" Loaded="Window_Loaded" Background="Black" MouseWheel="Window_MouseWheel">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="40" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Label x:Name="MenuLabel" Grid.ColumnSpan="2" Foreground="White" VerticalAlignment="Center" HorizontalAlignment="Center" FontSize="16"></Label>
<Label x:Name="KeyLabel" Grid.Row="1" Grid.ColumnSpan="2" Foreground="White" VerticalAlignment="Top" HorizontalAlignment="Center" FontSize="16"></Label>
<Button x:Name="ConfirmButton" Grid.Row="2" Click="ConfirmButton_Click">Confirm</Button>
<Button x:Name="ClearButton" Grid.Row="2" Click="ClearButton_Click" Grid.Column="1">Clear</Button>
</Grid>
</Window>

View File

@@ -0,0 +1,296 @@
using System;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Input;
using System.Windows.Interop;
using WF = System.Windows.Forms;
namespace mpvInputEdit
{
public partial class InputWindow : Window
{
string InputString = "";
public InputItem InputItem { get; set; }
public string NewKey { get; set; } = "";
public InputWindow()
{
InitializeComponent();
}
private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
WF.Message m = new WF.Message();
m.HWnd = hwnd;
m.Msg = msg;
m.WParam = wParam;
m.LParam = lParam;
ProcessKeyEventArgs(ref m);
return m.Result;
}
void OnKeyUp(WF.KeyEventArgs e)
{
if (e.KeyCode == WF.Keys.None) return;
char c = Convert.ToChar(e.KeyCode);
string text = InputString;
if (e.KeyCode == WF.Keys.ControlKey || e.KeyCode == WF.Keys.ShiftKey ||
e.KeyCode == WF.Keys.Menu)
{
return;
}
if (text == "")
{
text = e.KeyCode.ToString();
if (text.Length == 1)
text = text.ToLowerInvariant();
}
for (int i = 0; i < 13; i++)
if ("D" + i.ToString() == text)
text = text.Substring(1);
//Debug.WriteLine((int)c);
//Debug.WriteLine(e.KeyCode.ToString());
switch (e.KeyCode)
{
case WF.Keys.NumPad0:
case WF.Keys.NumPad1:
case WF.Keys.NumPad2:
case WF.Keys.NumPad3:
case WF.Keys.NumPad4:
case WF.Keys.NumPad5:
case WF.Keys.NumPad6:
case WF.Keys.NumPad7:
case WF.Keys.NumPad8:
case WF.Keys.NumPad9:
text = "KP" + e.KeyCode.ToString()[6].ToString(); break;
case WF.Keys.Space:
text = "Space"; break;
case WF.Keys.Enter:
text = "Enter"; break;
case WF.Keys.Tab:
text = "Tab"; break;
case WF.Keys.Back:
text = "BS"; break;
case WF.Keys.Delete:
text = "Del"; break;
case WF.Keys.Insert:
text = "Ins"; break;
case WF.Keys.Home:
text = "Home"; break;
case WF.Keys.End:
text = "End"; break;
case WF.Keys.PageUp:
text = "PGUP"; break;
case WF.Keys.PageDown:
text = "PGDWN"; break;
case WF.Keys.Escape:
text = "Esc"; break;
case WF.Keys.PrintScreen:
text = "Print"; break;
case WF.Keys.Right:
text = "Right"; break;
case WF.Keys.Left:
text = "Left"; break;
case WF.Keys.Up:
text = "Up"; break;
case WF.Keys.Down:
text = "Down"; break;
case WF.Keys.Play:
text = "Play"; break;
case WF.Keys.Pause:
text = "Pause"; break;
case WF.Keys.MediaPlayPause:
text = "PlayPause"; break;
case WF.Keys.MediaStop:
text = "Stop"; break;
case WF.Keys.MediaNextTrack:
text = "Next"; break;
case WF.Keys.MediaPreviousTrack:
text = "Prev"; break;
case WF.Keys.VolumeUp:
text = "Volume_Up"; break;
case WF.Keys.VolumeDown:
text = "Volume_Down"; break;
case WF.Keys.VolumeMute:
text = "Mute"; break;
case WF.Keys.BrowserHome:
text = "Homepage"; break;
case WF.Keys.LaunchMail:
text = "Mail"; break;
case WF.Keys.BrowserFavorites:
text = "Favorites"; break;
case WF.Keys.BrowserSearch:
text = "Search"; break;
case WF.Keys.Sleep:
text = "Sleep"; break;
case WF.Keys.Cancel:
text = "Cancel"; break;
}
if (text == "#")
text = "Sharp";
bool isAlt = GetKeyState(18) < (short)0;
bool isShift = GetKeyState(16) < (short)0;
bool isCtrl = GetKeyState(17) < (short)0;
if (!(isAlt && isCtrl && !isShift) && !(isShift && !isAlt && !isCtrl && !int.TryParse(text.Replace("F", ""), out int value)))
{
if (isAlt) text = "Alt+" + text;
if (isShift) text = "Shift+" + text;
if (isCtrl) text = "Ctrl+" + text;
}
if (!string.IsNullOrEmpty(text))
SetKey(text);
}
void SetKey(string key)
{
NewKey = key;
MenuLabel.Content = InputItem.Menu;
KeyLabel.Content = key;
}
void OnKeyPress(WF.KeyPressEventArgs e)
{
if (char.IsControl(e.KeyChar))
InputString = "";
else
InputString = e.KeyChar.ToString();
}
public static WF.Keys ModifierKeys {
get {
WF.Keys keys = WF.Keys.None;
if (GetKeyState(17) < (short)0)
keys |= WF.Keys.Control;
if (GetKeyState(16) < (short)0)
keys |= WF.Keys.Shift;
if (GetKeyState(18) < (short)0)
keys |= WF.Keys.Alt;
return keys;
}
}
void ProcessKeyEventArgs(ref WF.Message m)
{
int WM_CHAR = 258, WM_SYSCHAR = 262, /*WM_KEYDOWN = 256, WM_SYSKEYDOWN = 260,*/
WM_KEYUP = 0x0101, WM_SYSKEYUP = 0x0105, WM_APPCOMMAND = 0x0319;
IntPtr newWParam = IntPtr.Zero;
WF.KeyEventArgs ke = null;
WF.KeyPressEventArgs kpe = null;
if (m.Msg == WM_CHAR || m.Msg == WM_SYSCHAR)
{
kpe = new WF.KeyPressEventArgs(unchecked((char)(long)m.WParam));
OnKeyPress(kpe);
newWParam = (IntPtr)kpe.KeyChar;
}
else
{
ke = new WF.KeyEventArgs((WF.Keys)(unchecked((int)(long)m.WParam)) | ModifierKeys);
//if (m.Msg == WM_KEYDOWN || m.Msg == WM_SYSKEYDOWN)
// OnKeyDown(ke);
if (m.Msg == WM_KEYUP || m.Msg == WM_SYSKEYUP)
OnKeyUp(ke);
if (m.Msg == WM_APPCOMMAND)
{
switch ((AppCommand)m.LParam.ToInt32())
{
case AppCommand.MEDIA_CHANNEL_DOWN:
SetKey("CHANNEL_DOWN");
break;
case AppCommand.MEDIA_CHANNEL_UP:
SetKey("CHANNEL_UP");
break;
case AppCommand.MEDIA_FAST_FORWARD:
SetKey("FORWARD");
break;
case AppCommand.MEDIA_NEXTTRACK:
SetKey("NEXT");
break;
case AppCommand.MEDIA_PAUSE:
SetKey("PAUSE");
break;
case AppCommand.MEDIA_PLAY:
SetKey("PLAY");
break;
case AppCommand.MEDIA_PLAY_PAUSE:
SetKey("PLAYPAUSE");
break;
case AppCommand.MEDIA_PREVIOUSTRACK:
SetKey("PREV");
break;
case AppCommand.MEDIA_RECORD:
SetKey("RECORD");
break;
case AppCommand.MEDIA_REWIND:
SetKey("REWIND");
break;
case AppCommand.MEDIA_STOP:
SetKey("STOP");
break;
}
}
}
if (kpe != null)
m.WParam = newWParam;
}
internal enum AppCommand
{
MEDIA_CHANNEL_DOWN = 52,
MEDIA_CHANNEL_UP = 51,
MEDIA_FAST_FORWARD = 49,
MEDIA_NEXTTRACK = 11,
MEDIA_PAUSE = 47,
MEDIA_PLAY = 46,
MEDIA_PLAY_PAUSE = 14,
MEDIA_PREVIOUSTRACK = 12,
MEDIA_RECORD = 48,
MEDIA_REWIND = 50,
MEDIA_STOP = 13
}
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern short GetKeyState(int keyCode);
private void Window_Loaded(object sender, RoutedEventArgs e)
{
HwndSource source = HwndSource.FromHwnd(new WindowInteropHelper(this).Handle);
source.AddHook(new HwndSourceHook(WndProc));
SetKey(InputItem.Key);
}
private void ConfirmButton_Click(object sender, RoutedEventArgs e)
{
InputItem.Key = NewKey;
Close();
}
private void ClearButton_Click(object sender, RoutedEventArgs e)
{
InputItem.Key = "_";
Close();
}
private void Window_MouseWheel(object sender, MouseWheelEventArgs e)
{
if (e.Delta > 0)
SetKey("WHEEL_UP");
else
SetKey("WHEEL_DOWN");
}
}
}

View File

@@ -0,0 +1,30 @@
<Window xmlns:Controls="clr-namespace:Controls" x:Class="mpvInputEdit.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Title="MainWindow" Height="500" Width="750" FontSize="13" Loaded="Window_Loaded" Closed="Window_Closed">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="60" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Controls:SearchTextBoxUserControl x:Name="SearchControl" Width="300" Margin="0,0,0,10" Grid.ColumnSpan="2" />
<DataGrid Grid.Row="1" x:Name="DataGrid" AutoGenerateColumns="False" CellStyle="{StaticResource DataGrid_Font_Centering}" CommandManager.PreviewCanExecute="Grid_PreviewCanExecute">
<DataGrid.Columns>
<DataGridTextColumn Header="Context Menu" Binding="{Binding Menu}"/>
<DataGridTemplateColumn Header="Input">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Button MinHeight="20" Click="ButtonClick">
<TextBlock Text="{Binding Key}"></TextBlock>
</Button>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn Header="Command" Binding="{Binding Command}" MaxWidth="330" />
</DataGrid.Columns>
</DataGrid>
</Grid>
</Window>

View File

@@ -0,0 +1,119 @@
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Input;
namespace mpvInputEdit
{
public partial class MainWindow : Window
{
ICollectionView CollectionView;
public MainWindow()
{
InitializeComponent();
Title = (Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyProductAttribute), true)[0] as AssemblyProductAttribute).Product + " " + Assembly.GetExecutingAssembly().GetName().Version.ToString();
SearchControl.SearchTextBox.TextChanged += SearchTextBox_TextChanged;
DataGrid.SelectionMode = DataGridSelectionMode.Single;
CollectionViewSource collectionViewSource = new CollectionViewSource() { Source = App.InputItems };
CollectionView = collectionViewSource.View;
var yourCostumFilter = new Predicate<object>(item => Filter((InputItem)item));
CollectionView.Filter = yourCostumFilter;
DataGrid.ItemsSource = CollectionView;
}
private void SearchTextBox_TextChanged(object sender, TextChangedEventArgs e)
{
CollectionView.Refresh();
}
bool Filter(InputItem item)
{
string searchText = SearchControl.SearchTextBox.Text.ToLowerInvariant();
if (searchText == "")
return true;
if (item.Command.ToLower().Contains(searchText) ||
item.Menu.ToLower().Contains(searchText) ||
item.Key.ToLower().Contains(searchText))
{
return true;
}
return false;
}
private void ButtonClick(object sender, RoutedEventArgs e)
{
InputItem item = ((Button)e.Source).DataContext as InputItem;
if (item is null) return;
InputWindow w = new InputWindow();
w.Owner = this;
w.InputItem = item;
w.ShowDialog();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
Keyboard.Focus(SearchControl.SearchTextBox);
}
private void Grid_PreviewCanExecute(object sender, CanExecuteRoutedEventArgs e)
{
DataGrid grid = (DataGrid)sender;
if (e.Command == DataGrid.DeleteCommand)
{
if (MessageBox.Show($"Would you like to delete the selected item?\n\n{(grid.SelectedItem as InputItem).Menu}",
"Confirm Delete", MessageBoxButton.OKCancel) != MessageBoxResult.OK)
{
e.Handled = true;
}
}
}
private void Window_Closed(object sender, EventArgs e)
{
if (MessageBox.Show("Would you like to save changes?", "Confirm Save", MessageBoxButton.OKCancel) != MessageBoxResult.OK)
return;
var backupDir = Path.GetDirectoryName(App.InputConfPath) + "\\backup\\";
if (!Directory.Exists(backupDir))
Directory.CreateDirectory(backupDir);
File.Copy(App.InputConfPath, backupDir + "input conf " + DateTime.Now.ToString("yyyy-MM-dd HH-mm") + ".conf");
string text = "";
foreach (InputItem item in App.InputItems)
{
string line = " " + item.Key.PadRight(14);
if (item.Command.Trim() == "")
line += " ignore";
else
line += " " + item.Command.Trim();
if (item.Menu.Trim() != "")
line = line.PadRight(40) + " #menu: " + item.Menu;
text += line + "\r\n";
}
File.WriteAllText(App.InputConfPath, text);
foreach (Process process in Process.GetProcesses())
if (process.ProcessName == "mpvnet")
MessageBox.Show("Restart mpv.net in order to apply changed input bindings.", Title, MessageBoxButton.OK, MessageBoxImage.Information);
else if (process.ProcessName == "mpv")
MessageBox.Show("Restart mpv in order to apply changed input bindings.", Title, MessageBoxButton.OK, MessageBoxImage.Information);
}
}
}

View File

@@ -7,11 +7,11 @@ using System.Windows;
// General Information about an assembly is controlled through the following // General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information // set of attributes. Change these attribute values to modify the information
// associated with an assembly. // associated with an assembly.
[assembly: AssemblyTitle("mpv(.net) settings editor")] [assembly: AssemblyTitle("mpv(.net) input edit")]
[assembly: AssemblyDescription("")] [assembly: AssemblyDescription("mpv(.net) key bindings editor")]
[assembly: AssemblyConfiguration("")] [assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")] [assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("mpv(.net) settings editor")] [assembly: AssemblyProduct("mpv input edit")]
[assembly: AssemblyCopyright("Copyright © stax76")] [assembly: AssemblyCopyright("Copyright © stax76")]
[assembly: AssemblyTrademark("")] [assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")] [assembly: AssemblyCulture("")]

View File

@@ -0,0 +1,66 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace mpvInputEdit.Properties
{
/// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary>
// This class was auto-generated by the StronglyTypedResourceBuilder
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources
{
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources()
{
}
/// <summary>
/// Returns the cached ResourceManager instance used by this class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if ((resourceMan == null))
{
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("mpvInputEdit.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
}
}

View File

@@ -0,0 +1,117 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@@ -0,0 +1,28 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace mpvInputEdit.Properties
{
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
{
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
public static Settings Default {
get {
return defaultInstance;
}
}
}
}

View File

@@ -0,0 +1,7 @@
<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="uri:settings" CurrentProfile="(Default)">
<Profiles>
<Profile Name="(Default)" />
</Profiles>
<Settings />
</SettingsFile>

View File

@@ -0,0 +1,13 @@
<UserControl x:Class="Controls.SearchTextBoxUserControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Grid x:Name="SearchTextBoxUserControl1" Background="White">
<TextBlock x:Name="SearchTextBlock" Margin="5,2" Text="Search" Foreground="LightSteelBlue" VerticalAlignment="Center" />
<TextBox Name="SearchTextBox" Height="25" Padding="1,2,0,0" BorderThickness="2" Background="Transparent" TextChanged="SearchTextBox_TextChanged" />
<Button x:Name="SearchClearButton" Background="Transparent" HorizontalAlignment="Right" Margin="2,0,4,0" FontSize="5" Width="17" Height="17" Visibility="Hidden" Click="SearchClearButton_Click"></Button>
</Grid>
</UserControl>

View File

@@ -0,0 +1,32 @@
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
namespace Controls
{
public partial class SearchTextBoxUserControl : UserControl
{
public SearchTextBoxUserControl()
{
InitializeComponent();
}
public string Text { get => SearchTextBox.Text; set => SearchTextBox.Text = value; }
private void SearchClearButton_Click(object sender, RoutedEventArgs e)
{
SearchTextBox.Text = "";
Keyboard.Focus(SearchTextBox);
}
private void SearchTextBox_TextChanged(object sender, TextChangedEventArgs e)
{
SearchTextBlock.Text = SearchTextBox.Text == "" ? "Search" : "";
if (SearchTextBox.Text == "")
SearchClearButton.Visibility = Visibility.Hidden;
else
SearchClearButton.Visibility = Visibility.Visible;
}
}
}

30
mpvInputEdit/misc.cs Normal file
View File

@@ -0,0 +1,30 @@
using System.ComponentModel;
using System.Runtime.CompilerServices;
namespace mpvInputEdit
{
public class InputItem : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public string Menu { get; set; } = "";
public string Command { get; set; } = "";
private void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
private string _Key = "";
public string Key {
get {
return _Key;
}
set {
_Key = value;
NotifyPropertyChanged();
}
}
}
}

BIN
mpvInputEdit/mpv.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 264 KiB

View File

@@ -0,0 +1,121 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{635F8308-9F79-4BCC-B839-75FCEF8588AE}</ProjectGuid>
<OutputType>WinExe</OutputType>
<RootNamespace>mpvInputEdit</RootNamespace>
<AssemblyName>mpvInputEdit</AssemblyName>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<WarningLevel>4</WarningLevel>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<Deterministic>true</Deterministic>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>..\mpv.net\bin\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>..\mpv.net\bin\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup>
<ApplicationIcon>mpv.ico</ApplicationIcon>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xaml">
<RequiredTargetFramework>4.0</RequiredTargetFramework>
</Reference>
<Reference Include="WindowsBase" />
<Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" />
</ItemGroup>
<ItemGroup>
<ApplicationDefinition Include="App.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</ApplicationDefinition>
<Compile Include="SearchTextBoxUserControl.xaml.cs">
<DependentUpon>SearchTextBoxUserControl.xaml</DependentUpon>
</Compile>
<Page Include="InputWindow.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="MainWindow.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Compile Include="App.xaml.cs">
<DependentUpon>App.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Include="InputWindow.xaml.cs">
<DependentUpon>InputWindow.xaml</DependentUpon>
</Compile>
<Compile Include="MainWindow.xaml.cs">
<DependentUpon>MainWindow.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Page Include="SearchTextBoxUserControl.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
</ItemGroup>
<ItemGroup>
<Compile Include="misc.cs" />
<Compile Include="Properties\AssemblyInfo.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<Compile Include="Properties\Settings.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
</ItemGroup>
<ItemGroup>
<Resource Include="mpv.ico" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

View File

@@ -0,0 +1,25 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.28721.148
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "mpvInputEdit", "mpvInputEdit.csproj", "{635F8308-9F79-4BCC-B839-75FCEF8588AE}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{635F8308-9F79-4BCC-B839-75FCEF8588AE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{635F8308-9F79-4BCC-B839-75FCEF8588AE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{635F8308-9F79-4BCC-B839-75FCEF8588AE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{635F8308-9F79-4BCC-B839-75FCEF8588AE}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {492E8273-D465-496D-BA18-DC8CEC9EAD70}
EndGlobalSection
EndGlobal

View File

@@ -1,129 +0,0 @@
[[settings]]
name = "hwdec"
default = "no"
filter = "Video"
helpurl = "https://mpv.io/manual/master/#options-hwdec"
help = "hwdec=<mode> Specify the hardware video decoding API that should be used if possible. Whether hardware decoding is actually done depends on the video codec. If hardware decoding is not possible, mpv will fall back on software decoding."
options = [{ name = "no", text = "no (Default)", help = "always use software decoding (Default)" },
{ name = "auto", help = "enable best hw decoder (see below)" },
{ name = "yes", help = "exactly the same as auto" },
{ name = "auto-copy", help = "enable best hw decoder with copy-back (see below)" },
{ name = "dxva2", help = "requires --vo=gpu with --gpu-context=d3d11, --gpu-context=angle or --gpu-context=dxinterop (Windows only)" },
{ name = "dxva2-copy", help = "copies video back to system RAM (Windows only)" },
{ name = "d3d11va", help = "requires --vo=gpu with --gpu-context=d3d11 or --gpu-context=angle (Windows 8+ only)" },
{ name = "d3d11va-copy", help = "copies video back to system RAM (Windows 8+ only)" },
{ name = "cuda", help = "requires --vo=gpu (Any platform CUDA is available)" },
{ name = "cuda-copy", help = "copies video back to system RAM (Any platform CUDA is available)" },
{ name = "nvdec", help = "requires --vo=gpu (Any platform CUDA is available)" },
{ name = "nvdec-copy", help = "copies video back to system RAM (Any platform CUDA is available)" },
{ name = "crystalhd", help = "copies video back to system RAM (Any platform supported by hardware)" },
{ name = "rkmpp", help = "requires --vo=gpu (some RockChip devices only)" }]
[[settings]]
name = "vo"
default = "gpu"
filter = "Video"
helpurl = "https://mpv.io/manual/master/#video-output-drivers-vo"
help = "gpu=<mode> Video output drivers to be used. Default = gpu."
options = [{ name = "gpu", text = "gpu (Default)", help = "General purpose, customizable, GPU-accelerated video output driver. It supports extended scaling methods, dithering, color management, custom shaders, HDR, and more. (Default)" },
{ name = "direct3d", help = "Video output driver that uses the Direct3D interface" }]
[[settings]]
name = "volume"
default = ""
filter = "Audio"
help = "volume=<integer> Set the startup volume. 0 means silence, 100 means no volume reduction or amplification. Negative values can be passed for compatibility, but are treated as 0. Since mpv 0.18.1, this always controls the internal mixer (aka \"softvol\")."
[[settings]]
name = "slang"
default = ""
filter = "Subtitles"
help = "--slang=<languagecode[,languagecode,...]> Specify a priority list of subtitle languages to use. Different container formats employ different language codes. DVDs use ISO 639-1 two letter language codes, Matroska uses ISO 639-2 three letter language codes while OGM uses a free-form identifier. See also --sid."
[[settings]]
name = "screen"
default = ""
filter = "Screen"
help = "screen=<default|0-32> In multi-monitor configurations (i.e. a single desktop that spans across multiple displays), this option tells mpv which screen to display the video on. Default: default."
[[settings]]
name = "osd-playing-msg"
default = ""
width = 300
filter = "Screen"
helpurl = "https://mpv.io/manual/master/#property-expansion"
help = "osd-playing-msg=<value> Show a message on OSD when playback starts. The string is expanded for properties, e.g. --osd-playing-msg='file: ${filename}' will show the message file: followed by a space and the currently played filename."
[[settings]]
name = "fullscreen"
alias = "fs"
default = "no"
filter = "Screen"
help = "fullscreen=<yes|no>, fs=<yes|no> Start the player in fullscreen mode. Default: no."
options = [{ name = "yes" }, { name = "no", text = "no (Default)" }]
[[settings]]
name = "keep-open-pause"
default = "yes"
filter = "Playback"
help = "keep-open-pause=<yes|no> If set to no, instead of pausing when --keep-open is active, just stop at end of file and continue playing forward when you seek backwards until end where it stops again. Default: yes."
options = [{ name = "yes", text = "yes (Default)" }, { name = "no" }]
[[settings]]
name = "keep-open"
default = "no"
filter = "Playback"
help = "keep-open=<yes|no|always> 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."
options = [{ name = "yes", help = "Don't terminate if the current file is the last playlist entry. Equivalent to --keep-open without arguments."},
{ name = "no", text = "no (Default)", help = "If the current file ends, go to the next file or terminate. (Default.)" },
{ 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."}]
[[settings]]
name = "loop-file"
alias = "loop"
default = ""
filter = "Playback"
help = "loop-file=<N|inf|no>, loop=<N|inf|no> Loop a single file N times. inf means forever, no means normal playback. For compatibility, --loop-file and --loop-file=yes are also accepted, and are the same as --loop-file=inf.\n\nThe difference to --loop-playlist is that this doesn't loop the playlist, just the file itself. If the playlist contains only a single file, the difference between the two option is that this option performs a seek on loop, instead of reloading the file.\n\n--loop is an alias for this option."
[[settings]]
name = "save-position-on-quit"
default = "no"
filter = "Playback"
help = "Always save the current playback position on quit. When this file is played again later, the player will seek to the old playback position on start. This does not happen if playback of a file is stopped in any other way than quitting. For example, going to the next file in the playlist will not save the position, and start playback at beginning the next time the file is played.\n\nThis behavior is disabled by default, but is always available when quitting the player with Shift+Q."
options = [{ name = "yes" }, { name = "no", text = "no (Default)" }]
[[settings]]
name = "screenshot-directory"
default = ""
width = 500
folder = true
filter = "Screen"
help = "screenshot-directory=<value> Store screenshots in this directory. This path is joined with the filename generated by --screenshot-template. If the template filename is already absolute, the directory is ignored.\n\nIf the directory does not exist, it is created on the first screenshot. If it is not a directory, an error is generated when trying to write a screenshot.\n\nThis option is not set by default, and thus will write screenshots to the directory from which mpv was started. In pseudo-gui mode (see PSEUDO GUI MODE), this is set to the desktop."
[[settings]]
name = "input-ar-delay"
default = ""
filter = "Input"
help = "input-ar-delay=<integer> Delay in milliseconds before we start to autorepeat a key (0 to disable)."
[[settings]]
name = "input-ar-rate"
default = ""
filter = "Input"
help = "input-ar-rate=<integer> Number of key presses to generate per second on autorepeat."
[[settings]]
name = "alang"
default = ""
filter = "Audio"
help = "alang=<languagecode[,languagecode,...]> Specify a priority list of audio languages to use. Different container formats employ different language codes. DVDs use ISO 639-1 two-letter language codes, Matroska, MPEG-TS and NUT use ISO 639-2 three-letter language codes, while OGM uses a free-form identifier. See also --aid.\n\nExamples\n\nmpv dvd://1 --alang=hu,en chooses the Hungarian language track on a DVD and falls back on English if Hungarian is not available.\n\nmpv --alang=jpn example.mkv plays a Matroska file with Japanese audio."
[[settings]]
name = "hr-seek"
default = "absolute"
filter = "Playback"
help = "hr-seek=<no|absolute|yes> Select when to use precise seeks that are not limited to keyframes. Such seeks require decoding video from the previous keyframe up to the target position and so can take some time depending on decoding performance. For some video formats, precise seeks are disabled. This option selects the default choice to use for seeks; it is possible to explicitly override that default in the definition of key bindings and in input commands."
options = [{ name = "yes", help = "Use precise seeks whenever possible." },
{ name = "no", help = "Never use precise seeks." },
{ name = "absolute", text = "absolute (Default)", help = "Use precise seeks if the seek is to an absolute position in the file, such as a chapter seek, but not for relative seeks like the default behavior of arrow keys (default)." },
{ name = "always", help = "Same as yes (for compatibility)." }]

View File

@@ -1,24 +0,0 @@
using System;
using System.Diagnostics;
using System.Windows.Documents;
using System.Windows.Navigation;
namespace DynamicGUI
{
public class HyperlinkEx : Hyperlink
{
private void HyperLinkEx_RequestNavigate(object sender, RequestNavigateEventArgs e)
{
Process.Start(e.Uri.AbsoluteUri);
}
public void SetURL(string url)
{
if (string.IsNullOrEmpty(url)) return;
NavigateUri = new Uri(url);
RequestNavigate += HyperLinkEx_RequestNavigate;
Inlines.Clear();
Inlines.Add(url);
}
}
}

View File

@@ -1,8 +0,0 @@
namespace DynamicGUI
{
interface ISettingControl
{
bool Contains(string searchString);
SettingBase SettingBase { get; }
}
}

View File

@@ -1,11 +1,9 @@
$scriptDir = Split-Path -Path $PSCommandPath -Parent $scriptDir = Split-Path -Path $PSCommandPath -Parent
$exePath = $scriptDir + "\mpv.net\bin\Debug\mpvnet.exe" $exePath = $scriptDir + "\mpv.net\bin\mpvnet.exe"
$version = [Diagnostics.FileVersionInfo]::GetVersionInfo($exePath).FileVersion $version = [Diagnostics.FileVersionInfo]::GetVersionInfo($exePath).FileVersion
$desktopDir = [Environment]::GetFolderPath("Desktop") $desktopDir = [Environment]::GetFolderPath("Desktop")
$targetDir = $desktopDir + "\mpv.net-" + $version $targetDir = $desktopDir + "\mpv.net-" + $version
Copy-Item C:\Users\frank\Daten\Projekte\CS\mpv.net\mpvSettingsEditor\bin\mpvSettingsEditor.exe "C:\Users\frank\Daten\Projekte\CS\mpv.net\mpv.net\bin\Debug\mpvSettingsEditor.exe" -Force Copy-Item $scriptDir\mpv.net\bin $targetDir -Recurse -Exclude System.Management.Automation.xml -Force
Copy-Item C:\Users\frank\Daten\Projekte\CS\mpv.net\mpvSettingsEditor\bin\Definitions.toml "C:\Users\frank\Daten\Projekte\CS\mpv.net\mpv.net\bin\Debug\Definitions.toml" -Force
Copy-Item $scriptDir\mpv.net\bin\Debug $targetDir -Recurse -Exclude System.Management.Automation.xml -Force
Copy-Item $scriptDir\README.md $targetDir\README.md -Force Copy-Item $scriptDir\README.md $targetDir\README.md -Force
$7zPath = "C:\Program Files\7-Zip\7z.exe" $7zPath = "C:\Program Files\7-Zip\7z.exe"
$args = "a -t7z -mx9 $targetDir.7z -r $targetDir\*" $args = "a -t7z -mx9 $targetDir.7z -r $targetDir\*"

Binary file not shown.

After

Width:  |  Height:  |  Size: 194 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 150 KiB

View File

Before

Width:  |  Height:  |  Size: 130 KiB

After

Width:  |  Height:  |  Size: 130 KiB

16
scripts/fullscreen.cs Normal file
View File

@@ -0,0 +1,16 @@
using mpvnet;
class Script
{
public Script()
{
var fs = mp.get_property_string("fullscreen");
mp.commandv("show-text", "fullscreen: " + fs);
mp.observe_property_bool("fullscreen", FullscreenChange);
}
void FullscreenChange(bool val)
{
mp.commandv("show-text", "fullscreen: " + val.ToString());
}
}

View File

@@ -0,0 +1,31 @@
// when seeking displays position and
// duration like so: 70:00 / 80:00
// which is different from mpv which
// uses 01:10:00 / 01:20:00
function add_zero(val)
{
val = Math.round(val);
return val > 9 ? "" + val : "0" + val;
}
function format(val)
{
var sec = Math.round(val);
if (sec < 0)
sec = 0;
pos_min_floor = Math.floor(sec / 60);
sec_rest = sec - pos_min_floor * 60;
return add_zero(pos_min_floor) + ":" + add_zero(sec_rest);
}
function on_seek(_)
{
mp.commandv("show-text",
format(mp.get_property_number("time-pos")) + " / " +
format(mp.get_property_number("duration")));
}
mp.register_event("seek", on_seek);

2
scripts/seek.ps1 Normal file
View File

@@ -0,0 +1,2 @@
$position = [mp]::get_property_number("time-pos");
[mp]::commandv("show-text", $position.ToString() + " seconds")

67
wiki/scripting.md Normal file
View File

@@ -0,0 +1,67 @@
Here is a list of scripts that users of mpv(.net) have published, adding functionality that is not part of the core mpv(.net) player. Anyone can add their own script by editing this wiki. Scripts are usually placed in C:\Users\user\AppData\Roaming\mpv\scripts
### C#
```
using mpvnet;
class Script
{
public Script()
{
var fs = mp.get_property_string("fullscreen");
mp.commandv("show-text", "fullscreen: " + fs);
mp.observe_property_bool("fullscreen", FullscreenChange);
}
void FullscreenChange(bool val)
{
mp.commandv("show-text", "fullscreen: " + val.ToString());
}
}
```
### Python
```
# when seeking displays position and
# duration like so: 70:00 / 80:00
# which is different from mpv which
# uses 01:10:00 / 01:20:00
import math
def seek():
pos = mp.get_property_number("time-pos")
dur = mp.get_property_number("duration")
if pos > dur:
pos = dur
mp.commandv('show-text', format(pos) + " / " + format(dur))
def format(f):
sec = round(f)
if sec < 0:
sec = 0
pos_min_floor = math.floor(sec / 60)
sec_rest = sec - pos_min_floor * 60
return add_zero(pos_min_floor) + ":" + add_zero(sec_rest)
def add_zero(val):
val = round(val)
return "" + str(int(val)) if (val > 9) else "0" + str(int(val))
mp.register_event("seek", seek) # or use: mp.Seek += seek
```
### PowerShell
```
$position = [mp]::get_property_number("time-pos");
[mp]::commandv("show-text", $position.ToString() + " seconds")
```
Please note that PowerShell don't allow assigning to events and mpv.net uses as workaround a matching script filename, a list of available events can be found in the mpv manual or in the file mp.cs in the mpv.net source code.