Compare commits

...

35 Commits

Author SHA1 Message Date
stax76
a0d5a6f234 libmpv update 2022-05-08 15:08:32 +02:00
stax76
d9afd172f9 5.9.0.0 Beta 2022-05-08 15:01:45 +02:00
stax76
3b9368230c fix #414 2022-05-05 12:31:13 +02:00
stax76
7d510a8ba7 update about 2022-05-04 15:25:51 +02:00
stax76
e7f08bf0a7 about update 2022-05-04 13:12:33 +02:00
stax76
ad3235bb96 update project description 2022-05-04 12:33:47 +02:00
stax76
b5b18f2a1a try to fix #413 2022-05-04 12:06:20 +02:00
stax76
28f9df1cee New mpv.net specific option keep-open-exit added 2022-05-03 15:18:42 +02:00
stax76
cd2f2aeec8 Fix config editor handling keep-open incorrectly 2022-05-03 14:25:15 +02:00
stax76
a15d2cdbbe playlist-add command added 2022-05-01 01:01:51 +02:00
stax76
f489d59168 Fix multi monitor setup with different DPI values 2022-04-28 21:53:50 +02:00
stax76
309ddbf08e Fix #398 keyboard layout change not working 2022-04-08 19:16:18 +02:00
stax76
1bc6fb9509 Merge pull request #400 from hooke007/dev
update manual_chs for v5.8.0.0
2022-04-05 19:55:19 +02:00
hooke007
88e5628d7b update manual_chs for v5.8.0.0 2022-04-03 21:29:07 +01:00
stax76
27dc98af21 v5.8.0.0 2022-04-02 15:14:36 +02:00
stax76
ce12eb61fd Info command shows the length 2022-04-02 11:40:40 +02:00
stax76
8ed62df8e2 workaround not reproducible logo drawing crash 2022-04-02 11:15:04 +02:00
stax76
f4b4be5466 add show-menu to changelog and manual 2022-03-31 16:41:23 +02:00
stax76
9a33bea7e7 context menu issue fix #396 2022-03-31 16:22:54 +02:00
stax76
3f469897b0 Fix crash on Windows 7 systems without PowerShell. 2022-03-24 18:32:32 +01:00
stax76
1aa380f768 manual 2022-03-13 14:15:24 +01:00
stax76
b0c3988a9d improved manual 2022-03-13 14:00:26 +01:00
stax76
8c02bb59ee Media Info is shown using command palette 2022-03-12 21:27:07 +01:00
stax76
d60bf050cf show commands with text editor 2022-03-12 14:26:00 +01:00
stax76
a0f2e8bd92 Merge pull request #386 from hooke007/doc
update Manual_chs for v5.7.0.0
2022-03-11 22:05:51 +01:00
stax76
63db623d07 2 fixes 2022-03-11 22:02:54 +01:00
hooke007
ab0b2c4da2 update Manual_chs for v5.7.0.0 2022-03-12 03:35:18 +08:00
stax76
091e159d10 fix MS Store page displaying non existing ARM and x86 support 2022-03-11 15:31:11 +01:00
stax76
91fa89b058 Fix showing incorrect timestamps in About dialog of Store version 2022-03-10 18:27:33 +01:00
stax76
36d3543852 5.7.0.0 Stable 2022-03-09 12:48:52 +01:00
stax76
72ed687390 minor things 2022-03-05 22:06:20 +01:00
stax76
c56855bbc7 5.6.2.0 Beta 2022-03-05 21:05:50 +01:00
stax76
9377804b06 fixing reintroduced osc issue, sorry 2022-03-05 15:39:56 +01:00
stax76
c50ac7a53b manual update again 2022-03-05 15:23:23 +01:00
stax76
677e7b5a59 manual update 2022-03-05 15:21:33 +01:00
28 changed files with 970 additions and 647 deletions

View File

@@ -6,8 +6,19 @@
🎞 mpv.net
==========
mpv.net is a modern media player for Windows based on the popular [mpv](https://mpv.io) player.
mpv.net is a modern desktop media player for Windows based on the popular [mpv](https://mpv.io) player.
mpv.net is designed to be mpv compatible, almost all mpv features are available
because they are all contained in libmpv, this means the official
[mpv manual](https://mpv.io/manual/master/) applies to mpv.net.
mpv focuses on the usage of the command line and the terminal,
mpv.net retains the ability to be used from the command line and
the terminal and adds a modern Windows GUI on top of it.
Like mpv, mpv.net is designed for power users, for regular users there is a
[mpv.net-next](https://github.com/mpv-net-player/mpv.net-next)
project under construction.
#### Graphical User Interface

View File

@@ -1,10 +1,62 @@
5.9.0.0 Beta (2022-05-08)
- Fix startup without media file not working with gpu-api=vulkan.
- Fix keyboard layout change not working.
- Fix multi monitor setup with different DPI values not working.
- Fix config editor handling `keep-open` and `keep-open-pause` incorrectly.
- New mpv.net specific option `keep-open-exit` added. If set to yes and
keep-open is set to no, mpv.net exits after the last file ends.
- New `playlist-add` command added to change the playlist position,
jumps to the other end when the beginning or end is reached.
Ctrl+F11 goes 10 positions backward.
Ctrl+F12 goes 10 positions forward.
- libmpv zhongfly 2022-05-07
5.8.0.0 Beta (2022-04-02)
- Fix crash on Windows 7 systems without PowerShell.
- Fix showing incorrect timestamps in About dialog of Store version.
- Fix Store page showing non-existent ARM and x86 support.
- Fix opening zip files.
- The list of available input commands is like before shown
by the text editor, so it's like everything else searchable.
- Media Info isn't shown directly, instead the command palette
shows several choices. The command palette can be bypassed
using the arguments: msgbox, editor, full, raw.
https://github.com/stax76/mpv.net/blob/master/docs/Manual.md#show-media-info-flags
- mpv.net specific commands, the command palette, auto-play property
and various other things are documented in the manual.
- The action used for the right mouse button can be configured.
https://github.com/stax76/mpv.net/blob/master/docs/Manual.md#show-menu
- Workaround not reproducible logo drawing crash.
- Info command shows the length.
- New mpv.net specific option `show-logo` that allows to disable
the drawing of the blue mpv.net logo on top of the native OSC logo.
- MediaInfo 22.03
5.7.0.0 Stable (2022-03-09)
- Improved title and chapter menu for Blu-Rays.
- Fix of conf folder virtualization issue of MS Store version.
5.6.2.0 Beta (2022-03-05)
- Fix script-opts files being ignored, removed options are:
script-opts = osc-scalewindowed=1.5,osc-hidetimeout=2000,console-scale=1.5
- Update MediaInfo to version 21.9.0.0 and
write version and date in About dialog.
- Provide setup options in command palette to ensure backward
compatibility with previous input.conf definitions.
5.6.1.0 Beta (2022-03-05)
- Various conf editor improvements. (hooke007)
- Custom conf folder location feature removed.
- Inno Setup replaced with Microsoft Store setup.
- Fix script-opts files being ingnored.
- Fix script-opts files being ignored.
- Showing the recent list in the command palette,
the top item gets auto selected.
https://github.com/stax76/mpv.net/issues/328#issuecomment-1057296054
@@ -17,8 +69,8 @@
- The usability of the menu structure was improved.
- Audio and subtitle tracks and various other features
are now available in the command palette.
- Single character input in the command palette searches exclusivly
key bindings much like the search field of the input editor.
- Single character input in the command palette searches exclusively
key bindings, much like the search field of the input editor.
- Various default key bindings improved.
- New protocol registrations, so far supported are: ytdl, rtsp, srt, srtp
- libmpv zhongfly 2022-02-27

View File

@@ -13,8 +13,10 @@ Table of contents
* [Support](#support)
* [Settings](#settings)
* [Input and context menu](#input-and-context-menu)
* [Command Palette](#command-palette)
* [Command Line Interface](#command-line-interface)
* [Terminal](#terminal)
* [mpv.net specific commands](#mpvnet-specific-commands)
* [mpv.net specific options](#mpvnet-specific-options)
* [External Tools](#external-tools)
* [Scripting](#scripting)
@@ -40,35 +42,30 @@ mpv focuses on the usage of the command line and the terminal,
mpv.net retains the ability to be used from the command line and
the terminal and adds a modern Windows GUI on top of it.
Like mpv, mpv.net is designed for power users, for regular users there is a
[mpv.net-next](https://github.com/mpv-net-player/mpv.net-next)
project under construction.
Download
--------
[Changelog](Changelog.md)
1. [Stable via Microsoft Store](https://www.microsoft.com/store/productId/9N64SQZTB3LM)
### Stable
1. [Microsoft Store](https://www.microsoft.com/store/productId/9N64SQZTB3LM)
2. [Portable](../../../releases)
2. [Stable and beta via GitHub download](../../../releases)
3. `winget install mpv.net`
### Beta
[OneDrive](https://1drv.ms/u/s!ArwKS_ZUR01g1ldoLA90tX9DzKTj?e=xITXbC)
[DropBox](https://www.dropbox.com/sh/t54p9igdwvllbpl/AADKyWpaFnIhdyosxyP5d3_xa?dl=0)
[Changelog](Changelog.md)
Installation
------------
mpv.net requires the .NET Framework 4.8 and Windows 7 or higher and a modern graphics card.
For internet streaming youtube-dl or yt-dlp must be downloaded and installed manually.
For internet streaming from YouTube and similar sites, yt-dlp must be
copied into the mpv.net folder or the user environment variable PATH
must be edited to include the yt-dlp folder.
#### File Associations
@@ -91,7 +88,7 @@ the files are opened in mpv.net in random order, this works with maximum 15 file
Support
-------
Before making a support request, please try a newer [beta version](#beta) first.
Before making a support request, please try the newest version first.
Bugs and feature requests can be made on the github [issue tracker](../../../issues),
feel free to use for anything mpv.net related, usage questions are welcome.
@@ -116,9 +113,7 @@ Input and context menu
----------------------
The input (key/mouse) bindings and the context menu definitions are stored in the
input.conf file, if it's missing mpv.net generates it with the following defaults:
[input.conf defaults](../../../tree/master/src/Resources/input.conf.txt)
input.conf file, if it's missing mpv.net generates it with default values.
Please be aware that once input.conf exists, mpv.net cannot update it, this means
the menu becomes outdated when mpv.net is updated with new or changed default menu
@@ -136,7 +131,7 @@ The input test mode can be started via command line: --input-test
The input key list can be printed with --input-keylist or
shown from the context menu under: View > Advanced > Show Keys
mpv.net input.conf defaults:
mpv.net input.conf defaults:
https://github.com/stax76/mpv.net/blob/master/src/Resources/input.conf.txt
mpv input.conf defaults:
@@ -148,6 +143,37 @@ https://mpv.io/manual/master/#list-of-input-commands
mpv input options:
https://mpv.io/manual/master/#input
Command Palette
---------------
The command palette is designed to quickly find,
select and execute commands.
It can also be used to easily find shortcut keys.
The following functionality is presented with the Command Palette:
- Show media info in different ways.
- Show and select audio tracks.
- Show and select subtitle tracks.
- Show and select playlist files.
- Show and select recent files.
- Show available mpv properties.
- Show available decoders.
- Show available demuxers.
- Show available keys.
- Show available protocols.
| Key | Action |
| ------ | --------------------------- |
| F1 | Shows the command palette. |
| Escape | Hides the command palette. |
| Enter | Executes the selected item. |
| Up | Moves the selection up. |
| Down | Moves the selection down. |
Command Line Interface
----------------------
@@ -173,12 +199,12 @@ Supported are all mpv properties, they are documented here:
https://mpv.io/manual/master/#properties
mpv.net has a feature to list all properties:
mpv.net has a feature to list all available properties:
_Context Menu > View > Show Properties_
_Context Menu > View > Advanced > Show Properties_
Non property switches are generally not supported in mpv.net!
mpv has a few non property based switches which are generally not supported in mpv.net.
Terminal
@@ -187,12 +213,159 @@ Terminal
When mpv.net is started from a terminal it will output status,
error and debug messages to the terminal and accept input keys from the terminal.
In the context menu under _Tools > Setup_ a button can be found to add
mpv.net to the path environment variable.
A common task for the terminal is debugging scripts.
mpv.net specific commands
-------------------------
`script-message mpv.net <command> <arguments>`
mpv.net commands are used when mpv commands don't exist or lack a feature.
### cycle-audio
Switches to the next audio track and shows info about that track.
### load-audio
Shows a file browser dialog to open external audio files.
### load-sub
Shows a file browser dialog to open external subtitle files.
### open-conf-folder
Opens the config folder with Windows File Explorer.
### open-files [\<flags\>]
**no-folder**
For single files prevents loading the complete folder into the playlist.
**append**
Appends files to the playlist.
Opens a file browser dialog in order to select files to be opened.
The file browser dialog supports multiselect to load multiple files
at once. Pressing CTRL appends the files to the playlist.
### open-optical-media
Shows a folder browser dialog to open a DVD or BD folder.
ISO images don't have to be mounted, but instead can be
opened directly with the open-files command.
### open-clipboard
Opens a single URL or filepath from the clipboard,
or multiple files in the file clipboard format.
### play-pause
Cycles the pause property. In case the playlist is empty,
the most recent file from the recent files list is loaded.
### playlist-add \<integer\>
Changes the playlist position by adding the supplied integer value.
If the position goes out of range, it jumpes to the opposite end.
### playlist-first
Jumps to the first playlist entry, if the loaded file is
already the first entry, nothing happens.
### playlist-last
Jumps to the last playlist entry, if the loaded file is
already the last entry, nothing happens.
### reg-file-assoc \<audio|video|image\>
Registers the file associations.
### scale-window \<factor\>
Decreases or increases the Window size.
### shell-execute \<file|URL\>
Shell executes a single file or URL.
### show-about
Shows the about dialog.
### show-audio-devices
Shows available audio devices in a message box.
### show-audio-tracks
Shows available audio tracks in the command palette
and allows to load the selected audio track.
### show-command-palette
Shows the command palette.
### show-commands
Shows available mpv imput commands.
### show-conf-editor
Shows the conf editor.
### show-decoders
Shows available decoders.
### show-demuxers
Shows available demuxers.
### show-history
Shows the history file when existing.
### show-info
Shows a simple file info.
### show-input-editor
Shows the input editor.
### show-keys
Shows available keys (as shown with `--input-keylist`) in the command palette.
### show-media-info [\<flags\>]
**msgbox**
Shows media info in a messsge box.
**editor**
Shows media info in the text editor.
**full**
Shows fully detailed media info.
**raw**
Shows media info with raw property names.
### show-menu
Shows the context menu.
### show-playlist
Shows the playlist in the command palette
and allows to play the selected entry.
### show-profiles
Shows available profiles with a message box.
### show-progress
Shows a simple OSD progress message.
### show-properties
Shows available properties in the command palette and
allows to display the property value of the selected property.
### show-protocols
Shows available protocols in the command palette.
### show-recent
Shows recently played files and URLs in the
command palette and allows to select and play entries.
### show-subtitle-tracks
Shows available subtitles in the command palette
and allows to activate the selected subtitle.
### show-text \<text\> \<duration\> \<font-size\>
Shows a OSD message with given text, duration and font size.
### window-scale \<factor\>
Works similar as the [window-scale](https://mpv.io/manual/master/#command-interface-window-scale) mpv property.
mpv.net specific options
------------------------
@@ -244,21 +417,18 @@ Window size is remembered in the current session.
**always**
Window size is always remembered.
#### --start-threshold=\<milliseconds\>
Threshold in milliseconds to wait for libmpv returning the video
resolution before the window is shown, otherwise default dimensions
are used as defined by autofit and start-size. Default: 1500
#### --minimum-aspect-ratio=\<float\>
Minimum aspect ratio, if the AR is smaller than the defined value then
the window AR is set to 16/9. This avoids a square window for Music
with cover art. Default: 1.2
#### --remember-window-position=\<yes|no\>
Save the window position on exit. Default: no
@@ -271,6 +441,15 @@ Save the window position on exit. Default: no
For single files automatically load the entire directory into the playlist.
Can be suppressed via shift key. Default: yes
#### --auto-play=\<yes|no\>
If the player is paused and another file is loaded,
playback automatically resumes.
#### --keep-open-exit
If set to yes and keep-open is set to no, mpv.net exits after the last file ends.
In mpv the idle property would be used, it's not possible for mpv.net to use the idle property.
### General
@@ -278,7 +457,7 @@ Can be suppressed via shift key. Default: yes
Defines if more then one mpv.net process is allowed.
Tip: Whenever the control key is pressed when files or URLs are opened,
Tip: Whenever the CTRL key is pressed when files or URLs are opened,
the playlist is not cleared but the files or URLs are appended to the playlist.
This not only works on process startup but in all mpv.net features that open files and URLs.
@@ -291,27 +470,22 @@ Force a single process everytime the shell starts mpv.net. Default
**queue**
Force a single process and add files to playlist.
#### --recent-count=\<int\>
Amount of recent files to be remembered. Default: 15
#### --video-file-extensions=\<string\>
Video file extensions used to create file associations and used by the auto-load-folder feature.
#### --audio-file-extensions=\<string\>
Audio file extensions used to create file associations and used by the auto-load-folder feature.
#### --image-file-extensions=\<string\>
Image file extensions used to create file associations and used by the auto-load-folder feature.
#### --debug-mode=\<yes|no\>
Enable this only when a developer asks for it. Default: no
@@ -331,20 +505,23 @@ Available on Windows 10 or higher.
**never**
#### ---dark-theme=\<string\>
#### --dark-theme=\<string\>
Color theme used in dark mode. Default: dark
[Color Themes](#color-theme)
#### --light-theme=\<string\>
Color theme used in light mode. Default: light
[Color Themes](#color-theme)
#### --show-logo=\<yes|no\>
Draws the blue mpv.net logo ontop of the native OSC logo.
Changes take effect after application restart. Default: yes
External Tools
--------------
@@ -395,6 +572,16 @@ My primary remote control solution however is a One For All Contour URC1210
using Philips code 0556 together with FLIRC USB (gen2).
### External Application Button
Videos can be streamed or downloaded easily with the Chrome extension
External Application Button, for download (recommended):
path: `wt`
args: `-- pwsh -NoLogo -Command "yt-dlp --ignore-errors --download-archive 'C:\External Application Button.txt' --output 'C:\YouTube\%(channel)s - %(title)s.%(ext)s' ('[HREF]' -replace '&list=.+','')"`
Scripting
---------
@@ -406,14 +593,17 @@ Location: `<config folder>\scripts`
The Lua script host is built into libmpv.
There is no debugging support, only error and debug messages printed on the terminal.
Error and debug messages are printed on the terminal.
Lua scripts are loaded before the first media file loads.
[mpv Lua documentation](https://mpv.io/manual/master/#lua-scripting)
[mpv user scripts](https://github.com/mpv-player/mpv/wiki/User-Scripts)
[mpv user scripts in the wiki](https://github.com/mpv-player/mpv/wiki/User-Scripts)
[mpv user scripts on GitHub](https://github.com/topics/mpv-script)
[mpv user scripts found by Google](https://www.google.com/search?q=mpv+script)
#### JavaScript
@@ -423,7 +613,7 @@ Location: `<config folder>\scripts`
The JavaScript script host is built into libmpv.
There is no debugging support, only error and debug messages printed on the terminal.
Error and debug messages are printed on the terminal.
JavaScript scripts are loaded before the first media file loads.
@@ -460,6 +650,8 @@ Script code can be written within a C# [extension](../../../tree/master/src/Exte
that way full code completion and debugger support is available.
Once the code was developed and debugged, it can be moved
from the extension to a lightweight standalone script.
The script host uses an old C# version, modern features
like string interpolation are not available.
The C# scripting host is like [extensions](../../../tree/master/src/Extensions)
not initialized before media files are loaded.

View File

@@ -2,7 +2,7 @@
mpv.net手册
==============
同步源提交_[20211114](https://github.com/stax76/mpv.net/commit/243b45326ef8defa038edacd01fafee13f6a009a#diff-bf7b5e59783955f479505de4969f792255eca0a69945ccfe3ec5dda409495bbe)
同步源提交_[20220402](https://github.com/stax76/mpv.net/commit/27dc98af2195622d3443cc048b3c856c5238b9f5)
**[ENGLISH](Manual.md)** | **简体中文**
@@ -14,9 +14,11 @@ mpv.net手册
* [安装](#安装)
* [支持](#支持)
* [设置](#设置)
* [快捷键输入绑定](#快捷键输入绑定)
* [快捷键和上下文菜单](#快捷键和上下文菜单)
* [命令面板](#命令面板)
* [命令行界面](#命令行界面)
* [终端](#终端)
* [mpv.net的专属命令](#mpvnet的专属命令)
* [mpv.net的专属选项](#mpvnet的专属选项)
* [外部工具](#外部工具)
* [脚本](#脚本)
@@ -43,67 +45,51 @@ mpv专注命令行与终端的使用而mpv.net保留了这些并加入了现
下载
--------
1. [Microsoft Store 的稳定版](https://www.microsoft.com/store/productId/9N64SQZTB3LM)
2. [Github 的稳定与测试版](../../../releases)
3. `winget install mpv.net`
[更新日志](Changelog.md)
### 稳定版
[发布页面](../../../releases)
### 测试版
[OneDrive](https://1drv.ms/u/s!ArwKS_ZUR01g1ldoLA90tX9DzKTj?e=xITXbC)
[DropBox](https://www.dropbox.com/sh/t54p9igdwvllbpl/AADKyWpaFnIhdyosxyP5d3_xa?dl=0)
安装
------------
mpv.net需要.NET Framework 4.8运行库和高于win7版本的系统以及一张不太旧的显卡。
安装版和便携版可供下载。
安装新版本之前应完全卸载旧版本,使用旧版本覆盖安装新版本通常不是推荐的做法,
安装工具不强制执行这项操作,因为它难以实现。
对于网络串流必须手动下载安装youtube-dl它必须位于环境变量 PATH 或启动目录中。
mpv.net不限制系统平台win32的用户必须替换目录中的3个工具
- mpv-1.dll
- MediaInfo.dll
- mpvnet.com
对于来自YouTube和类似网站的网络流必须将yt-dlp复制到mpv.net的文件夹中
或编辑用户环境变量PATH使其包括yt-dlp的文件夹。
#### 文件关联
可以使用上下文菜单创建文件关联。 'Tools > Setup'
可以使用上下文菜单注册文件关联。 'Settings > Setup'
注册完文件关联后,进入 "Windows设置 > 应用 > 默认应用"或者从powershell
执行 `ms-settings:defaultapps` 然后选择mpv. net作为视频/音频/图像的默认程序。
注册完文件关联后,进入 "Windows设置 > 应用 > 默认应用" (Win+I, ms-settings:defaultapps)
然后选择mpv. net作为视频/音频/图像的默认程序。
可以使用资源管理器的上下文菜单的'Open with'功能更改默认应用程序。
另一种注册文件关联的方式是使用文件资源管理器,选中媒体文件后,
选择上下文菜单的 '打开方式 > 选择其它应用' 。
[Open with++](#open-with) 可用来扩展资源管理器的上下文菜单
[Play with mpv.net](https://github.com/stax76/OpenWithPlusPlus#play-with-mpvnet) 和
[Add to mpv.net playlist](https://github.com/stax76/OpenWithPlusPlus#add-to-mpvnet-playlist).
可用来获取 'Play with mpv.net' 和 'Add to mpv.net playlist' 的菜单子项
当在资源管理器中选择多个文件并按 enter 键时文件会在mpv.net随机排序打开最多限制15个文件。
当在资源管理器中选择多个文件并按 enter 键时文件会在mpv.net随机排序打开
最多限制15个文件。
支持
-------
在提出支持请求之前,先尝试最新的[测试版](#测试版)
在提出支持请求之前,先尝试最新的测试版。
程序错误和功能请求可以在github的[问题追踪](../../../issues)上提出,
程序错误和功能请求可以在github的 [问题追踪](../../../issues) 上提出,
任何与mpv. net相关的东西都可以使用欢迎提交使用上出现的问题。
或者浏览VideoHelp论坛的讨论帖。
[support thread](https://forum.videohelp.com/threads/392514-mpv-net-a-extendable-media-player-for-windows)
或者浏览VideoHelp论坛的 [讨论帖](https://forum.videohelp.com/threads/392514-mpv-net-a-extendable-media-player-for-windows)
设置
@@ -119,17 +105,67 @@ mpv.net的专属选项保存在 mpvnet.conf 文件中,
参数解释请参阅 [此处](#mpvnet的专属选项)
快捷键输入绑定
快捷键和上下文菜单
----------------------
键鼠的快捷键和上下文菜单的操作保存在 input.conf 文件中,
如果设置目录中不存在,将使用以下文件生成默认的初始设置:
如果设置目录中不存在,mpv.net会用默认值生成它。
[input.conf defaults](../../../tree/master/src/Resources/input.conf.txt)
请注意,一旦 input.conf 存在, mpv.net 就不能更新它,这意味着当 mpv.net 升级了
新的版本或改变了的默认菜单项时,菜单条目就会过时。获得最新菜单的唯一方法是
通过删除 input.conf 来重置菜单,或者通过手动编辑 input.conf 来更新它。
通过 global-input.conf 文件支持全局热键。
置文件夹可以从上下文菜单中打开: `Settings > Open Config Folder`
置文件夹可以从上下文菜单中打开: `Settings > Open Config Folder`
input 和 config editor 可以在上下文菜单的该条目中找到 'Settings'
输入测试模式可以通过命令行启动: --input-test
输入的键位列表可由该参数输出 --input-keylist
或从上下文菜单的该条目获取 `View > Advanced > Show Keys`
mpv.net的默认input.conf文件
https://github.com/stax76/mpv.net/blob/master/src/Resources/input.conf.txt
mpv的默认input.conf文件
https://github.com/mpv-player/mpv/blob/master/etc/input.conf
mpv的命令
https://mpv.io/manual/master/#list-of-input-commands
mpv的input选项
https://mpv.io/manual/master/#input
命令面板
---------------
命令面板能用来快速查找、选择和执行命令。
它也可以用来方便的找到快捷键。
命令面板提供了以下功能:
- 以不同方式显示 mediainfo
- 显示和选择音轨
- 显示和选择字幕轨
- 显示和选择播放列表的文件
- 显示和选择最近的文件
- 显示可用的mpv属性
- 显示可用的解码器
- 显示可用的解复用器
- 显示可用的按键
- 显示可用的协议
| 按键 | 动作 |
| ----- | -------------- |
| F1 | 显示命令面板 |
| Esc | 隐藏命令面板 |
| Enter | 执行所选的条目 |
| Up | 光标向上移动 |
| Down | 光标向下移动 |
命令行界面
@@ -157,12 +193,12 @@ mpv的参数与mpv.net共通例如
https://mpv.io/manual/master/#properties
mpv.net可以使用以下功能列出所有属性
mpv.net可以使用以下功能列出所有可用的属性:
'Context Menu > View > Show Properties'
_Context Menu > View > Advanced > Show Properties_
mpv.net通常不支持非属性的运行时状态切换
mpv有一些基于非属性的开关在mpv.net中一般不受支持。
终端
@@ -170,11 +206,143 @@ mpv.net通常不支持非属性的运行时状态切换
当mpv. net从终端启动时它将输出状态、错误和调试消息并接受终端的输入。
在菜单中的 'Tools > Setup' 可以将mpv.net添加到环境变量PATH。
终端的常见用处是脚本调试。
mpv.net的专属命令
-------------------------
`script-message mpv.net <command> <arguments>`
mpv.net命令可在mpv命令不存在或缺乏某种功能时使用。
### cycle-audio
切换到下一个音轨并显示该音轨的信息。
### load-audio
显示一个资源管理器的对话框来加载外部音频文件。
### load-sub
显示一个资源管理器的对话框来加载外部字幕文件。
### open-conf-folder
用Windows资源管理器打开配置文件夹。
### open-files [\<flags\>]
**no-folder**
对于单个文件,防止将文件夹内的全部文件加载到播放列表中。
**append**
追加文件到播放列表中。
打开一个资源管理器的对话框,以便选择要打开的文件。资源管理器的对话框支持多选以
一次性加载多个文件。按住CTRL键可以将这些文件追加到播放列表中。
### open-optical-media
显示一个资源管理器的对话框来打开一个DVD或BD文件夹。ISO镜像不需要被挂载
但可以直接用 open-files 命令打开。
### open-clipboard
从剪贴板打开单个的URL或文件路径或以文件剪贴板中的格式打开多个文件。
### play-pause
循环切换 pause 的属性。如果播放列表为空,将加载最近文件列表中的最新文件。
### playlist-first
跳转到播放列表的第一个条目,如果加载的文件已经是第一个条目,则无动作。
### playlist-last
跳转到播放列表的最后一个条目,如果加载的文件已经是最后一个条目,则无动作。
### reg-file-assoc \<audio|video|image\>
注册文件关联。
### scale-window \<factor\>
减小或增大窗口的尺寸。
### shell-execute \<file|URL\>
Shell执行单个文件或URL。
### show-about
显示 "关于" 的对话框。
### show-audio-devices
在一个信息框中显示可用的音频设备。
### show-audio-tracks
在命令面板中显示可用的音轨,并允许加载选中的音轨。
### show-command-palette
显示命令面板。
### show-commands
显示可用的mpv输入命令。
### show-conf-editor
显示配置编辑器。
### show-decoders
显示可用的解码器。
### show-demuxers
显示可用的解复用器。
### show-history
显示已有的历史文件。
### show-info
显示一个简易的文件信息。
### show-input-editor
显示器快捷键编辑器。
### show-keys
在命令面板中显示可用的按键。(与 `--input-keylist` 显示的内容一致)
### show-media-info [\<flags\>]
**msgbox**
在一个信息框中显示mediainfo
**editor**
在一个文本编辑器中显示mediainfo
**full**
显示mediainfo的完整细节
**raw**
显示带有原始属性名的mediainfo
### show-menu
显示上下文菜单。
### show-playlist
在命令面板中显示播放列表,并允许播放选中的条目。
### show-profiles
用一个信息框显示可用的profile
### show-progress
显示一个简易的OSD进度条信息。
### show-properties
在命令面板中显示可用的属性,并允许显示所选属性的值。
### show-protocols
在命令面板中显示可用的协议。
### show-recent
在命令面板中显示最近播放的文件和URL并允许选择和播放条目。
### show-subtitle-tracks
在命令面板中显示可用的字幕轨,并允许激活选中的字幕。
### show-text \<text\> \<duration\> \<font-size\>
显示一个具有指定文本、持续时间和字体大小的OSD信息。
### window-scale \<factor\>
职能类似于mpv的属性 [window-scale](https://mpv.io/manual/master/#command-interface-window-scale)
mpv.net的专属选项
------------------------
@@ -251,6 +419,11 @@ mpv.net的专属选项
打开单个文件时,自动将整个目录加载到播放列表中。可以通过 shift 键临时禁用。默认yes
#### --auto-play=\<yes|no\>
如果在播放器暂停时,加载另一个文件,会自动恢复播放。
### General
#### --process-instance=\<value\>
@@ -311,7 +484,7 @@ mpv.net的专属选项
从不
#### ---dark-theme=\<string\>
#### --dark-theme=\<string\>
深色模式中使用的配色主题。默认dark
@@ -325,6 +498,11 @@ mpv.net的专属选项
[配色主题](#配色主题)
#### --show-logo=\<yes|no\>
在原始OSC标志的基础上绘制蓝色的mpvnet图标。更改将在应用程序重新启动后生效。默认yes
外部工具
--------------
@@ -381,6 +559,15 @@ Universal Remote 的 File Browser 功能十分有用。
Philips code 0556 和 FLIRC USB (gen2) 一同被使用。
### External Application Button
视频可以通过Chrome扩展程序的外部应用按钮进行流式传输或轻松下载对于下载推荐
path: `wt`
args: `-- pwsh -NoLogo -Command "yt-dlp --ignore-errors --download-archive 'C:\External Application Button.txt' --output 'C:\YouTube\%(channel)s - %(title)s.%(ext)s' ('[HREF]' -replace '&list=.+','')"`
脚本
---------
@@ -392,13 +579,17 @@ Philips code 0556 和 FLIRC USB (gen2) 一同被使用。
Lua脚本的host由libmpv内建。
没有调试支持,只有错误和调试消息输出在终端上。
错误和调试消息输出在终端上。
Lua脚本在第一个媒体文件打开之前加载。
[mpv Lua 文档](https://mpv.io/manual/master/#lua-scripting)
[mpv用户脚本](https://github.com/mpv-player/mpv/wiki/User-Scripts)
[mpv 用户脚本 wiki](https://github.com/mpv-player/mpv/wiki/User-Scripts)
[mpv 用户脚本 GitHub](https://github.com/topics/mpv-script)
[mpv 用户脚本 Google](https://www.google.com/search?q=mpv+script)
#### JavaScript
@@ -409,7 +600,7 @@ Lua脚本在第一个媒体文件打开之前加载。
JavaScriptLua脚本的host由libmpv内建。
没有调试支持,只有错误和调试消息输出在终端上。
错误和调试消息输出在终端上。
JavaScript脚本在第一个媒体文件打开之前加载。
@@ -441,6 +632,7 @@ mpv.net没有定义脚本接口而是公开了它的完整内部没有兼
脚本代码可以在C#[扩展](../../../tree/master/src/Extensions)中编写,这样就可以获得
完整的代码和调试器支持。一旦代码被调试和开发完成,就可以将其从扩展转移到轻量级的独立脚本。
脚本host使用的是旧的C#版本,像字符串插值这样的现代功能是不存在的。
C#脚本的host类似于[扩展](../../../tree/master/src/Extensions),在打开媒体文件前尚未初始化。
@@ -640,8 +832,6 @@ input.conf 定义mpv的快捷键同时mpv.net使用注释定义上下文菜
从剪贴板打开文件和URL。如何从YouTube等网站的浏览器中直接打开url在[外部工具](#外部工具)部分进行了描述。
对于网络流媒体必须手动下载并安装youtube-dl这意味着它必须位于环境变量PATH或启动目录中。
### Open > Open DVD/Blu-ray Drive/Folder

View File

@@ -13,22 +13,22 @@
<FileAlignment>512</FileAlignment>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|AnyCPU'">
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>AnyCPU</PlatformTarget>
<PlatformTarget>x64</PlatformTarget>
<LangVersion>7.3</LangVersion>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|AnyCPU'">
<OutputPath>bin\</OutputPath>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
<OutputPath>bin\x64\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>AnyCPU</PlatformTarget>
<PlatformTarget>x64</PlatformTarget>
<LangVersion>7.3</LangVersion>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>

View File

@@ -25,9 +25,11 @@ namespace mpvnet
public static bool AutoPlay { get; set; }
public static bool DebugMode { get; set; }
public static bool IsTerminalAttached { get; } = Environment.GetEnvironmentVariable("_started_from_console") == "yes";
public static bool KeepOpenExit { get; set; }
public static bool Queue { get; set; }
public static bool RememberVolume { get; set; } = true;
public static bool RememberWindowPosition { get; set; }
public static bool ShowLogo { get; set; } = true;
public static int StartThreshold { get; set; } = 1500;
public static int RecentCount { get; set; } = 15;
@@ -130,8 +132,21 @@ namespace mpvnet
}
public static string Version => "Copyright (C) 2000-2022 mpv.net/mpv/mplayer\n" +
$"mpv.net {Application.ProductVersion} ({File.GetLastWriteTime(Application.ExecutablePath).ToShortDateString()})\n" +
$"{Core.GetPropertyString("mpv-version")} ({File.GetLastWriteTime(Folder.Startup + "mpv-2.dll").ToShortDateString()})\nffmpeg {Core.GetPropertyString("ffmpeg-version")}\nGPL v2 License";
$"mpv.net {Application.ProductVersion}" + GetLastWriteTime(Application.ExecutablePath) + "\n" +
$"{Core.GetPropertyString("mpv-version")}" + GetLastWriteTime(Folder.Startup + "mpv-2.dll") + "\n" +
$"ffmpeg {Core.GetPropertyString("ffmpeg-version")}\n" +
$"MediaInfo {FileVersionInfo.GetVersionInfo(Path.Combine(Application.StartupPath, "MediaInfo.dll")).FileVersion}" +
GetLastWriteTime(Path.Combine(Application.StartupPath , "MediaInfo.dll")) + "\nGPL v2 License";
static string GetLastWriteTime(string path)
{
if (IsStoreVrsion)
return "";
return $" ({File.GetLastWriteTime(path).ToShortDateString()})";
}
static bool IsStoreVrsion => Application.StartupPath.Contains("FrankSkare.mpv.net");
public static void ShowException(object obj)
{
@@ -227,6 +242,7 @@ namespace mpvnet
case "dark-theme": DarkTheme = value.Trim('\'', '"'); return true;
case "debug-mode": DebugMode = value == "yes"; return true;
case "image-file-extensions": CorePlayer.ImageTypes = value.Split(" ,;".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); return true;
case "keep-open-exit": KeepOpenExit = value == "yes"; return true;
case "light-theme": LightTheme = value.Trim('\'', '"'); return true;
case "minimum-aspect-ratio": MinimumAspectRatio = value.ToFloat(); return true;
case "process-instance": ProcessInstance = value; return true;
@@ -234,6 +250,7 @@ namespace mpvnet
case "recent-count": RecentCount = value.ToInt(); return true;
case "remember-volume": RememberVolume = value == "yes"; return true;
case "remember-window-position": RememberWindowPosition = value == "yes"; return true;
case "show-logo": ShowLogo = value == "yes"; return true;
case "start-size": StartSize = value; return true;
case "start-threshold": StartThreshold = value.ToInt(); return true;
case "video-file-extensions": CorePlayer.VideoTypes = value.Split(" ,;".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); return true;

View File

@@ -26,14 +26,16 @@ namespace mpvnet
{
case "add-files-to-playlist": OpenFiles("append"); break; // deprecated 2019
case "cycle-audio": CycleAudio(); break;
case "execute-mpv-command": Msg.ShowError("Command was removed, reset input.conf."); break; // deprecated 2020
case "execute-mpv-command": Msg.ShowError("The command was removed, reset input.conf by deleting it, in the new menu use the on screen console."); break; // deprecated 2020
case "load-audio": LoadAudio(); break;
case "load-sub": LoadSubtitle(); break;
case "open-clipboard": OpenFromClipboard(); break;
case "open-conf-folder": ProcessHelp.ShellExecute(Core.ConfigFolder); break;
case "open-files": OpenFiles(args); break;
case "open-optical-media": Open_DVD_Or_BD_Folder(); break;
case "open-url": OpenURL(); break;
case "open-url": OpenFromClipboard(); break; // deprecated 2022
case "play-pause": PlayPause(); break;
case "playlist-add": PlaylistAdd(Convert.ToInt32(args[0])); break;
case "playlist-first": PlaylistFirst(); break;
case "playlist-last": PlaylistLast(); break;
case "reg-file-assoc": RegisterFileAssociations(args[0]); break;
@@ -52,29 +54,37 @@ namespace mpvnet
case "show-input-editor": ShowDialog(typeof(InputWindow)); break;
case "show-keys": ShowStrings(Core.GetPropertyString("input-key-list").Split(',')); break;
case "show-media-info": ShowMediaInfo(args); break;
case "show-menu": ShowMenu(); break;
case "show-playlist": ShowPlaylist(); break;
case "show-profiles": Msg.ShowInfo(mpvHelp.GetProfiles()); break;
case "show-progress": ShowProgress(); break;
case "show-properties": ShowProperties(); break;
case "show-protocols": ShowStrings(mpvHelp.GetProtocols().Split("\r\n".ToCharArray(), StringSplitOptions.RemoveEmptyEntries)); break;
case "show-recent": ShowRecent(); break;
case "show-setup-dialog": ShowSetupDialog(); break; // deprecated 2022
case "show-subtitle-tracks": ShowSubtitleTracks(); break;
case "show-text": ShowText(args[0], Convert.ToInt32(args[1]), Convert.ToInt32(args[2])); break;
case "window-scale": WindowScale(float.Parse(args[0], CultureInfo.InvariantCulture)); break;
default: Terminal.WriteError($"No command '{id}' found."); break;
default: Terminal.WriteError($"No command '{id}' found, reset input.conf by deleting it."); break;
}
}
public static void ShowDialog(Type winType)
public static void ShowTextWithEditor(string name, string text)
{
App.InvokeOnMainThread(new Action(() => {
Window win = Activator.CreateInstance(winType) as Window;
new WindowInteropHelper(win).Owner = MainForm.Instance.Handle;
win.ShowDialog();
}));
string file = Path.Combine(Path.GetTempPath(), name + ".txt");
App.TempFiles.Add(file);
File.WriteAllText(file, BR + text.Trim() + BR);
ProcessHelp.ShellExecute(file);
}
public static void ShowDialog(Type winType) => App.InvokeOnMainThread(() =>
{
Window win = Activator.CreateInstance(winType) as Window;
new WindowInteropHelper(win).Owner = MainForm.Instance.Handle;
win.ShowDialog();
});
public static void OpenFiles(params string[] args)
{
bool append = Control.ModifierKeys.HasFlag(Keys.Control);
@@ -96,15 +106,13 @@ namespace mpvnet
}));
}
public static void Open_DVD_Or_BD_Folder()
public static void Open_DVD_Or_BD_Folder() => App.InvokeOnMainThread(() =>
{
App.InvokeOnMainThread(new Action(() => {
var dialog = new FolderBrowser();
var dialog = new FolderBrowser();
if (dialog.Show())
Core.LoadDiskFolder(dialog.SelectedPath);
}));
}
if (dialog.Show())
Core.LoadDiskFolder(dialog.SelectedPath);
});
public static void PlaylistFirst()
{
@@ -166,9 +174,6 @@ namespace mpvnet
if (path.Contains("://"))
path = Core.GetPropertyString("media-title");
int width = Core.GetPropertyInt("video-params/w");
int height = Core.GetPropertyInt("video-params/h");
if (File.Exists(path))
{
fileSize = new FileInfo(path).Length;
@@ -216,12 +221,13 @@ namespace mpvnet
string videoFormat = Core.GetPropertyString("video-format").ToUpper();
string audioCodec = Core.GetPropertyString("audio-codec-name").ToUpper();
text = path.FileName() + $"\n{width} x {height}\n";
if (fileSize > 0)
text += Convert.ToInt32(fileSize / 1024.0 / 1024.0) + " MB\n";
int width = Core.GetPropertyInt("video-params/w");
int height = Core.GetPropertyInt("video-params/h");
TimeSpan len = TimeSpan.FromSeconds(Core.GetPropertyDouble("duration"));
text = path.FileName() + "\n";
text += FormatTime(len.TotalMinutes) + ":" + FormatTime(len.Seconds) + "\n";
if (fileSize > 0) text += Convert.ToInt32(fileSize / 1024.0 / 1024.0) + " MB\n";
text += $"{width} x {height}\n";
text += $"{videoFormat}\n{audioCodec}";
Core.CommandV("show-text", text, "5000");
@@ -232,6 +238,8 @@ namespace mpvnet
}
}
static string FormatTime(double value) => ((int)value).ToString("00");
public static void ShowProgress()
{
TimeSpan position = TimeSpan.FromSeconds(Core.GetPropertyDouble("time-pos"));
@@ -243,71 +251,63 @@ namespace mpvnet
FormatTime(duration.Seconds);
Core.CommandV("show-text", text, "5000");
string FormatTime(double value) => ((int)value).ToString("00");
}
public static void OpenURL()
public static void OpenFromClipboard() => App.InvokeOnMainThread(() =>
{
App.InvokeOnMainThread(new Action(() => {
if (WinForms.Clipboard.ContainsFileDropList())
if (WinForms.Clipboard.ContainsFileDropList())
{
string[] files = WinForms.Clipboard.GetFileDropList().Cast<string>().ToArray();
Core.LoadFiles(files, false, Control.ModifierKeys.HasFlag(Keys.Control));
}
else
{
string clipboard = WinForms.Clipboard.GetText();
if (string.IsNullOrEmpty(clipboard) || (!clipboard.Contains("://") && !File.Exists(clipboard)) ||
clipboard.Contains("\n"))
{
string[] files = WinForms.Clipboard.GetFileDropList().Cast<string>().ToArray();
Core.LoadFiles(files, false, Control.ModifierKeys.HasFlag(Keys.Control));
App.ShowError("The clipboard does not contain a valid URL or file.");
return;
}
else
{
string clipboard = WinForms.Clipboard.GetText();
if (string.IsNullOrEmpty(clipboard) || (!clipboard.Contains("://") && !File.Exists(clipboard)) ||
clipboard.Contains("\n"))
{
App.ShowError("No URL found, the clipboard does not contain a valid URL or file.");
return;
}
Core.LoadFiles(new [] { clipboard }, false, Control.ModifierKeys.HasFlag(Keys.Control));
}
});
Core.LoadFiles(new [] { clipboard }, false, Control.ModifierKeys.HasFlag(Keys.Control));
}
}));
}
public static void LoadSubtitle()
public static void LoadSubtitle() => App.InvokeOnMainThread(() =>
{
App.InvokeOnMainThread(new Action(() => {
using (var d = new OpenFileDialog())
{
string path = Core.GetPropertyString("path");
using (var d = new OpenFileDialog())
{
string path = Core.GetPropertyString("path");
if (File.Exists(path))
d.InitialDirectory = Path.GetDirectoryName(path);
if (File.Exists(path))
d.InitialDirectory = Path.GetDirectoryName(path);
d.Multiselect = true;
d.Multiselect = true;
if (d.ShowDialog() == DialogResult.OK)
foreach (string filename in d.FileNames)
Core.CommandV("sub-add", filename);
}
}));
}
if (d.ShowDialog() == DialogResult.OK)
foreach (string filename in d.FileNames)
Core.CommandV("sub-add", filename);
}
});
public static void LoadAudio()
public static void LoadAudio() => App.InvokeOnMainThread(() =>
{
App.InvokeOnMainThread(new Action(() => {
using (var d = new OpenFileDialog())
{
string path = Core.GetPropertyString("path");
using (var d = new OpenFileDialog())
{
string path = Core.GetPropertyString("path");
if (File.Exists(path))
d.InitialDirectory = Path.GetDirectoryName(path);
if (File.Exists(path))
d.InitialDirectory = Path.GetDirectoryName(path);
d.Multiselect = true;
d.Multiselect = true;
if (d.ShowDialog() == DialogResult.OK)
foreach (string i in d.FileNames)
Core.CommandV("audio-add", i);
}
}));
}
if (d.ShowDialog() == DialogResult.OK)
foreach (string i in d.FileNames)
Core.CommandV("audio-add", i);
}
});
public static void CycleAudio()
{
@@ -335,16 +335,16 @@ namespace mpvnet
public static void ShowCommands()
{
string json = Core.GetPropertyString("command-list");
var o = json.FromJson<List<Dictionary<string, object>>>().OrderBy(i => i["name"]);
string jsonString = Core.GetPropertyString("command-list");
var jsonObject = jsonString.FromJson<List<Dictionary<string, object>>>().OrderBy(i => i["name"]);
StringBuilder sb = new StringBuilder();
foreach (Dictionary<string, object> i in o)
foreach (Dictionary<string, object> dic in jsonObject)
{
sb.AppendLine();
sb.AppendLine(i["name"].ToString());
sb.AppendLine(dic["name"].ToString());
foreach (Dictionary<string, object> i2 in i["args"] as List<object>)
foreach (Dictionary<string, object> i2 in dic["args"] as List<object>)
{
string value = i2["name"].ToString() + " <" + i2["type"].ToString().ToLower() + ">";
@@ -355,7 +355,7 @@ namespace mpvnet
}
}
Msg.ShowInfo(sb.ToString());
ShowTextWithEditor("command-list", sb.ToString());
}
public static void ScaleWindow(float factor) => Core.RaiseScaleWindow(factor);
@@ -377,8 +377,23 @@ namespace mpvnet
"}${osd-ass-cc/1}" + text + "\" " + duration);
}
public static void ShowMediaInfo(string[] args)
public static void ShowMediaInfo(string[] args) => App.InvokeOnMainThread(() =>
{
if (args == null || args.Length == 0)
{
(string Name, string Value)[] pairs = {
("Show text box", "script-message mpv.net show-media-info default"),
("Show text editor", "script-message mpv.net show-media-info editor"),
("Show full", "script-message mpv.net show-media-info editor full"),
("Show raw", "script-message mpv.net show-media-info editor full raw") };
var list = pairs.Select(i => new CommandPaletteItem(i.Name, () => Core.Command(i.Value)));
CommandPalette.Instance.SetItems(list);
MainForm.Instance.ShowCommandPalette();
CommandPalette.Instance.SelectFirst();
return;
}
string path = Core.GetPropertyString("path");
if (File.Exists(path) && !path.Contains(@"\\.\pipe\"))
@@ -387,14 +402,22 @@ namespace mpvnet
{
bool full = args.Contains("full");
bool raw = args.Contains("raw");
bool editor = args.Contains("editor");
string text = mediaInfo.GetSummary(full, raw);
text = Regex.Replace(text, "Unique ID.+", "");
MsgBoxEx.MessageBoxEx.MsgFontFamily = new FontFamily("Consolas");
Msg.ShowInfo(text);
MsgBoxEx.MessageBoxEx.MsgFontFamily = new FontFamily("Segoe UI");
if (editor)
ShowTextWithEditor("media-info", text);
else
{
MsgBoxEx.MessageBoxEx.MsgFontFamily = new FontFamily("Consolas");
Msg.ShowInfo(text);
MsgBoxEx.MessageBoxEx.MsgFontFamily = new FontFamily("Segoe UI");
}
}
}
}
});
public static void ShowCommandPalette() => App.InvokeOnMainThread(() =>
{
@@ -537,7 +560,7 @@ namespace mpvnet
if (propValue.ContainsEx("${"))
propValue += BR2 + Core.Expand(propValue);
App.ShowInfo(prop + ": " + propValue);
App.ShowInfo(prop + "\n\n" + propValue);
}
};
@@ -624,5 +647,40 @@ namespace mpvnet
MainForm.Instance.ShowCommandPalette();
CommandPalette.Instance.SelectFirst();
});
public static void ShowSetupDialog() => App.InvokeOnMainThread(() =>
{
(string Name, string Value)[] pairs = {
("Register video file associations", "script-message mpv.net reg-file-assoc video"),
("Register audio file associations", "script-message mpv.net reg-file-assoc audio"),
("Register image file associations", "script-message mpv.net reg-file-assoc image"),
("Unregister file associations", "script-message mpv.net reg-file-assoc unreg") };
var list = pairs.Select(i => new CommandPaletteItem(i.Name, () => Core.Command(i.Value)));
CommandPalette.Instance.SetItems(list);
MainForm.Instance.ShowCommandPalette();
CommandPalette.Instance.SelectFirst();
});
public static void ShowMenu() => Core.RaiseShowMenu();
public static void PlaylistAdd(int value)
{
int pos = Core.GetPropertyInt("playlist-pos");
int count = Core.GetPropertyInt("playlist-count");
if (count < 2)
return;
pos = pos + value;
if (pos < 0)
pos = count - 1;
if (pos > count - 1)
pos = 0;
Core.SetPropertyInt("playlist-pos", pos);
}
}
}

View File

@@ -68,13 +68,25 @@ public static class ConvertStringExtension
public static class PathStringExtension
{
// returns the extension with lower case and without preceding dot.
public static string Ext(this string instance)
public static string Ext(this string filepath) => Ext(filepath, false);
public static string Ext(this string filepath, bool includeDot)
{
if (instance == null)
if (string.IsNullOrEmpty(filepath))
return "";
return Path.GetExtension(instance).TrimStart('.').ToLower();
char[] chars = filepath.ToCharArray();
for (int x = filepath.Length - 1; x >= 0; x--)
{
if (chars[x] == Path.DirectorySeparatorChar)
return "";
if (chars[x] == '.')
return filepath.Substring(x + (includeDot ? 0 : 1)).ToLowerInvariant();
}
return "";
}
public static string FileName(this string instance)

View File

@@ -22,9 +22,9 @@ namespace mpvnet
public partial class MainForm : Form
{
public ElementHost CommandPaletteHost { get; set; }
public IntPtr mpvWindowHandle { get; set; }
public static MainForm Instance { get; set; }
public static IntPtr Hwnd { get; set; }
new WpfControls.ContextMenu ContextMenu { get; set; }
AutoResetEvent MenuAutoResetEvent { get; } = new AutoResetEvent(false);
Point LastCursorPosition;
@@ -44,10 +44,9 @@ namespace mpvnet
try
{
Instance = this;
Hwnd = Handle;
Core.Init();
Core.Shutdown += Core_Shutdown;
Core.ShowMenu += Core_ShowMenu;
Core.VideoSizeChanged += Core_VideoSizeChanged;
Core.ScaleWindow += Core_ScaleWindow;
Core.WindowScale += Core_WindowScale;
@@ -55,27 +54,8 @@ namespace mpvnet
Core.Seek += () => UpdateProgressBar();
Core.PlaylistPosChanged += (value) => SetTitle();
Core.ObserveProperty("window-maximized", PropChangeWindowMaximized);
Core.ObserveProperty("window-minimized", PropChangeWindowMinimized);
Core.ObservePropertyBool("border", PropChangeBorder);
Core.ObservePropertyBool("fullscreen", PropChangeFullscreen);
Core.ObservePropertyBool("keepaspect-window", value => Core.KeepaspectWindow = value);
Core.ObservePropertyBool("ontop", PropChangeOnTop);
Core.ObservePropertyBool("pause", PropChangePause);
Core.ObservePropertyString("sid", PropChangeSid);
Core.ObservePropertyString("aid", PropChangeAid);
Core.ObservePropertyString("vid", PropChangeVid);
Core.ObservePropertyString("title", PropChangeTitle);
Core.ObservePropertyInt("edition", PropChangeEdition);
Core.ObservePropertyDouble("window-scale", WindowScale);
if (Core.GPUAPI != "vulkan")
Core.ProcessCommandLine(false);
Init();
AppDomain.CurrentDomain.UnhandledException += (sender, e) => App.ShowException(e.ExceptionObject);
Application.ThreadException += (sender, e) => App.ShowException(e.Exception);
@@ -135,6 +115,44 @@ namespace mpvnet
}
}
void Init()
{
Core.Init(Handle);
Core.ObserveProperty("window-maximized", PropChangeWindowMaximized);
Core.ObserveProperty("window-minimized", PropChangeWindowMinimized);
Core.ObservePropertyBool("border", PropChangeBorder);
Core.ObservePropertyBool("fullscreen", PropChangeFullscreen);
Core.ObservePropertyBool("keepaspect-window", value => Core.KeepaspectWindow = value);
Core.ObservePropertyBool("ontop", PropChangeOnTop);
Core.ObservePropertyBool("pause", PropChangePause);
Core.ObservePropertyString("sid", PropChangeSid);
Core.ObservePropertyString("aid", PropChangeAid);
Core.ObservePropertyString("vid", PropChangeVid);
Core.ObservePropertyString("title", PropChangeTitle);
Core.ObservePropertyInt("edition", PropChangeEdition);
Core.ObservePropertyDouble("window-scale", WindowScale);
Core.ProcessCommandLine(false);
}
void Core_ShowMenu()
{
BeginInvoke(new Action(() => {
if (IsMouseInOSC())
return;
CursorHelp.Show();
UpdateMenu();
ContextMenu.IsOpen = true;
}));
}
void Core_ScaleWindow(float scale) {
BeginInvoke(new Action(() => {
int w, h;
@@ -320,22 +338,26 @@ namespace mpvnet
lock (Core.BluRayTitles)
{
List<(int Index, TimeSpan Len)> items = new List<(int Index, TimeSpan Len)>();
List<(int Index, TimeSpan Length)> items = new List<(int, TimeSpan)>();
for (int i = 0; i < Core.BluRayTitles.Count; i++)
items.Add((i, Core.BluRayTitles[i]));
var titleItems = items.OrderByDescending(item => item.Len)
.Take(20).OrderBy(item => item.Index);
var titleItems = items.OrderByDescending(item => item.Length)
.Take(20)
.OrderBy(item => item.Index);
foreach (var item in titleItems)
{
if (item.Len != TimeSpan.Zero)
if (item.Length != TimeSpan.Zero)
{
var mi = MenuHelp.Add(titlesMenuItem.Items, $"{item.Len} ({item.Index})");
var mi = MenuHelp.Add(titlesMenuItem.Items, $"Title {item.Index + 1}");
if (mi != null)
{
mi.InputGestureText = item.Length.ToString();
mi.Click += (sender, args) => Core.SetBluRayTitle(item.Index);
}
}
}
}
@@ -787,29 +809,22 @@ namespace mpvnet
case 0x105: // WM_SYSKEYUP
case 0x201: // WM_LBUTTONDOWN
case 0x202: // WM_LBUTTONUP
case 0x204: // WM_RBUTTONDOWN
case 0x205: // WM_RBUTTONUP
case 0x207: // WM_MBUTTONDOWN
case 0x208: // WM_MBUTTONUP
case 0x20a: // WM_MOUSEWHEEL
case 0x20e: // WM_MOUSEHWHEEL
case 0x20b: // WM_XBUTTONDOWN
case 0x20c: // WM_XBUTTONUP
if (Core.WindowHandle != IntPtr.Zero)
m.Result = SendMessage(Core.WindowHandle, m.Msg, m.WParam, m.LParam);
case 0x20c: // WM_XBUTTONUP
case 0x20e: // WM_MOUSEHWHEEL
if (mpvWindowHandle == IntPtr.Zero)
mpvWindowHandle = FindWindowEx(Handle, IntPtr.Zero, "mpv", null);
if (mpvWindowHandle != IntPtr.Zero)
m.Result = SendMessage(mpvWindowHandle, m.Msg, m.WParam, m.LParam);
break;
case 0x0204: // WM_RBUTTONDOWN
if (IsMouseInOSC() && Core.WindowHandle != IntPtr.Zero)
m.Result = SendMessage(Core.WindowHandle, m.Msg, m.WParam, m.LParam);
break;
case 0x0205: // WM_RBUTTONUP
if (!IsMouseInOSC())
{
CursorHelp.Show();
UpdateMenu();
ContextMenu.IsOpen = true;
}
else
if (Core.WindowHandle != IntPtr.Zero)
m.Result = SendMessage(Core.WindowHandle, m.Msg, m.WParam, m.LParam);
case 0x051: // WM_INPUTLANGCHANGE
ActivateKeyboardLayout(m.LParam, 0x00000100u /*KLF_SETFORPROCESS*/);
break;
case 0x319: // WM_APPCOMMAND
{
@@ -1017,7 +1032,8 @@ namespace mpvnet
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
Core.VideoSizeAutoResetEvent.WaitOne(App.StartThreshold);
if (Core.GPUAPI != "vulkan")
Core.VideoSizeAutoResetEvent.WaitOne(App.StartThreshold);
LastCycleFullscreen = Environment.TickCount;
SetFormPosAndSize();
}
@@ -1032,12 +1048,12 @@ namespace mpvnet
{
base.OnShown(e);
if (Core.GPUAPI == "vulkan")
Init();
if (WindowState == FormWindowState.Maximized)
Core.SetPropertyBool("window-maximized", true);
if (Core.GPUAPI == "vulkan")
Core.ProcessCommandLine(false);
WPF.Init();
App.UpdateWpfColors();
MessageBoxEx.MessageForeground = Theme.Current.GetBrush("heading");

View File

@@ -166,6 +166,14 @@ namespace mpvnet
}
}
public string Alias {
get {
if (Input.Contains("SHARP") || Input.Contains("sharp") || Input.Contains("Sharp"))
return "#";
return null;
}
}
public static ObservableCollection<CommandItem> GetItems(string content)
{
var items = new ObservableCollection<CommandItem>();
@@ -233,6 +241,14 @@ namespace mpvnet
public class CommandPaletteItem
{
public CommandPaletteItem() {}
public CommandPaletteItem(string text, Action action)
{
Text = text;
Action = action;
}
public string Text { get; set; } = "";
public string SecondaryText { get; set; } = "";
public Action Action { get; set; }

View File

@@ -53,6 +53,7 @@ namespace mpvnet
public event Action Initialized;
public event Action InitializedAsync;
public event Action ShowMenu;
public event Action<float> ScaleWindow;
public event Action<float> WindowScale;
public event Action<int> PlaylistPosChanged;
@@ -70,7 +71,6 @@ namespace mpvnet
public List<KeyValuePair<string, double>> Chapters { get; set; } = new List<KeyValuePair<string, double>>();
public List<TimeSpan> BluRayTitles { get; } = new List<TimeSpan>();
public IntPtr Handle { get; set; }
public IntPtr WindowHandle { get; set; }
public Size VideoSize { get; set; }
public TimeSpan Duration;
@@ -81,7 +81,7 @@ namespace mpvnet
public string ConfPath { get => ConfigFolder + "mpv.conf"; }
public string GPUAPI { get; set; } = "auto";
public string VO { get; set; } = "gpu";
public string InputConfPath { get => ConfigFolder + "input.conf"; }
public string InputConfPath => ConfigFolder + "input.conf";
public string VID { get; set; } = "";
public string AID { get; set; } = "";
@@ -107,8 +107,10 @@ namespace mpvnet
public float AutofitSmaller { get; set; } = 0.3f;
public float AutofitLarger { get; set; } = 0.8f;
public void Init()
public void Init(IntPtr handle)
{
ApplyShowMenuFix();
Handle = mpv_create();
if (Handle == IntPtr.Zero)
@@ -124,24 +126,21 @@ namespace mpvnet
SetPropertyString("input-terminal", "yes");
SetPropertyString("msg-level", "osd/libass=fatal");
}
SetPropertyInt("osd-duration", 2000);
SetPropertyLong("wid", handle.ToInt64());
SetPropertyBool("input-default-bindings", true);
SetPropertyBool("input-builtin-bindings", false);
SetPropertyString("script-opts", "osc-scalewindowed=1.5,osc-hidetimeout=2000,console-scale=1.5");
SetPropertyString("watch-later-options", "mute");
SetPropertyString("screenshot-directory", "~~desktop/");
SetPropertyString("osd-playing-msg", "${filename}");
SetPropertyString("wid", MainForm.Hwnd.ToString());
SetPropertyString("osc", "yes");
SetPropertyString("force-window", "yes");
SetPropertyString("config-dir", ConfigFolder);
SetPropertyString("config", "yes");
SetPropertyInt("osd-duration", 2000);
SetPropertyBool("keep-open", true);
SetPropertyBool("keep-open-pause", false);
SetPropertyBool("input-default-bindings", true);
SetPropertyBool("input-builtin-bindings", false);
ProcessCommandLine(true);
mpv_error err = mpv_initialize(Handle);
@@ -160,7 +159,7 @@ namespace mpvnet
{
ShowLogo();
if (GetPropertyString("keep-open") == "no")
if (GetPropertyString("keep-open") == "no" && App.KeepOpenExit)
Core.CommandV("quit");
}
});
@@ -169,23 +168,40 @@ namespace mpvnet
InvokeAsync(InitializedAsync);
}
void ApplyCompatibilityFixes()
void ApplyShowMenuFix()
{
if (!App.Settings.InputDefaultBindingsFixApplied)
if (App.Settings.ShowMenuFixApplied)
return;
if (File.Exists(InputConfPath))
{
if (File.Exists(ConfPath))
{
string content = File.ReadAllText(ConfPath);
string content = File.ReadAllText(InputConfPath);
if (content.Contains("input-default-bindings = no"))
File.WriteAllText(ConfPath, content.Replace("input-default-bindings = no", ""));
if (content.Contains("input-default-bindings=no"))
File.WriteAllText(ConfPath, content.Replace("input-default-bindings=no", ""));
}
App.Settings.InputDefaultBindingsFixApplied = true;
if (!content.Contains("script-message mpv.net show-menu"))
File.WriteAllText(InputConfPath, BR + content.Trim() + BR +
"MBTN_Right script-message mpv.net show-menu" + BR);
}
App.Settings.ShowMenuFixApplied = true;
}
void ApplyInputDefaultBindingsFix()
{
if (App.Settings.InputDefaultBindingsFixApplied)
return;
if (File.Exists(ConfPath))
{
string content = File.ReadAllText(ConfPath);
if (content.Contains("input-default-bindings = no"))
File.WriteAllText(ConfPath, content.Replace("input-default-bindings = no", ""));
if (content.Contains("input-default-bindings=no"))
File.WriteAllText(ConfPath, content.Replace("input-default-bindings=no", ""));
}
App.Settings.InputDefaultBindingsFixApplied = true;
}
public void ProcessProperty(string name, string value)
@@ -233,15 +249,17 @@ namespace mpvnet
if (!Directory.Exists(_ConfigFolder))
{
using (Process proc = new Process())
{
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.CreateNoWindow = true;
proc.StartInfo.FileName = "powershell.exe";
proc.StartInfo.Arguments = $@"-Command New-Item -Path '{_ConfigFolder}' -ItemType Directory";
proc.Start();
proc.WaitForExit();
}
try {
using (Process proc = new Process())
{
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.CreateNoWindow = true;
proc.StartInfo.FileName = "powershell.exe";
proc.StartInfo.Arguments = $@"-Command New-Item -Path '{_ConfigFolder}' -ItemType Directory";
proc.Start();
proc.WaitForExit();
}
} catch (Exception) {}
if (!Directory.Exists(_ConfigFolder))
Directory.CreateDirectory(_ConfigFolder);
@@ -250,7 +268,7 @@ namespace mpvnet
_ConfigFolder = _ConfigFolder.AddSep();
if (!File.Exists(_ConfigFolder + "input.conf"))
File.WriteAllText(_ConfigFolder + "input.conf", PatchInput(Properties.Resources.input_conf));
File.WriteAllText(_ConfigFolder + "input.conf", Properties.Resources.input_conf);
}
return _ConfigFolder;
@@ -263,7 +281,7 @@ namespace mpvnet
get {
if (_Conf == null)
{
ApplyCompatibilityFixes();
ApplyInputDefaultBindingsFix();
_Conf = new Dictionary<string, string>();
@@ -280,28 +298,6 @@ namespace mpvnet
}
}
string PatchInput(string value)
{
if (Environment.GetEnvironmentVariable("username") == "frank" && Directory.Exists(@"D:\Projects\CS\mpv.net"))
value = value.Replace("volume 2 ", "volume 10")
.Replace("volume -2 ", "volume -10");
value += @"
KP2 script-message rate-file 2
2 script-message rate-file 2
KP3 script-message rate-file 3
3 script-message rate-file 3
KP4 script-message rate-file 4
4 script-message rate-file 4
KP5 script-message rate-file 5
5 script-message rate-file 5
KP0 script-binding delete_current_file/delete
0 script-binding delete_current_file/delete
KP1 script-binding delete_current_file/confirm
1 script-binding delete_current_file/confirm";
return value;
}
public void LoadScripts()
{
if (Directory.Exists(ConfigFolder + "scripts-ps"))
@@ -391,24 +387,6 @@ KP1 script-binding delete_current_file/confirm
IntPtr ptr = mpv_wait_event(Handle, -1);
mpv_event evt = (mpv_event)Marshal.PtrToStructure(ptr, typeof(mpv_event));
if (WindowHandle == IntPtr.Zero)
{
WindowHandle = Native.FindWindowEx(MainForm.Hwnd, IntPtr.Zero, "mpv", null);
if (WindowHandle != IntPtr.Zero)
{
int GWL_STYLE = -16;
uint WS_CHILD = 0x40000000;
uint WS_CLIPSIBLINGS = 0x04000000;
uint WS_DISABLED = 0x08000000;
uint WS_VISIBLE = 0x10000000;
Native.SetWindowLong(WindowHandle, GWL_STYLE,
WS_CHILD | WS_VISIBLE | WS_DISABLED | WS_CLIPSIBLINGS);
}
}
try
{
switch (evt.event_id)
@@ -779,6 +757,14 @@ KP1 script-binding delete_current_file/confirm
HandleError(err, throwException, $"error setting property: {name} = {value}");
}
public void SetPropertyLong(string name, long value, bool throwException = false)
{
mpv_error err = mpv_set_property(Handle, GetUtf8Bytes(name), mpv_format.MPV_FORMAT_INT64, ref value);
if (err < 0)
HandleError(err, throwException, $"error setting property: {name} = {value}");
}
public long GetPropertyLong(string name, bool throwException = false)
{
mpv_error err = mpv_get_property(Handle, GetUtf8Bytes(name),
@@ -790,15 +776,6 @@ KP1 script-binding delete_current_file/confirm
return lpBuffer.ToInt64();
}
public void SetPropertyLong(string name, long value, bool throwException = false)
{
long val = value;
mpv_error err = mpv_set_property(Handle, GetUtf8Bytes(name), mpv_format.MPV_FORMAT_INT64, ref val);
if (err < 0)
HandleError(err, throwException, $"error setting property: {name} = {value}");
}
public double GetPropertyDouble(string name, bool throwException = false)
{
mpv_error err = mpv_get_property(Handle, GetUtf8Bytes(name),
@@ -1309,7 +1286,7 @@ KP1 script-binding delete_current_file/confirm
public void ShowLogo()
{
if (MainForm.Instance is null)
if (!App.ShowLogo || MainForm.Instance == null || Core.Handle == IntPtr.Zero)
return;
bool december = DateTime.Now.Month == 12;
@@ -1317,7 +1294,7 @@ KP1 script-binding delete_current_file/confirm
Rectangle cr = MainForm.Instance.ClientRectangle;
int len = Convert.ToInt32(cr.Height / (december ? 4.5 : 5));
if (len == 0)
if (len < 16 || cr.Height < 16)
return;
using (Bitmap bmp = new Bitmap(len, len))
@@ -1351,6 +1328,8 @@ KP1 script-binding delete_current_file/confirm
public void RaiseScaleWindow(float value) => ScaleWindow(value);
public void RaiseWindowScale(float value) => WindowScale(value);
public void RaiseShowMenu() => ShowMenu();
void ReadMetaData()
{
@@ -1510,6 +1489,10 @@ KP1 script-binding delete_current_file/confirm
{
string text = GetPropertyString($"chapter-list/{x}/title");
double time = GetPropertyDouble($"chapter-list/{x}/time");
if (string.IsNullOrEmpty(text))
text = "Chapter " + (x + 1);
Chapters.Add(new KeyValuePair<string, double>(text, time));
}
}

View File

@@ -15,7 +15,7 @@ namespace mpvnet
public class AppSettings
{
public bool InputDefaultBindingsFixApplied;
public int LastUpdateCheck;
public bool ShowMenuFixApplied;
public int Volume = 70;
public List<string> RecentFiles = new List<string>();
public Point WindowLocation;

View File

@@ -18,6 +18,9 @@ namespace mpvnet
[DllImport("kernel32.dll")]
public static extern IntPtr LoadLibrary(string path);
[DllImport("user32.dll")]
public static extern uint ActivateKeyboardLayout(IntPtr hkl, uint flags);
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
public static extern IntPtr FindWindowEx(
IntPtr parentHandle, IntPtr childAfter, string lclassName, string windowTitle);

View File

@@ -11,7 +11,7 @@
<Identity
Name="5664FrankSkare.mpv.net"
Publisher="CN=6A1A1E69-736C-4C77-B310-7B6D38E32617"
Version="5.6.0.0" />
Version="5.7.0.0" />
<Properties>
<DisplayName>mpv.net</DisplayName>

View File

@@ -4,14 +4,6 @@
<VisualStudioVersion>15.0</VisualStudioVersion>
</PropertyGroup>
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|x86">
<Configuration>Debug</Configuration>
<Platform>x86</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x86">
<Configuration>Release</Configuration>
<Platform>x86</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
@@ -20,30 +12,6 @@
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|ARM">
<Configuration>Debug</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|ARM">
<Configuration>Release</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|ARM64">
<Configuration>Debug</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|ARM64">
<Configuration>Release</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|AnyCPU">
<Configuration>Debug</Configuration>
<Platform>AnyCPU</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|AnyCPU">
<Configuration>Release</Configuration>
<Platform>AnyCPU</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup>
<WapProjPath Condition="'$(WapProjPath)'==''">$(MSBuildExtensionsPath)\Microsoft\DesktopBridge\</WapProjPath>
@@ -63,36 +31,12 @@
<GenerateTemporaryStoreCertificate>True</GenerateTemporaryStoreCertificate>
<HoursBetweenUpdateChecks>0</HoursBetweenUpdateChecks>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<AppxBundle>Always</AppxBundle>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x86'">
<AppxBundle>Always</AppxBundle>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
<AppxBundle>Always</AppxBundle>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x86'">
<AppxBundle>Always</AppxBundle>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<AppxBundle>Always</AppxBundle>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
<AppxBundle>Always</AppxBundle>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<AppxBundle>Always</AppxBundle>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
<AppxBundle>Always</AppxBundle>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<AppxBundle>Always</AppxBundle>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
<AppxBundle>Always</AppxBundle>
</PropertyGroup>
<ItemGroup>
<AppxManifest Include="Package.appxmanifest">
<SubType>Designer</SubType>

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
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("5.6.1.0")]
[assembly: AssemblyFileVersion("5.6.1.0")]
[assembly: AssemblyVersion("5.9.0.0")]
[assembly: AssemblyFileVersion("5.9.0.0")]

View File

@@ -4,8 +4,15 @@ $exePath = $PSScriptRoot + '\bin\mpvnet.exe'
$versionInfo = [Diagnostics.FileVersionInfo]::GetVersionInfo($exePath)
$7z = 'C:\Program Files\7-Zip\7z.exe'
$targetDir = $tmpDir + "\mpv.net-$($versionInfo.FileVersion)-portable-beta"
Copy-Item $PSScriptRoot\bin $targetDir -Recurse -Exclude 'System.Management.Automation.xml'
$targetDir = $tmpDir + "\mpv.net-$($versionInfo.FileVersion)-beta"
Copy-Item $PSScriptRoot\bin $targetDir -Recurse -Exclude System.Management.Automation.xml
$folders = 'Debug', 'Release', 'x64', 'x86', 'Arm'
foreach ($folder in $folders) {
Remove-Item (Join-Path $targetDir $folder) -Recurse -ErrorAction SilentlyContinue
}
& $7z a -tzip -mx9 "$targetDir.zip" -r "$targetDir\*"
if ($LastExitCode) { throw $LastExitCode }

View File

@@ -505,6 +505,17 @@ help = Show progress in taskbar.
option = yes
option = no
[setting]
name = keep-open
file = mpv
default = no
filter = Playback
help = Using no, mpv would terminate after the last file but mpv.net never terminates automatically.
option = yes If the current file ends, go to the next file, keep the last file open.
option = no If the current file ends, go to the next file. If keep-open-exit is set to yes, mpv.net exits after the last file.
option = always Playback will never automatically advance to the next file.
[setting]
name = keep-open-pause
file = mpv
@@ -516,15 +527,14 @@ option = yes
option = no
[setting]
name = keep-open
file = mpv
name = keep-open-exit
file = mpvnet
default = no
filter = Playback
help = Using no, mpv would terminate after the last file but mpv.net never terminates automatically.
help = If set to yes and keep-open is set to no, mpv.net exits after the last file ends. In mpv the idle property would be used, it's not possible for mpv.net to use the idle property.
option = yes If the current file ends, go to the next file, keep the last file open.
option = no If the current file ends, go to the next file.
option = always Playback will never automatically advance to the next file.
option = yes
option = no
[setting]
name = auto-play
@@ -681,3 +691,13 @@ file = mpvnet
filter = UI
url = https://github.com/stax76/mpv.net/blob/master/docs/Manual.md#color-theme
help = Color theme used in light mode.\nmpv.net must be restarted after a change.\nmpv.net specific option. Default: light
[setting]
name = show-logo
file = mpvnet
default = yes
filter = UI
help = Draws the blue mpv.net logo ontop of the native OSC logo.
option = yes
option = no

View File

@@ -2,7 +2,7 @@
# https://github.com/stax76/mpv.net/blob/master/docs/Manual.md#input-and-context-menu
o script-message mpv.net open-files #menu: Open > Open Files...
Ctrl+v script-message mpv.net open-url #menu: Open > Open URL or file from clipboard
Ctrl+v script-message mpv.net open-clipboard #menu: Open > Open URL or file from clipboard
_ script-message mpv.net open-optical-media #menu: Open > Open DVD/Blu-ray Drive/Folder...
_ ignore #menu: Open > -
Alt+a script-message mpv.net load-audio #menu: Open > Load external audio files...
@@ -18,8 +18,8 @@ Ctrl+s stop #menu: Stop
_ ignore #menu: -
Enter cycle fullscreen #menu: Toggle Fullscreen
F11 playlist-prev; set pause no #menu: Navigate > Previous File
F12 playlist-next; set pause no #menu: Navigate > Next File
F11 script-message mpv.net playlist-add -1; set pause no #menu: Navigate > Previous File
F12 script-message mpv.net playlist-add 1; set pause no #menu: Navigate > Next File
_ ignore #menu: Navigate > -
Home script-message mpv.net playlist-first #menu: Navigate > First File
End script-message mpv.net playlist-last #menu: Navigate > Last File
@@ -71,6 +71,7 @@ _ ignore #menu: Video > -
s async screenshot #menu: Video > Take Screenshot
d cycle deinterlace #menu: Video > Toggle Deinterlace
a cycle-values video-aspect 16:9 4:3 2.35:1 -1 #menu: Video > Cycle Aspect Ratio
Ctrl+r cycle-values video-rotate 90 180 270 0 #menu: Video > Rotate Video
KP7 script-message mpv.net cycle-audio #menu: Audio > Cycle/Next
_ ignore #menu: Audio > -
@@ -119,7 +120,6 @@ b cycle border #menu: View > Toggle Border
Ctrl+t cycle ontop #menu: View > Toggle On Top
t script-binding stats/display-stats-toggle #menu: View > Toggle Statistics
Del script-binding osc/visibility #menu: View > Toggle OSC Visibility
Ctrl+r cycle-values video-rotate 90 180 270 0 #menu: View > Rotate Video
i script-message mpv.net show-info #menu: View > Show File/Stream Info
p show-progress #menu: View > Show Progress
Ctrl+p script-message mpv.net show-profiles #menu: View > Show Profiles
@@ -166,10 +166,13 @@ F1 script-message mpv.net show-command-palette #menu: Command Palette
_ ignore #menu: -
Esc quit #menu: Exit
MBTN_Right script-message mpv.net show-menu
6 script-message mpv.net show-progress
KP6 script-message mpv.net show-progress
7 script-message mpv.net cycle-audio
SHARP script-message mpv.net cycle-audio
Sharp script-message mpv.net cycle-audio
Ctrl+F11 script-message mpv.net playlist-add -10
Ctrl+F12 script-message mpv.net playlist-add 10
8 cycle sub
j cycle sub
q quit
@@ -195,15 +198,15 @@ MBTN_Left ignore
f cycle fullscreen
MBTN_Left_DBL cycle fullscreen
KP_Enter cycle fullscreen
Shift+RIGHT no-osd seek 1 exact
Shift+LEFT no-osd seek -1 exact
Shift+UP no-osd seek 5 exact
Shift+DOWN no-osd seek -5 exact
Shift+Right no-osd seek 1 exact
Shift+Left no-osd seek -1 exact
Shift+Up no-osd seek 5 exact
Shift+Down no-osd seek -5 exact
Shift+BS revert-seek # undo the previous (or marked) seek
Shift+Ctrl+BS revert-seek mark # mark the position for revert-seek
Shift+g add sub-scale +0.1 # increase the subtitle font size
Shift+f add sub-scale -0.1 # decrease the subtitle font size
Ctrl+Shift+LEFT no-osd sub-seek -1 # seek to the previous subtitle
Ctrl+Shift+RIGHT no-osd sub-seek 1 # seek to the next subtitle
Ctrl+Shift+Left no-osd sub-seek -1 # seek to the previous subtitle
Ctrl+Shift+Right no-osd sub-seek 1 # seek to the next subtitle
Ctrl+Wheel_Up no-osd seek 7
Ctrl+Wheel_Down no-osd seek -7

View File

@@ -1,35 +0,0 @@
// When seeking displays position and duration like so: 70:00 / 80:00
// Which is different from most players which use: 01:10:00 / 01:20:00
// In input.conf set the input command prefix no-osd infront of the seek command.
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(_)
{
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));
}
mp.register_event("seek", on_seek);

View File

@@ -1,26 +0,0 @@
// This script shows the playlist.
function showPlaylist()
{
// set font size
mp.set_property_number("osd-font-size", 40);
// show playlist for 5 seconds
mp.command("show-text ${playlist} 5000");
// restore original font size in 6 seconds
setTimeout(resetFontSize, 6000);
}
// restore original font size
function resetFontSize()
{
mp.set_property_number("osd-font-size", size);
}
// save original font size
var size = mp.get_property_number("osd-font-size");
// input.conf: key script-binding show-playlist
mp.add_key_binding(null, "show-playlist", showPlaylist);

View File

@@ -1,62 +0,0 @@
-- This script deletes the file that is currently playing.
-- input.conf:
-- KP0 script-binding delete_current_file/delete
-- 0 script-binding delete_current_file/delete
-- KP1 script-binding delete_current_file/confirm
-- 1 script-binding delete_current_file/confirm
function delete()
FileToDelete = mp.get_property("path")
DeleteTime = os.time()
mp.commandv("show-text", "Press 1 to delete file", "10000")
end
function confirm()
local path = mp.get_property("path")
if FileToDelete == path and (os.time() - DeleteTime) < 10 then
mp.commandv("show-text", "")
local count = mp.get_property_number("playlist-count")
local pos = mp.get_property_number("playlist-pos")
local newPos = 0
if pos == count - 1 then
newPos = pos - 1
else
newPos = pos + 1
end
if newPos > -1 then
mp.command("set pause no")
mp.set_property_number("playlist-pos", newPos)
end
mp.command("playlist-remove " .. pos)
local ps_code = [[& {
Start-Sleep -Seconds 2
Add-Type -AssemblyName Microsoft.VisualBasic
[Microsoft.VisualBasic.FileIO.FileSystem]::DeleteFile('FileToDelete', 'OnlyErrorDialogs', 'SendToRecycleBin')
}]]
local escapedFileToDelete = string.gsub(FileToDelete, "'", "''")
escapedFileToDelete = string.gsub(escapedFileToDelete, "", "")
escapedFileToDelete = string.gsub(escapedFileToDelete, "%%", "%%%%")
ps_code = string.gsub(ps_code, "FileToDelete", escapedFileToDelete)
mp.command_native({
name = "subprocess",
playback_only = false,
detach = true,
args = { 'powershell', '-NoProfile', '-ExecutionPolicy', 'Bypass', '-Command', ps_code },
})
end
end
mp.add_key_binding(nil, "delete", delete)
mp.add_key_binding(nil, "confirm", confirm)

View File

@@ -1,23 +0,0 @@
-- https://github.com/mpv-player/mpv/blob/master/TOOLS/lua/pause-when-minimize.lua
-- This script pauses playback when minimizing the window, and resumes playback
-- if it's brought back again. If the player was already paused when minimizing,
-- then try not to mess with the pause state.
local did_minimize = false
mp.observe_property("window-minimized", "bool", function(name, value)
local pause = mp.get_property_native("pause")
if value == true then
if pause == false then
mp.set_property_native("pause", true)
did_minimize = true
end
elseif value == false then
if did_minimize and (pause == true) then
mp.set_property_native("pause", false)
end
did_minimize = false
end
end)

View File

@@ -90,10 +90,19 @@ namespace mpvnet
{
string filter = SearchControl.SearchTextBox.Text.ToLower();
if (filter.Length == 1 && item.CommandItem != null)
return item.CommandItem.Input.ToLower().Replace("ctrl+", "")
.Replace("shift+", "")
.Replace("alt+", "") == filter.ToLower();
if (item.CommandItem != null)
{
if (item.CommandItem.Alias.ContainsEx(filter))
return true;
if (filter.Length == 1)
return item.CommandItem.Input.ToLower().Replace("ctrl+", "")
.Replace("shift+", "")
.Replace("alt+", "") == filter.ToLower();
if (item.CommandItem.Command.ToLower().Contains(filter))
return true;
}
if (filter == "" || item.Text.ToLower().Contains(filter) ||
item.SecondaryText.ToLower().Contains(filter))

View File

@@ -9,7 +9,7 @@
mc:Ignorable="d"
Title="Config Editor"
Height="530"
Height="540"
Width="700"
Foreground="{Binding Theme.Foreground}"
Background="{Binding Theme.Background}"
@@ -25,7 +25,7 @@
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100" />
<ColumnDefinition Width="105" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
@@ -75,7 +75,8 @@
</ListBox.ItemTemplate>
</ListBox>
<TextBlock Name="OpenSettingsTextBlock" Margin="0,30,0,0" Cursor="Hand" TextWrapping="WrapWithOverflow" Foreground="{Binding Theme.Heading}" MouseUp="OpenSettingsTextBlock_MouseUp">Open config folder</TextBlock>
<TextBlock Name="ShowMpvNetSpecific" Margin="0,15,0,0" Cursor="Hand" TextWrapping="WrapWithOverflow" Foreground="{Binding Theme.Heading}" MouseUp="ShowMpvNetSpecific_MouseUp">Show mpv.net specific options</TextBlock>
<TextBlock Name="OpenSettingsTextBlock" Margin="0,15,0,0" Cursor="Hand" TextWrapping="WrapWithOverflow" Foreground="{Binding Theme.Heading}" MouseUp="OpenSettingsTextBlock_MouseUp">Open config folder</TextBlock>
<TextBlock Name="PreviewTextBlock" Margin="0,15,0,0" Cursor="Hand" TextWrapping="WrapWithOverflow" Foreground="{Binding Theme.Heading}" MouseUp="PreviewTextBlock_MouseUp">Preview mpv.conf</TextBlock>
<TextBlock Name="ShowManualTextBlock" Margin="0,15,0,0" Cursor="Hand" TextWrapping="WrapWithOverflow" Foreground="{Binding Theme.Heading}" MouseUp="ShowManualTextBlock_MouseUp">Show mpv manual</TextBlock>
<TextBlock Name="SupportTextBlock" Margin="0,15,0,0" Cursor="Hand" TextWrapping="WrapWithOverflow" Foreground="{Binding Theme.Heading}" MouseUp="SupportTextBlock_MouseUp">Show support forum</TextBlock>

View File

@@ -344,5 +344,7 @@ namespace mpvnet
if (e.Key == Key.Escape)
Close();
}
void ShowMpvNetSpecific_MouseUp(object sender, MouseButtonEventArgs e) => SearchControl.Text = "mpv.net";
}
}

View File

@@ -48,28 +48,25 @@
<PropertyGroup>
<ApplicationManifest>app.manifest</ApplicationManifest>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|AnyCPU'">
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>AnyCPU</PlatformTarget>
<PlatformTarget>x64</PlatformTarget>
<LangVersion>7.3</LangVersion>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<Prefer32Bit>false</Prefer32Bit>
<AllowUnsafeBlocks>false</AllowUnsafeBlocks>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|AnyCPU'">
<OutputPath>bin\</OutputPath>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
<OutputPath>bin\x64\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>AnyCPU</PlatformTarget>
<PlatformTarget>x64</PlatformTarget>
<LangVersion>7.3</LangVersion>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<ItemGroup>
<Reference Include="Microsoft.VisualBasic" />
@@ -196,7 +193,7 @@
<DependentUpon>MainForm.cs</DependentUpon>
</Compile>
<Compile Include="Misc\Misc.cs" />
<Compile Include="Misc\CorePlayer.cs" />
<Compile Include="Misc\Player.cs" />
<Compile Include="Misc\Commands.cs" />
<Compile Include="Native\Native.cs" />
<Compile Include="Misc\Program.cs" />

View File

@@ -1,7 +1,7 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.28729.10
# Visual Studio Version 17
VisualStudioVersion = 17.1.32228.430
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "mpv.net", "mpv.net.csproj", "{1751F378-8EDF-4B62-BE6D-304C7C287089}"
EndProject
@@ -16,88 +16,24 @@ Project("{C7167F0D-BC9F-4E6E-AFE1-012C56B48DB5}") = "mpv.net.package", "Package\
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|ARM = Debug|ARM
Debug|ARM64 = Debug|ARM64
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|ARM = Release|ARM
Release|ARM64 = Release|ARM64
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{1751F378-8EDF-4B62-BE6D-304C7C287089}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1751F378-8EDF-4B62-BE6D-304C7C287089}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1751F378-8EDF-4B62-BE6D-304C7C287089}.Debug|ARM.ActiveCfg = Debug|Any CPU
{1751F378-8EDF-4B62-BE6D-304C7C287089}.Debug|ARM.Build.0 = Debug|Any CPU
{1751F378-8EDF-4B62-BE6D-304C7C287089}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{1751F378-8EDF-4B62-BE6D-304C7C287089}.Debug|ARM64.Build.0 = Debug|Any CPU
{1751F378-8EDF-4B62-BE6D-304C7C287089}.Debug|x64.ActiveCfg = Debug|Any CPU
{1751F378-8EDF-4B62-BE6D-304C7C287089}.Debug|x64.Build.0 = Debug|Any CPU
{1751F378-8EDF-4B62-BE6D-304C7C287089}.Debug|x86.ActiveCfg = Debug|Any CPU
{1751F378-8EDF-4B62-BE6D-304C7C287089}.Debug|x86.Build.0 = Debug|Any CPU
{1751F378-8EDF-4B62-BE6D-304C7C287089}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1751F378-8EDF-4B62-BE6D-304C7C287089}.Release|Any CPU.Build.0 = Release|Any CPU
{1751F378-8EDF-4B62-BE6D-304C7C287089}.Release|ARM.ActiveCfg = Release|Any CPU
{1751F378-8EDF-4B62-BE6D-304C7C287089}.Release|ARM.Build.0 = Release|Any CPU
{1751F378-8EDF-4B62-BE6D-304C7C287089}.Release|ARM64.ActiveCfg = Release|Any CPU
{1751F378-8EDF-4B62-BE6D-304C7C287089}.Release|ARM64.Build.0 = Release|Any CPU
{1751F378-8EDF-4B62-BE6D-304C7C287089}.Release|x64.ActiveCfg = Release|Any CPU
{1751F378-8EDF-4B62-BE6D-304C7C287089}.Release|x64.Build.0 = Release|Any CPU
{1751F378-8EDF-4B62-BE6D-304C7C287089}.Release|x86.ActiveCfg = Release|Any CPU
{1751F378-8EDF-4B62-BE6D-304C7C287089}.Release|x86.Build.0 = Release|Any CPU
{55C88710-539D-4402-84C8-31694841C731}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{55C88710-539D-4402-84C8-31694841C731}.Debug|Any CPU.Build.0 = Debug|Any CPU
{55C88710-539D-4402-84C8-31694841C731}.Debug|ARM.ActiveCfg = Debug|Any CPU
{55C88710-539D-4402-84C8-31694841C731}.Debug|ARM.Build.0 = Debug|Any CPU
{55C88710-539D-4402-84C8-31694841C731}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{55C88710-539D-4402-84C8-31694841C731}.Debug|ARM64.Build.0 = Debug|Any CPU
{55C88710-539D-4402-84C8-31694841C731}.Debug|x64.ActiveCfg = Debug|Any CPU
{55C88710-539D-4402-84C8-31694841C731}.Debug|x64.Build.0 = Debug|Any CPU
{55C88710-539D-4402-84C8-31694841C731}.Debug|x86.ActiveCfg = Debug|Any CPU
{55C88710-539D-4402-84C8-31694841C731}.Debug|x86.Build.0 = Debug|Any CPU
{55C88710-539D-4402-84C8-31694841C731}.Release|Any CPU.ActiveCfg = Release|Any CPU
{55C88710-539D-4402-84C8-31694841C731}.Release|Any CPU.Build.0 = Release|Any CPU
{55C88710-539D-4402-84C8-31694841C731}.Release|ARM.ActiveCfg = Release|Any CPU
{55C88710-539D-4402-84C8-31694841C731}.Release|ARM.Build.0 = Release|Any CPU
{55C88710-539D-4402-84C8-31694841C731}.Release|ARM64.ActiveCfg = Release|Any CPU
{55C88710-539D-4402-84C8-31694841C731}.Release|ARM64.Build.0 = Release|Any CPU
{55C88710-539D-4402-84C8-31694841C731}.Release|x64.ActiveCfg = Release|Any CPU
{55C88710-539D-4402-84C8-31694841C731}.Release|x64.Build.0 = Release|Any CPU
{55C88710-539D-4402-84C8-31694841C731}.Release|x86.ActiveCfg = Release|Any CPU
{55C88710-539D-4402-84C8-31694841C731}.Release|x86.Build.0 = Release|Any CPU
{81DAEE3A-76FF-4494-9384-D28A651D70BB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{81DAEE3A-76FF-4494-9384-D28A651D70BB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{81DAEE3A-76FF-4494-9384-D28A651D70BB}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
{81DAEE3A-76FF-4494-9384-D28A651D70BB}.Debug|ARM.ActiveCfg = Debug|ARM
{81DAEE3A-76FF-4494-9384-D28A651D70BB}.Debug|ARM.Build.0 = Debug|ARM
{81DAEE3A-76FF-4494-9384-D28A651D70BB}.Debug|ARM.Deploy.0 = Debug|ARM
{81DAEE3A-76FF-4494-9384-D28A651D70BB}.Debug|ARM64.ActiveCfg = Debug|ARM64
{81DAEE3A-76FF-4494-9384-D28A651D70BB}.Debug|ARM64.Build.0 = Debug|ARM64
{81DAEE3A-76FF-4494-9384-D28A651D70BB}.Debug|ARM64.Deploy.0 = Debug|ARM64
{1751F378-8EDF-4B62-BE6D-304C7C287089}.Debug|x64.ActiveCfg = Debug|x64
{1751F378-8EDF-4B62-BE6D-304C7C287089}.Debug|x64.Build.0 = Debug|x64
{1751F378-8EDF-4B62-BE6D-304C7C287089}.Release|x64.ActiveCfg = Release|x64
{1751F378-8EDF-4B62-BE6D-304C7C287089}.Release|x64.Build.0 = Release|x64
{55C88710-539D-4402-84C8-31694841C731}.Debug|x64.ActiveCfg = Debug|x64
{55C88710-539D-4402-84C8-31694841C731}.Debug|x64.Build.0 = Debug|x64
{55C88710-539D-4402-84C8-31694841C731}.Release|x64.ActiveCfg = Release|x64
{55C88710-539D-4402-84C8-31694841C731}.Release|x64.Build.0 = Release|x64
{81DAEE3A-76FF-4494-9384-D28A651D70BB}.Debug|x64.ActiveCfg = Debug|x64
{81DAEE3A-76FF-4494-9384-D28A651D70BB}.Debug|x64.Build.0 = Debug|x64
{81DAEE3A-76FF-4494-9384-D28A651D70BB}.Debug|x64.Deploy.0 = Debug|x64
{81DAEE3A-76FF-4494-9384-D28A651D70BB}.Debug|x86.ActiveCfg = Debug|x86
{81DAEE3A-76FF-4494-9384-D28A651D70BB}.Debug|x86.Build.0 = Debug|x86
{81DAEE3A-76FF-4494-9384-D28A651D70BB}.Debug|x86.Deploy.0 = Debug|x86
{81DAEE3A-76FF-4494-9384-D28A651D70BB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{81DAEE3A-76FF-4494-9384-D28A651D70BB}.Release|Any CPU.Build.0 = Release|Any CPU
{81DAEE3A-76FF-4494-9384-D28A651D70BB}.Release|Any CPU.Deploy.0 = Release|Any CPU
{81DAEE3A-76FF-4494-9384-D28A651D70BB}.Release|ARM.ActiveCfg = Release|ARM
{81DAEE3A-76FF-4494-9384-D28A651D70BB}.Release|ARM.Build.0 = Release|ARM
{81DAEE3A-76FF-4494-9384-D28A651D70BB}.Release|ARM.Deploy.0 = Release|ARM
{81DAEE3A-76FF-4494-9384-D28A651D70BB}.Release|ARM64.ActiveCfg = Release|ARM64
{81DAEE3A-76FF-4494-9384-D28A651D70BB}.Release|ARM64.Build.0 = Release|ARM64
{81DAEE3A-76FF-4494-9384-D28A651D70BB}.Release|ARM64.Deploy.0 = Release|ARM64
{81DAEE3A-76FF-4494-9384-D28A651D70BB}.Release|x64.ActiveCfg = Release|x64
{81DAEE3A-76FF-4494-9384-D28A651D70BB}.Release|x64.Build.0 = Release|x64
{81DAEE3A-76FF-4494-9384-D28A651D70BB}.Release|x64.Deploy.0 = Release|x64
{81DAEE3A-76FF-4494-9384-D28A651D70BB}.Release|x86.ActiveCfg = Release|x86
{81DAEE3A-76FF-4494-9384-D28A651D70BB}.Release|x86.Build.0 = Release|x86
{81DAEE3A-76FF-4494-9384-D28A651D70BB}.Release|x86.Deploy.0 = Release|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE