Compare commits
31 Commits
v6.0.0.0-b
...
v6.0.1.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cadc5d65cf | ||
|
|
3e2f104aa7 | ||
|
|
c87ce3b66f | ||
|
|
3093dd43a4 | ||
|
|
061bb39b60 | ||
|
|
d994c79d5d | ||
|
|
9ca66db07b | ||
|
|
4a382d4e29 | ||
|
|
69a5ba4470 | ||
|
|
4a890a4da7 | ||
|
|
023c1db417 | ||
|
|
7ef1f9315e | ||
|
|
a148c88435 | ||
|
|
f6ad169f9d | ||
|
|
e69a5559e8 | ||
|
|
500fe9abc4 | ||
|
|
55f4a340af | ||
|
|
b17ed3675e | ||
|
|
34031fa15d | ||
|
|
d6d31d8ae9 | ||
|
|
0bfee26418 | ||
|
|
71d6b96c10 | ||
|
|
d1b7250a7a | ||
|
|
39b81d0664 | ||
|
|
6337818dbc | ||
|
|
2257af6294 | ||
|
|
572257b645 | ||
|
|
6eb82b6b7e | ||
|
|
7ef703da42 | ||
|
|
f7f8aa550a | ||
|
|
8d693b5e01 |
@@ -1,4 +1,33 @@
|
||||
|
||||
# 6.0.1.0
|
||||
|
||||
- New tutorial: [Extending mpv and mpv.net via Lua scripting](https://github.com/stax76/mpv.net/wiki/Extending-mpv-and-mpv.net-via-Lua-scripting)
|
||||
- New options `autofit-image` and `autofit-audio`, like autofit, but used for image and audio files.
|
||||
- New [auto-mode](https://github.com/stax76/mpv-scripts) script to use mpv and mpv.net as image viewer and audio player.
|
||||
- New [smart-volume](https://github.com/stax76/mpv-scripts) script. Records the volume per file in order to restore it
|
||||
in future sessions. What is recorded and restored is the volume offset relative to the session average volume.
|
||||
- New support of the mpv option `snap-window`.
|
||||
- New feature to show chapters in the command palette, see binding and menu definition below.
|
||||
- New option minimum-aspect-ratio-audio, same as minimum-aspect-ratio but used for audio files.
|
||||
- Fix long commands causing key bindings not visible in the command palette.
|
||||
- Fix script compatibility with mordenx and mpv-osc-tethys.
|
||||
- Fix borderless window not resizable with mouse.
|
||||
- Fix start-size=session not working.
|
||||
- Fix chapters that are script created after the media file is loaded.
|
||||
- Width of command palette slightly increased.
|
||||
- The default key bindings for 0 and 9 change the volume, like mpv.
|
||||
- When a menu item is defined multiple times with different key bindings,
|
||||
only one menu item is created, it shows all bindings.
|
||||
- libmpv zhongfly 2022-06-19
|
||||
|
||||
input.conf changes:
|
||||
|
||||
New:
|
||||
|
||||
```
|
||||
Ctrl+c script-message-to mpvnet show-chapters #menu: View > Show Chapters
|
||||
```
|
||||
|
||||
# 6.0.0.0 Beta (2022-06-05)
|
||||
|
||||
- The options `cache` and `demuxer-max-bytes`have been added
|
||||
|
||||
@@ -282,6 +282,9 @@ Registers the file associations.
|
||||
### scale-window \<factor\>
|
||||
Decreases or increases the Window size.
|
||||
|
||||
### select-profile
|
||||
Shows the command palette to select a profile.
|
||||
|
||||
### shell-execute \<file|URL\>
|
||||
Shell executes a single file or URL.
|
||||
|
||||
@@ -295,6 +298,9 @@ Shows available audio devices in a message box.
|
||||
Shows available audio tracks in the command palette
|
||||
and allows to load the selected audio track.
|
||||
|
||||
### show-chapters
|
||||
Shows chapters in the command palette.
|
||||
|
||||
### show-command-palette
|
||||
Shows the command palette.
|
||||
|
||||
@@ -381,6 +387,12 @@ mpv.net specific options can be found in the conf editor searching for 'mpv.net'
|
||||
|
||||
The options are saved in the mpvnet.conf file.
|
||||
|
||||
#### --autofit-audio \<integer\>
|
||||
Initial window height in percent for audio files. Default: 70
|
||||
|
||||
#### --autofit-image \<integer\>
|
||||
Initial window height in percent for image files. Default: 80
|
||||
|
||||
#### --queue \<files\>
|
||||
|
||||
Adds files to the playlist, requires [--process-instance=single](#--process-instancevalue).
|
||||
@@ -425,22 +437,24 @@ 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
|
||||
Minimum aspect ratio of the window. Useful to force
|
||||
a wider window and therefore a larger OSC.
|
||||
|
||||
#### --minimum-aspect-ratio-audio=\<float\>
|
||||
|
||||
Same as minimum-aspect-ratio but used for audio files.
|
||||
|
||||
#### --remember-window-position=\<yes|no\>
|
||||
|
||||
Save the window position on exit. Default: no
|
||||
|
||||
#### --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
|
||||
|
||||
### Playback
|
||||
|
||||
@@ -532,7 +546,7 @@ Draws the blue mpv.net logo ontop of the native OSC logo. Default: yes
|
||||
#### --show-santa-logo=\<yes|no\>
|
||||
|
||||
Draws the blue mpv.net logo with a santa hat in december,
|
||||
the option is called green and grumpy in mpv. Default: yes
|
||||
the option is called greenandgrumpy in mpv. Default: yes
|
||||
|
||||
External Tools
|
||||
--------------
|
||||
@@ -598,64 +612,28 @@ Scripting
|
||||
|
||||
#### Lua
|
||||
|
||||
File Type: `lua`
|
||||
A very large collection of Lua user scripts can be found in the mpv wiki [here](https://github.com/mpv-player/mpv/wiki/User-Scripts).
|
||||
|
||||
Location: `<config folder>\scripts`
|
||||
|
||||
The Lua script host is built into libmpv.
|
||||
|
||||
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 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)
|
||||
Lua scripting is documented in the mpv.net wiki [here](https://github.com/stax76/mpv.net/wiki/Extending-mpv-and-mpv.net-via-Lua-scripting).
|
||||
|
||||
#### JavaScript
|
||||
|
||||
File Type: `js`
|
||||
|
||||
Location: `<config folder>\scripts`
|
||||
|
||||
The JavaScript script host is built into libmpv.
|
||||
|
||||
Error and debug messages are printed on the terminal.
|
||||
|
||||
JavaScript scripts are loaded before the first media file loads.
|
||||
|
||||
[mpv JavaScript documentation](https://mpv.io/manual/master/#javascript)
|
||||
|
||||
[mpv user scripts](https://github.com/mpv-player/mpv/wiki/User-Scripts)
|
||||
|
||||
|
||||
#### PowerShell
|
||||
|
||||
File Type: `ps1`
|
||||
|
||||
Location: `<config folder>\scripts-ps`
|
||||
|
||||
The PowerShell scripting host is like extensions not
|
||||
initialized before media files are loaded.
|
||||
|
||||
mpv.net does not define scripting interfaces but instead exposed
|
||||
its complete internals, there are no compatibility guaranties.
|
||||
The PowerShell scripting host is not initialized before media files are loaded.
|
||||
|
||||
[Example Scripts](../../../tree/master/src/Scripts)
|
||||
|
||||
|
||||
#### C#
|
||||
|
||||
File Type: `cs`
|
||||
|
||||
Location: `<config folder>\scripts-cs`
|
||||
|
||||
mpv.net does not define scripting interfaces but instead exposed
|
||||
its complete internals, there are no compatibility guaranties.
|
||||
There are no compatibility guaranties.
|
||||
|
||||
Script code can be written within a C# [extension](../../../tree/master/src/Extensions),
|
||||
that way full code completion and debugger support is available.
|
||||
@@ -664,6 +642,10 @@ from the extension to a lightweight standalone script.
|
||||
The script host uses an old C# version, modern features
|
||||
like string interpolation are not available.
|
||||
|
||||
There are synchronous and asynchronous events, prefer asynchronous events
|
||||
and don't block synchronous events and observed properties, as it would
|
||||
block the main event loop.
|
||||
|
||||
The C# scripting host is like [extensions](../../../tree/master/src/Extensions)
|
||||
not initialized before media files are loaded.
|
||||
|
||||
@@ -680,9 +662,9 @@ and the filename must have the same name as the directory:
|
||||
<config folder>\extensions\ExampleExtension\ExampleExtension.dll
|
||||
```
|
||||
|
||||
mpv.net does not define extension interfaces but instead exposed
|
||||
its complete internals, there are no compatibility guaranties.
|
||||
|
||||
There are synchronous and asynchronous events, prefer asynchronous events
|
||||
and don't block synchronous events and observed properties, as it would
|
||||
block the main event loop.
|
||||
|
||||
### Walkthrough creating an extension
|
||||
|
||||
@@ -789,6 +771,7 @@ https://mpv.io/manual/master/#window
|
||||
- [keepaspect-window](https://mpv.io/manual/master/#options-keepaspect-window)
|
||||
- [ontop](https://mpv.io/manual/master/#options-ontop)
|
||||
- [screen](https://mpv.io/manual/master/#options-screen)
|
||||
- [snap-window](https://mpv.io/manual/master/#options-snap-window)
|
||||
- [title](https://mpv.io/manual/master/#options-title)
|
||||
- [window-maximized](https://mpv.io/manual/master/#options-window-maximized)
|
||||
- [window-minimized](https://mpv.io/manual/master/#options-window-minimized)
|
||||
@@ -798,8 +781,11 @@ https://mpv.io/manual/master/#window
|
||||
**Partly implemented are:**
|
||||
|
||||
- [autofit-larger](https://mpv.io/manual/master/#options-autofit-larger)
|
||||
Supported is a single integer value in the range 0-100.
|
||||
- [autofit-smaller](https://mpv.io/manual/master/#options-autofit-smaller)
|
||||
Supported is a single integer value in the range 0-100.
|
||||
- [autofit](https://mpv.io/manual/master/#options-autofit)
|
||||
Supported is a single integer value in the range 0-100.
|
||||
|
||||
mpv.net specific window features are documented in the [screen section](#screen).
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
mpv.net手册
|
||||
==============
|
||||
|
||||
适配版本 [v5.9.0.0-beta](https://github.com/stax76/mpv.net/releases/tag/v5.9.0.0-beta)
|
||||
适配版本 [v6.0.0.0-beta](https://github.com/stax76/mpv.net/releases/tag/v6.0.0.0-beta)
|
||||
|
||||
**[ENGLISH](Manual.md)** | **简体中文**
|
||||
|
||||
@@ -62,8 +62,10 @@ mpv专注命令行与终端的使用,而mpv.net保留了这些并加入了现
|
||||
|
||||
mpv.net需要.NET Framework 4.8运行库和高于win7版本的系统以及一张不太旧的显卡。
|
||||
|
||||
对于来自YouTube和类似网站的网络流,必须将yt-dlp复制到mpv.net的文件夹中,
|
||||
或编辑用户环境变量PATH,使其包括yt-dlp的文件夹。
|
||||
互联网流媒体需要:
|
||||
|
||||
- 下载[yt-dlp](https://github.com/yt-dlp/yt-dlp)并将其添加到[用户环境变量PATH](https://www.google.com/search?q=user+environment+variable+PATH);
|
||||
- 在使用代理服务器的情况下,需要[手动配置](https://github.com/stax76/mpv.net/issues/401)。
|
||||
|
||||
#### 文件关联
|
||||
|
||||
@@ -215,7 +217,7 @@ mpv有一些基于非属性的开关,在mpv.net中一般不受支持。
|
||||
mpv.net的专属命令
|
||||
-------------------------
|
||||
|
||||
`script-message mpv.net <command> <arguments>`
|
||||
`script-message-to mpvnet <command> <arguments>`
|
||||
|
||||
mpv.net命令可在mpv命令不存在或缺乏某种功能时使用。
|
||||
|
||||
@@ -232,14 +234,11 @@ mpv.net命令可在mpv命令不存在或缺乏某种功能时使用。
|
||||
用Windows资源管理器打开配置文件夹。
|
||||
|
||||
### open-files [\<flags\>]
|
||||
**no-folder**
|
||||
对于单个文件,防止将文件夹内的全部文件加载到播放列表中。
|
||||
|
||||
**append**
|
||||
追加文件到播放列表中。
|
||||
|
||||
打开一个资源管理器的对话框,以便选择要打开的文件。资源管理器的对话框支持多选以
|
||||
一次性加载多个文件。按住CTRL键可以将这些文件追加到播放列表中。
|
||||
打开一个资源管理器的对话框,以便选择要打开的文件。资源管理器的对话框
|
||||
支持多选以一次性加载多个文件。按住CTRL键可以将这些文件追加到播放列表中。
|
||||
|
||||
### open-optical-media
|
||||
显示一个资源管理器的对话框来打开一个DVD或BD文件夹。ISO镜像不需要被挂载,
|
||||
@@ -260,6 +259,10 @@ mpv.net命令可在mpv命令不存在或缺乏某种功能时使用。
|
||||
### playlist-last
|
||||
跳转到播放列表的最后一个条目,如果加载的文件已经是最后一个条目,则无动作。
|
||||
|
||||
### quick-bookmark
|
||||
第一次触发时,书签被保存,第二次触发时,它被恢复并移除。当加载新文件时,
|
||||
书签也会被移除。
|
||||
|
||||
### reg-file-assoc \<audio|video|image\>
|
||||
注册文件关联。
|
||||
|
||||
@@ -297,7 +300,7 @@ Shell执行单个文件或URL。
|
||||
显示已有的历史文件。
|
||||
|
||||
### show-info
|
||||
显示一个简易的文件信息。
|
||||
在屏幕上显示mediainfo,第二次触发可显示更详细的媒体信息。
|
||||
|
||||
### show-input-editor
|
||||
显示器快捷键编辑器。
|
||||
@@ -312,6 +315,9 @@ Shell执行单个文件或URL。
|
||||
**editor**
|
||||
在一个文本编辑器中显示mediainfo
|
||||
|
||||
**osd**
|
||||
OSD上显示mediainfo
|
||||
|
||||
**full**
|
||||
显示mediainfo的完整细节
|
||||
|
||||
@@ -328,7 +334,7 @@ Shell执行单个文件或URL。
|
||||
用一个信息框显示可用的profile
|
||||
|
||||
### show-progress
|
||||
显示一个简易的OSD进度条信息。
|
||||
显示一个简易的OSD进度条信息,附带时间和日期。
|
||||
|
||||
### show-properties
|
||||
在命令面板中显示可用的属性,并允许显示所选属性的值。
|
||||
@@ -363,8 +369,8 @@ mpv.net的专属选项
|
||||
|
||||
#### --command=\<input command\>
|
||||
|
||||
通过命令行向正在运行的mpv.net实例发送输入命令,例如使用 AutoHotkey 创建全局热键,
|
||||
必须设置 [process-instance=single](#--process-instancevalue) 。
|
||||
通过命令行向正在运行的mpv.net实例发送输入命令,例如使用 AutoHotkey 创建
|
||||
全局热键,必须设置 [process-instance=single](#--process-instancevalue) 。
|
||||
|
||||
### Audio
|
||||
|
||||
@@ -430,12 +436,6 @@ mpv.net的专属选项
|
||||
如果在播放器暂停时,加载另一个文件,会自动恢复播放。
|
||||
|
||||
|
||||
#### --keep-open-exit
|
||||
|
||||
如果设置为yes并且keep-open设置为no,mpv.net将在播完最后一个文件后退出。
|
||||
在mpv中可以使用idle属性,但对mpv.net来说不可能实现它。
|
||||
|
||||
|
||||
### General
|
||||
|
||||
#### --process-instance=\<value\>
|
||||
@@ -460,6 +460,11 @@ mpv.net的专属选项
|
||||
最近文件的记录数量。默认:15
|
||||
|
||||
|
||||
#### --media-info=\<yes|no\>
|
||||
|
||||
使用MediaInfo而不是mpv来访问媒体信息。默认:yes
|
||||
|
||||
|
||||
#### --video-file-extensions=\<string\>
|
||||
|
||||
用于创建文件关联的视频文件扩展名,由自动加载文件夹的功能使用。
|
||||
@@ -512,7 +517,12 @@ mpv.net的专属选项
|
||||
|
||||
#### --show-logo=\<yes|no\>
|
||||
|
||||
在原始OSC标志的基础上绘制蓝色的mpvnet图标。更改将在应用程序重新启动后生效。默认:yes
|
||||
在原始OSC标志的基础上绘制蓝色的mpvnet图标。默认:yes
|
||||
|
||||
|
||||
#### --show-santa-logo=\<yes|no\>
|
||||
|
||||
在12月绘制蓝色的mpvnet图标时使用圣诞彩蛋。默认:yes
|
||||
|
||||
|
||||
外部工具
|
||||
@@ -642,9 +652,10 @@ mpv.net没有定义脚本接口,而是公开了它的完整内部,没有兼
|
||||
|
||||
mpv.net没有定义脚本接口,而是公开了它的完整内部,没有兼容性保证。
|
||||
|
||||
脚本代码可以在C#[扩展](../../../tree/master/src/Extensions)中编写,这样就可以获得
|
||||
完整的代码和调试器支持。一旦代码被调试和开发完成,就可以将其从扩展转移到轻量级的独立脚本。
|
||||
脚本host使用的是旧的C#版本,像字符串插值这样的现代功能是不存在的。
|
||||
脚本代码可以在C#[扩展](../../../tree/master/src/Extensions)中编写,这样
|
||||
就可以获得完整的代码和调试器支持。一旦代码被调试和开发完成,就可以将其
|
||||
从扩展转移到轻量级的独立脚本。脚本host使用的是旧的C#版本,像字符串插值
|
||||
这样的现代功能是不存在的。
|
||||
|
||||
C#脚本的host类似于[扩展](../../../tree/master/src/Extensions),在打开媒体文件前尚未初始化。
|
||||
|
||||
@@ -789,6 +800,13 @@ mpv.net支持基于属性的mpv命令行选项,这意味着它支持mpv几乎
|
||||
--version
|
||||
|
||||
|
||||
### 其它限制
|
||||
|
||||
mpv的属性 [idle](https://mpv.io/manual/master/#options-idle) 在mpv.net中
|
||||
也会相应的发挥作用,但是LUA脚本获取到的值始终是 `yes` ,因为mpv.net必须
|
||||
设置它才能正常工作,这是一个难以攻克的来自libmpv的限制。
|
||||
|
||||
|
||||
### mpv.net的专属选项
|
||||
|
||||
在config editor中输入 `mpv.net` 检索这些选项,在[此处](#mpvnet的专属选项)的手册中有对应说明。
|
||||
@@ -1481,8 +1499,8 @@ input.conf 文件内涵mpv的键鼠绑定
|
||||
|
||||
### Tools > Show History
|
||||
|
||||
显示包含历史记录的文本文件。如果文件不存在,则会询问是否在设置文件夹中创建该文件。
|
||||
一旦文件存在,则写入历史记录(包括时间和文件名)
|
||||
显示包含历史记录的文本文件。如果文件不存在,则会询问是否在设置文件夹中
|
||||
创建该文件。一旦文件存在,则写入历史记录(包括时间和文件名)
|
||||
|
||||
屏蔽部分路径的参数:
|
||||
|
||||
|
||||
@@ -36,7 +36,10 @@ namespace mpvnet
|
||||
public static int StartThreshold { get; set; } = 1500;
|
||||
public static int RecentCount { get; set; } = 15;
|
||||
|
||||
public static float MinimumAspectRatio { get; set; } = 1.2f;
|
||||
public static float AutofitAudio { get; set; } = 0.7f;
|
||||
public static float AutofitImage { get; set; } = 0.8f;
|
||||
public static float MinimumAspectRatio { get; set; }
|
||||
public static float MinimumAspectRatioAudio { get; set; }
|
||||
public static float QuickBookmark { get; set; }
|
||||
|
||||
public static Extension Extension { get; set; }
|
||||
@@ -241,6 +244,8 @@ namespace mpvnet
|
||||
case "audio-file-extensions": CorePlayer.AudioTypes = value.Split(" ,;".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); return true;
|
||||
case "auto-load-folder": AutoLoadFolder = value == "yes"; return true;
|
||||
case "auto-play": AutoPlay = value == "yes"; return true;
|
||||
case "autofit-image": AutofitImage = value.Trim('%').ToInt() / 100f; return true;
|
||||
case "autofit-audio": AutofitAudio = value.Trim('%').ToInt() / 100f; return true;
|
||||
case "dark-mode": DarkMode = value; return true;
|
||||
case "dark-theme": DarkTheme = value.Trim('\'', '"'); return true;
|
||||
case "debug-mode": DebugMode = value == "yes"; return true;
|
||||
@@ -248,6 +253,7 @@ namespace mpvnet
|
||||
case "light-theme": LightTheme = value.Trim('\'', '"'); return true;
|
||||
case "media-info": MediaInfo = value == "yes"; return true;
|
||||
case "minimum-aspect-ratio": MinimumAspectRatio = value.ToFloat(); return true;
|
||||
case "minimum-aspect-ratio-audio": MinimumAspectRatioAudio = value.ToFloat(); return true;
|
||||
case "process-instance": ProcessInstance = value; return true;
|
||||
case "queue": Queue = value == "yes"; return true;
|
||||
case "recent-count": RecentCount = value.ToInt(); return true;
|
||||
|
||||
@@ -46,6 +46,7 @@ namespace mpvnet
|
||||
case "show-about": ShowDialog(typeof(AboutWindow)); break;
|
||||
case "show-audio-devices": Msg.ShowInfo(Core.GetPropertyOsdString("audio-device-list")); break;
|
||||
case "show-audio-tracks": ShowAudioTracks(); break;
|
||||
case "show-chapters": ShowChapters(); break;
|
||||
case "show-command-palette": ShowCommandPalette(); break;
|
||||
case "show-commands": ShowCommands(); break;
|
||||
case "show-conf-editor": ShowDialog(typeof(ConfWindow)); break;
|
||||
@@ -170,81 +171,33 @@ namespace mpvnet
|
||||
|
||||
LastShowInfo = Environment.TickCount;
|
||||
|
||||
string performer, title, album, genre, date, duration, text = "";
|
||||
string text;
|
||||
long fileSize = 0;
|
||||
string path = Core.GetPropertyString("path");
|
||||
|
||||
if (path.Contains("://"))
|
||||
path = Core.GetPropertyString("media-title");
|
||||
|
||||
if (File.Exists(path))
|
||||
{
|
||||
fileSize = new FileInfo(path).Length;
|
||||
|
||||
if (CorePlayer.AudioTypes.Contains(path.Ext()))
|
||||
{
|
||||
if (App.MediaInfo)
|
||||
{
|
||||
using (MediaInfo mediaInfo = new MediaInfo(path))
|
||||
{
|
||||
performer = mediaInfo.GetInfo(MediaInfoStreamKind.General, "Performer");
|
||||
title = mediaInfo.GetInfo(MediaInfoStreamKind.General, "Title");
|
||||
album = mediaInfo.GetInfo(MediaInfoStreamKind.General, "Album");
|
||||
genre = mediaInfo.GetInfo(MediaInfoStreamKind.General, "Genre");
|
||||
date = mediaInfo.GetInfo(MediaInfoStreamKind.General, "Recorded_Date");
|
||||
duration = mediaInfo.GetInfo(MediaInfoStreamKind.Audio, "Duration/String");
|
||||
|
||||
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";
|
||||
|
||||
text += "Size: " + mediaInfo.GetInfo(MediaInfoStreamKind.General, "FileSize/String") + "\n";
|
||||
text += "Type: " + path.Ext().ToUpper();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
text = "File: " + path.FileName() + "\n";
|
||||
duration = TimeSpan.FromSeconds((int)Core.GetPropertyDouble("duration")).ToString();
|
||||
|
||||
if (duration != "") text += "Length: " + duration + "\n";
|
||||
if (fileSize > 0) text += "Size: " + Convert.ToInt32(fileSize / 1024.0 / 1024.0) + " MB\n";
|
||||
|
||||
text += "Type: " + path.Ext().ToUpper();
|
||||
}
|
||||
|
||||
text = Core.GetPropertyOsdString("filtered-metadata");
|
||||
Core.CommandV("show-text", text, "5000");
|
||||
return;
|
||||
|
||||
}
|
||||
else if (CorePlayer.ImageTypes.Contains(path.Ext()))
|
||||
{
|
||||
if (App.MediaInfo)
|
||||
{
|
||||
using (MediaInfo mediaInfo = new MediaInfo(path))
|
||||
{
|
||||
text = "Width: " + mediaInfo.GetInfo(MediaInfoStreamKind.Image, "Width") + "\n" +
|
||||
"Height: " + mediaInfo.GetInfo(MediaInfoStreamKind.Image, "Height") + "\n" +
|
||||
"Size: " + mediaInfo.GetInfo(MediaInfoStreamKind.General, "FileSize/String") + "\n" +
|
||||
"Type: " + path.Ext().ToUpper();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
text = "Width: " + Core.GetPropertyInt("width") + "\n" +
|
||||
"Height: " + Core.GetPropertyInt("height") + "\n" +
|
||||
"Size: " + Convert.ToInt32(fileSize / 1024.0) + " KB\n" +
|
||||
"Type: " + path.Ext().ToUpper();
|
||||
}
|
||||
|
||||
Core.CommandV("show-text", text, "5000");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (path.Contains("://")) path = Core.GetPropertyString("media-title");
|
||||
string videoFormat = Core.GetPropertyString("video-format").ToUpper();
|
||||
string audioCodec = Core.GetPropertyString("audio-codec-name").ToUpper();
|
||||
int width = Core.GetPropertyInt("video-params/w");
|
||||
@@ -255,7 +208,6 @@ namespace mpvnet
|
||||
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");
|
||||
}
|
||||
|
||||
@@ -718,6 +670,16 @@ namespace mpvnet
|
||||
CommandPalette.Instance.SelectFirst();
|
||||
});
|
||||
|
||||
public static void ShowChapters() => App.InvokeOnMainThread(() =>
|
||||
{
|
||||
var items = Core.GetChapters().Select(i => new CommandPaletteItem(i.Title, i.TimeDisplay, () =>
|
||||
Core.CommandV("seek", i.Time.ToString(CultureInfo.InvariantCulture), "absolute")));
|
||||
|
||||
CommandPalette.Instance.SetItems(items);
|
||||
MainForm.Instance.ShowCommandPalette();
|
||||
CommandPalette.Instance.SelectFirst();
|
||||
});
|
||||
|
||||
public static void ShowMenu() => Core.RaiseShowMenu();
|
||||
|
||||
public static void PlaylistAdd(int value)
|
||||
|
||||
@@ -146,7 +146,19 @@ namespace mpvnet
|
||||
|
||||
public string Path { get; set; } = "";
|
||||
public string Command { get; set; } = "";
|
||||
public string Display { get { return string.IsNullOrEmpty(Path) ? Command : Path; } }
|
||||
|
||||
public string Display {
|
||||
get {
|
||||
if (string.IsNullOrEmpty(Path))
|
||||
{
|
||||
if (Command.Length > 47)
|
||||
return Command.Substring(0, 47) + "...";
|
||||
return Command;
|
||||
}
|
||||
else
|
||||
return Path;
|
||||
}
|
||||
}
|
||||
|
||||
public CommandItem() { }
|
||||
|
||||
@@ -249,6 +261,13 @@ namespace mpvnet
|
||||
Action = action;
|
||||
}
|
||||
|
||||
public CommandPaletteItem(string text, string secondaryText, Action action)
|
||||
{
|
||||
Text = text;
|
||||
Action = action;
|
||||
SecondaryText = secondaryText;
|
||||
}
|
||||
|
||||
public string Text { get; set; } = "";
|
||||
public string SecondaryText { get; set; } = "";
|
||||
public Action Action { get; set; }
|
||||
@@ -271,4 +290,26 @@ namespace mpvnet
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public class Chapter
|
||||
{
|
||||
public string Title { get; set; }
|
||||
public double Time { get; set; }
|
||||
|
||||
string _TimeDisplay;
|
||||
|
||||
public string TimeDisplay {
|
||||
get {
|
||||
if (_TimeDisplay == null)
|
||||
{
|
||||
_TimeDisplay = TimeSpan.FromSeconds(Time).ToString();
|
||||
|
||||
if (_TimeDisplay.ContainsEx("."))
|
||||
_TimeDisplay = _TimeDisplay.Substring(0, _TimeDisplay.LastIndexOf("."));
|
||||
}
|
||||
|
||||
return _TimeDisplay;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,8 +21,8 @@ namespace mpvnet
|
||||
public class CorePlayer
|
||||
{
|
||||
public static string[] VideoTypes { get; set; } = "264 265 asf avc avi avs dav flv h264 h265 hevc m2t m2ts m2v m4v mkv mov mp4 mpeg mpg mpv mts ts vob vpy webm wmv y4m".Split(' ');
|
||||
public static string[] AudioTypes { get; set; } = "aac ac3 dts dtshd dtshr dtsma eac3 flac m4a mka mp2 mp3 mpa mpc ogg opus thd thd+ac3 w64 wav".Split(' ');
|
||||
public static string[] ImageTypes { get; set; } = { "jpg", "bmp", "png", "gif" };
|
||||
public static string[] AudioTypes { get; set; } = "aac ac3 dts dtshd dtshr dtsma eac3 flac m4a mka mp2 mp3 mpa mpc ogg opus thd w64 wav".Split(' ');
|
||||
public static string[] ImageTypes { get; set; } = { "jpg", "bmp", "png", "gif", "webp" };
|
||||
public static string[] SubtitleTypes { get; } = { "srt", "ass", "idx", "sub", "sup", "ttxt", "txt", "ssa", "smi", "mks" };
|
||||
|
||||
public event Action<mpv_log_level, string> LogMessageAsync; // log-message MPV_EVENT_LOG_MESSAGE
|
||||
@@ -56,9 +56,9 @@ namespace mpvnet
|
||||
public event Action InitializedAsync;
|
||||
public event Action Pause;
|
||||
public event Action ShowMenu;
|
||||
public event Action<double> WindowScaleMpv;
|
||||
public event Action<float> ScaleWindow;
|
||||
public event Action<float> WindowScaleNET;
|
||||
public event Action<double> WindowScaleMpv;
|
||||
public event Action<int> PlaylistPosChanged;
|
||||
public event Action<int> PlaylistPosChangedAsync;
|
||||
public event Action<Size> VideoSizeChanged;
|
||||
@@ -70,23 +70,21 @@ namespace mpvnet
|
||||
public Dictionary<string, List<Action<double>>> DoublePropChangeActions { get; set; } = new Dictionary<string, List<Action<double>>>();
|
||||
public Dictionary<string, List<Action<string>>> StringPropChangeActions { get; set; } = new Dictionary<string, List<Action<string>>>();
|
||||
|
||||
public List<MediaTrack> MediaTracks { get; set; } = new List<MediaTrack>();
|
||||
public object MediaTracksLock { get; } = new object();
|
||||
public List<KeyValuePair<string, double>> Chapters { get; set; } = new List<KeyValuePair<string, double>>();
|
||||
public List<TimeSpan> BluRayTitles { get; } = new List<TimeSpan>();
|
||||
public AutoResetEvent ShutdownAutoResetEvent { get; } = new AutoResetEvent(false);
|
||||
public AutoResetEvent VideoSizeAutoResetEvent { get; } = new AutoResetEvent(false);
|
||||
public IntPtr Handle { get; set; }
|
||||
public IntPtr NamedHandle { get; set; }
|
||||
|
||||
public List<MediaTrack> MediaTracks { get; set; } = new List<MediaTrack>();
|
||||
public List<TimeSpan> BluRayTitles { get; } = new List<TimeSpan>();
|
||||
public object MediaTracksLock { get; } = new object();
|
||||
public Size VideoSize { get; set; }
|
||||
public TimeSpan Duration;
|
||||
|
||||
public AutoResetEvent ShutdownAutoResetEvent { get; } = new AutoResetEvent(false);
|
||||
public AutoResetEvent VideoSizeAutoResetEvent { get; } = new AutoResetEvent(false);
|
||||
|
||||
public string ConfPath { get => ConfigFolder + "mpv.conf"; }
|
||||
public string GPUAPI { get; set; } = "auto";
|
||||
public string VO { get; set; } = "gpu";
|
||||
public string InputConfPath => ConfigFolder + "input.conf";
|
||||
public string Path { get; set; } = "";
|
||||
public string VO { get; set; } = "gpu";
|
||||
|
||||
public string VID { get; set; } = "";
|
||||
public string AID { get; set; } = "";
|
||||
@@ -99,6 +97,7 @@ namespace mpvnet
|
||||
public bool KeepaspectWindow { get; set; }
|
||||
public bool Paused { get; set; }
|
||||
public bool Shown { get; set; }
|
||||
public bool SnapWindow { get; set; }
|
||||
public bool TaskbarProgress { get; set; } = true;
|
||||
public bool WasInitialSizeSet;
|
||||
public bool WindowMaximized { get; set; }
|
||||
@@ -130,7 +129,6 @@ namespace mpvnet
|
||||
{
|
||||
SetPropertyString("terminal", "yes");
|
||||
SetPropertyString("input-terminal", "yes");
|
||||
SetPropertyString("msg-level", "osd/libass=fatal");
|
||||
}
|
||||
|
||||
SetPropertyInt("osd-duration", 2000);
|
||||
@@ -149,6 +147,8 @@ namespace mpvnet
|
||||
|
||||
ProcessCommandLine(true);
|
||||
|
||||
Environment.SetEnvironmentVariable("MPVNET_VERSION", Application.ProductVersion);
|
||||
|
||||
mpv_error err = mpv_initialize(Handle);
|
||||
|
||||
if (err < 0)
|
||||
@@ -171,6 +171,7 @@ namespace mpvnet
|
||||
SetPropertyString("idle", "yes");
|
||||
|
||||
ObservePropertyDouble("window-scale", value => WindowScaleMpv(value));
|
||||
ObservePropertyString("path", value => Path = value);
|
||||
|
||||
ObservePropertyBool("pause", value => {
|
||||
Paused = value;
|
||||
@@ -249,27 +250,34 @@ namespace mpvnet
|
||||
switch (name)
|
||||
{
|
||||
case "autofit":
|
||||
{
|
||||
if (int.TryParse(value.Trim('%'), out int result))
|
||||
Autofit = result / 100f;
|
||||
}
|
||||
break;
|
||||
case "autofit-smaller":
|
||||
if (int.TryParse(value.Trim('%'), out int result2))
|
||||
AutofitSmaller = result2 / 100f;
|
||||
{
|
||||
if (int.TryParse(value.Trim('%'), out int result))
|
||||
AutofitSmaller = result / 100f;
|
||||
}
|
||||
break;
|
||||
case "autofit-larger":
|
||||
if (int.TryParse(value.Trim('%'), out int result3))
|
||||
AutofitLarger = result3 / 100f;
|
||||
{
|
||||
if (int.TryParse(value.Trim('%'), out int result))
|
||||
AutofitLarger = result / 100f;
|
||||
}
|
||||
break;
|
||||
case "border": Border = value == "yes"; break;
|
||||
case "fs":
|
||||
case "fullscreen": Fullscreen = value == "yes"; break;
|
||||
case "border": Border = value == "yes"; break;
|
||||
case "gpu-api": GPUAPI = value; break;
|
||||
case "keepaspect-window": KeepaspectWindow = value == "yes"; break;
|
||||
case "screen": Screen = Convert.ToInt32(value); break;
|
||||
case "snap-window": SnapWindow = value == "yes"; break;
|
||||
case "taskbar-progress": TaskbarProgress = value == "yes"; break;
|
||||
case "vo": VO = value; break;
|
||||
case "window-maximized": WindowMaximized = value == "yes"; break;
|
||||
case "window-minimized": WindowMinimized = value == "yes"; break;
|
||||
case "taskbar-progress": TaskbarProgress = value == "yes"; break;
|
||||
case "screen": Screen = Convert.ToInt32(value); break;
|
||||
case "gpu-api": GPUAPI = value; break;
|
||||
case "vo": VO = value; break;
|
||||
}
|
||||
|
||||
if (AutofitLarger > 1)
|
||||
@@ -331,7 +339,7 @@ namespace mpvnet
|
||||
{
|
||||
File.WriteAllText(_ConfigFolder + "input.conf", Properties.Resources.input_conf);
|
||||
|
||||
string scriptOptsPath = _ConfigFolder + "script-opts" + Path.DirectorySeparatorChar;
|
||||
string scriptOptsPath = _ConfigFolder + "script-opts" + System.IO.Path.DirectorySeparatorChar;
|
||||
|
||||
if (!Directory.Exists(scriptOptsPath))
|
||||
{
|
||||
@@ -436,7 +444,7 @@ namespace mpvnet
|
||||
ps.Scripts.Add(eventCode);
|
||||
ps.Scripts.Add(propertyChangedCode);
|
||||
ps.Scripts.Add(File.ReadAllText(file));
|
||||
ps.Module = Path.GetFileName(file);
|
||||
ps.Module = System.IO.Path.GetFileName(file);
|
||||
ps.Print = true;
|
||||
|
||||
lock (PowerShell.References)
|
||||
@@ -1193,7 +1201,7 @@ namespace mpvnet
|
||||
LoadISO(file);
|
||||
else if(SubtitleTypes.Contains(file.Ext()))
|
||||
CommandV("sub-add", file);
|
||||
else if (file.Ext().Length != 3 && File.Exists(Path.Combine(file, "BDMV\\index.bdmv")))
|
||||
else if (file.Ext().Length != 3 && File.Exists(System.IO.Path.Combine(file, "BDMV\\index.bdmv")))
|
||||
{
|
||||
Command("stop");
|
||||
Thread.Sleep(500);
|
||||
@@ -1282,7 +1290,7 @@ namespace mpvnet
|
||||
path = path.Replace("/", "\\");
|
||||
|
||||
if (path.Contains("\\"))
|
||||
dir = Path.GetDirectoryName(path);
|
||||
dir = System.IO.Path.GetDirectoryName(path);
|
||||
|
||||
List<string> files = Directory.GetFiles(dir).ToList();
|
||||
|
||||
@@ -1386,6 +1394,10 @@ namespace mpvnet
|
||||
|
||||
void HideLogo() => Command("overlay-remove 0");
|
||||
|
||||
public bool IsImage => ImageTypes.Contains(Path.Ext());
|
||||
|
||||
public bool IsAudio => AudioTypes.Contains(Path.Ext());
|
||||
|
||||
string GetLanguage(string id)
|
||||
{
|
||||
foreach (CultureInfo ci in CultureInfo.GetCultures(CultureTypes.NeutralCultures))
|
||||
@@ -1437,23 +1449,26 @@ namespace mpvnet
|
||||
else
|
||||
MediaTracks = GetTracks();
|
||||
}
|
||||
}
|
||||
|
||||
lock (Chapters)
|
||||
{
|
||||
Chapters.Clear();
|
||||
public List<Chapter> GetChapters() {
|
||||
List<Chapter> chapters = new List<Chapter>();
|
||||
int count = GetPropertyInt("chapter-list/count");
|
||||
|
||||
for (int x = 0; x < count; x++)
|
||||
{
|
||||
string text = GetPropertyString($"chapter-list/{x}/title");
|
||||
string title = GetPropertyString($"chapter-list/{x}/title");
|
||||
double time = GetPropertyDouble($"chapter-list/{x}/time");
|
||||
|
||||
if (string.IsNullOrEmpty(text))
|
||||
text = "Chapter " + (x + 1);
|
||||
if (string.IsNullOrEmpty(title) ||
|
||||
(title.Length == 12 && title.Contains(":") && title.Contains(".")))
|
||||
|
||||
Chapters.Add(new KeyValuePair<string, double>(text, time));
|
||||
}
|
||||
title = "Chapter " + (x + 1);
|
||||
|
||||
chapters.Add(new Chapter() { Title = title, Time = time });
|
||||
}
|
||||
|
||||
return chapters;
|
||||
}
|
||||
|
||||
public void UpdateExternalTracks()
|
||||
@@ -1598,7 +1613,7 @@ namespace mpvnet
|
||||
Add(track, fps + " FPS");
|
||||
Add(track, mi.GetVideo(i, "Language/String"));
|
||||
Add(track, mi.GetVideo(i, "Forced") == "Yes" ? "Forced" : "");
|
||||
Add(track, mi.GetVideo(i, "Default") == "Yes" ? "Default" : "");
|
||||
Add(track, (videoCount > 1 && mi.GetVideo(i, "Default") == "Yes") ? "Default" : "");
|
||||
Add(track, mi.GetVideo(i, "Title"));
|
||||
track.Text = "V: " + track.Text.Trim(' ', ',');
|
||||
track.Type = "v";
|
||||
@@ -1618,7 +1633,7 @@ namespace mpvnet
|
||||
Add(track, mi.GetAudio(i, "Channel(s)") + " ch");
|
||||
Add(track, mi.GetAudio(i, "SamplingRate/String"));
|
||||
Add(track, mi.GetAudio(i, "Forced") == "Yes" ? "Forced" : "");
|
||||
Add(track, mi.GetAudio(i, "Default") == "Yes" ? "Default" : "");
|
||||
Add(track, (audioCount > 1 && mi.GetAudio(i, "Default") == "Yes") ? "Default" : "");
|
||||
Add(track, mi.GetAudio(i, "Title"));
|
||||
track.Text = "A: " + track.Text.Trim(' ', ',');
|
||||
track.Type = "a";
|
||||
@@ -1643,7 +1658,7 @@ namespace mpvnet
|
||||
Add(track, codec);
|
||||
Add(track, mi.GetText(i, "Format_Profile"));
|
||||
Add(track, mi.GetText(i, "Forced") == "Yes" ? "Forced" : "");
|
||||
Add(track, mi.GetText(i, "Default") == "Yes" ? "Default" : "");
|
||||
Add(track, (subCount > 1 && mi.GetText(i, "Default") == "Yes") ? "Default" : "");
|
||||
Add(track, mi.GetText(i, "Title"));
|
||||
track.Text = "S: " + track.Text.Trim(' ', ',');
|
||||
track.Type = "s";
|
||||
|
||||
@@ -21,6 +21,9 @@ namespace mpvnet
|
||||
[DllImport("user32.dll")]
|
||||
public static extern uint ActivateKeyboardLayout(IntPtr hkl, uint flags);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
public static extern bool GetWindowRect(IntPtr hwnd, out RECT lpRect);
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
|
||||
public static extern IntPtr FindWindowEx(
|
||||
IntPtr parentHandle, IntPtr childAfter, string lclassName, string windowTitle);
|
||||
@@ -88,6 +91,37 @@ namespace mpvnet
|
||||
[DllImport("gdi32.dll")]
|
||||
public static extern int GetDeviceCaps(IntPtr hdc, int nIndex);
|
||||
|
||||
[DllImport("dwmapi.dll")]
|
||||
public static extern int DwmGetWindowAttribute(
|
||||
IntPtr hwnd, uint dwAttribute, out RECT pvAttribute, uint cbAttribute);
|
||||
|
||||
public static bool GetDwmWindowRect(IntPtr handle, out RECT rect)
|
||||
{
|
||||
const uint DWMWA_EXTENDED_FRAME_BOUNDS = 9;
|
||||
return 0 == DwmGetWindowAttribute(handle, DWMWA_EXTENDED_FRAME_BOUNDS, out rect, (uint)Marshal.SizeOf<RECT>());
|
||||
}
|
||||
|
||||
public static Rectangle GetWorkingArea(IntPtr handle, Rectangle workingArea)
|
||||
{
|
||||
if (handle != IntPtr.Zero && GetDwmWindowRect(handle, out RECT dwmRect) &&
|
||||
GetWindowRect(handle, out RECT rect))
|
||||
{
|
||||
int left = workingArea.Left;
|
||||
int top = workingArea.Top;
|
||||
int right = workingArea.Right;
|
||||
int bottom = workingArea.Bottom;
|
||||
|
||||
left += rect.Left - dwmRect.Left;
|
||||
top -= rect.Top - dwmRect.Top;
|
||||
right -= dwmRect.Right - rect.Right;
|
||||
bottom -= dwmRect.Bottom - rect.Bottom;
|
||||
|
||||
return new Rectangle(left, top, right - left, bottom - top);
|
||||
}
|
||||
|
||||
return workingArea;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct RECT
|
||||
{
|
||||
@@ -116,6 +150,16 @@ namespace mpvnet
|
||||
public Size Size => new Size(Right - Left, Bottom - Top);
|
||||
public int Width => Right - Left;
|
||||
public int Height => Bottom - Top;
|
||||
|
||||
public static RECT FromRectangle(Rectangle rect)
|
||||
{
|
||||
return new RECT(rect.X, rect.Y, rect.X + rect.Width, rect.Y + rect.Height);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return "{Left=" + Left + ",Top=" + Top + ",Right=" + Right + ",Bottom=" + Bottom + "}";
|
||||
}
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
|
||||
@@ -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("6.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("6.0.0.0")]
|
||||
[assembly: AssemblyVersion("6.0.1.0")]
|
||||
[assembly: AssemblyFileVersion("6.0.1.0")]
|
||||
|
||||
@@ -21,7 +21,7 @@ name = media-info
|
||||
file = mpvnet
|
||||
default = yes
|
||||
filter = General
|
||||
help = Usage of the media info library instead of mpv to access media information. Default: no (mpv.net specific option)
|
||||
help = Usage of the media info library instead of mpv to access media information. (mpv.net specific option)
|
||||
|
||||
option = yes
|
||||
option = no
|
||||
@@ -410,6 +410,18 @@ file = mpv
|
||||
filter = Screen
|
||||
help = <int> Initial window height in percent. Default: 60
|
||||
|
||||
[setting]
|
||||
name = autofit-image
|
||||
file = mpvnet
|
||||
filter = Screen
|
||||
help = <int> Initial window height in percent for image files. Default: 80
|
||||
|
||||
[setting]
|
||||
name = autofit-audio
|
||||
file = mpvnet
|
||||
filter = Screen
|
||||
help = <int> Initial window height in percent for audio files. Default: 70
|
||||
|
||||
[setting]
|
||||
name = autofit-smaller
|
||||
file = mpv
|
||||
@@ -447,17 +459,17 @@ help = keepaspect-window will lock the window size to the video aspect. Default:
|
||||
option = yes
|
||||
option = no
|
||||
|
||||
[setting]
|
||||
name = start-threshold
|
||||
file = mpvnet
|
||||
filter = Screen
|
||||
help = Threshold in milliseconds to wait for libmpv returning the video resolution before the window is shown, otherwise default dimensions are used as defined by autofit and start-size. Default: 1500 (mpv.net specific option)
|
||||
|
||||
[setting]
|
||||
name = minimum-aspect-ratio
|
||||
file = mpvnet
|
||||
filter = Screen
|
||||
help = <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 (mpv.net specific option)
|
||||
help = <float> Minimum aspect ratio of the window. Useful to force a wider window and therefore a larger OSC. (mpv.net specific option)
|
||||
|
||||
[setting]
|
||||
name = minimum-aspect-ratio-audio
|
||||
file = mpvnet
|
||||
filter = Screen
|
||||
help = Same as minimum-aspect-ratio but used for audio files.
|
||||
|
||||
[setting]
|
||||
name = remember-window-position
|
||||
@@ -469,6 +481,16 @@ help = Save the window position on exit. (mpv.net specific option)
|
||||
option = yes
|
||||
option = no
|
||||
|
||||
[setting]
|
||||
name = snap-window
|
||||
file = mpv
|
||||
default = no
|
||||
filter = Screen
|
||||
help = Snap the player window to screen edges.
|
||||
|
||||
option = yes
|
||||
option = no
|
||||
|
||||
[setting]
|
||||
name = window-maximized
|
||||
file = mpv
|
||||
@@ -479,6 +501,12 @@ help = Start with a maximized window.
|
||||
option = yes
|
||||
option = no
|
||||
|
||||
[setting]
|
||||
name = start-threshold
|
||||
file = mpvnet
|
||||
filter = Screen
|
||||
help = Threshold in milliseconds to wait for libmpv returning the video resolution before the window is shown, otherwise default dimensions are used as defined by autofit and start-size. Default: 1500 (mpv.net specific option)
|
||||
|
||||
[setting]
|
||||
name = taskbar-progress
|
||||
file = mpv
|
||||
@@ -643,7 +671,7 @@ name = show-santa-logo
|
||||
file = mpvnet
|
||||
default = yes
|
||||
filter = UI
|
||||
help = Draws the blue mpv.net logo with a santa hat in december, the option is called green and grumpy in mpv.
|
||||
help = Draws the blue mpv.net logo with a santa hat in december, the option is called greenandgrumpy in mpv.
|
||||
|
||||
option = yes
|
||||
option = no
|
||||
|
||||
@@ -94,6 +94,8 @@ _ ignore #menu: Track
|
||||
|
||||
+ add volume 2 #menu: Volume > Up
|
||||
- add volume -2 #menu: Volume > Down
|
||||
0 add volume 2 #menu: Volume > Up
|
||||
9 add volume -2 #menu: Volume > Down
|
||||
_ ignore #menu: Volume > -
|
||||
m cycle mute #menu: Volume > Mute
|
||||
|
||||
@@ -118,6 +120,7 @@ Ctrl+p script-message-to mpvnet select-profile #menu: View > Show Profile
|
||||
Ctrl+P script-message-to mpvnet show-profiles #menu: View > Show Profiles
|
||||
Ctrl+7 script-message-to mpvnet show-audio-tracks #menu: View > Show Audio Tracks
|
||||
Ctrl+8 script-message-to mpvnet show-subtitle-tracks #menu: View > Show Subtitle Tracks
|
||||
Ctrl+c script-message-to mpvnet show-chapters #menu: View > Show Chapters
|
||||
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
|
||||
@@ -170,7 +173,6 @@ Esc quit #menu: Exit
|
||||
MBTN_Right script-message-to mpvnet show-menu
|
||||
6 script-message-to mpvnet show-progress
|
||||
KP6 script-message-to mpvnet show-progress
|
||||
9 ab-loop
|
||||
KP9 ab-loop
|
||||
7 script-message-to mpvnet cycle-audio
|
||||
Sharp script-message-to mpvnet cycle-audio
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Drawing;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
@@ -20,9 +21,11 @@ namespace mpvnet
|
||||
{
|
||||
public partial class MainForm : Form
|
||||
{
|
||||
public SnapManager SnapManager = new SnapManager();
|
||||
public ElementHost CommandPaletteHost { get; set; }
|
||||
public IntPtr mpvWindowHandle { get; set; }
|
||||
public static MainForm Instance { get; set; }
|
||||
public Dictionary<string, WpfControls.MenuItem> MenuItemDuplicate = new Dictionary<string, WpfControls.MenuItem>();
|
||||
|
||||
new WpfControls.ContextMenu ContextMenu { get; set; }
|
||||
AutoResetEvent MenuAutoResetEvent { get; } = new AutoResetEvent(false);
|
||||
@@ -220,7 +223,7 @@ namespace mpvnet
|
||||
if (FormBorderStyle == FormBorderStyle.None)
|
||||
top = ClientSize.Height * 0.1f;
|
||||
|
||||
return pos.Y > ClientSize.Height * 0.85 || pos.Y < top;
|
||||
return pos.Y > ClientSize.Height * 0.78 || pos.Y < top;
|
||||
}
|
||||
|
||||
void UpdateMenu()
|
||||
@@ -291,28 +294,20 @@ namespace mpvnet
|
||||
}
|
||||
}
|
||||
|
||||
lock (Core.Chapters)
|
||||
{
|
||||
var chaptersMenuItem = FindMenuItem("Chapters");
|
||||
|
||||
if (chaptersMenuItem != null)
|
||||
{
|
||||
chaptersMenuItem.Items.Clear();
|
||||
|
||||
foreach (var pair in Core.Chapters)
|
||||
foreach (Chapter chapter in Core.GetChapters())
|
||||
{
|
||||
string caption = TimeSpan.FromSeconds(pair.Value).ToString();
|
||||
|
||||
if (caption.ContainsEx("."))
|
||||
caption = caption.Substring(0, caption.LastIndexOf("."));
|
||||
|
||||
var chapterMenuItem = new WpfControls.MenuItem() { Header = pair.Key };
|
||||
chapterMenuItem.InputGestureText = caption;
|
||||
chapterMenuItem.Click += (sender, args) => Core.CommandV("seek", pair.Value.ToString(CultureInfo.InvariantCulture), "absolute");
|
||||
var chapterMenuItem = new WpfControls.MenuItem() { Header = chapter.Title };
|
||||
chapterMenuItem.InputGestureText = chapter.TimeDisplay;
|
||||
chapterMenuItem.Click += (sender, args) => Core.CommandV("seek", chapter.Time.ToString(CultureInfo.InvariantCulture), "absolute");
|
||||
chaptersMenuItem.Items.Add(chapterMenuItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var recentMenuItem = FindMenuItem("Recent");
|
||||
|
||||
@@ -431,13 +426,23 @@ namespace mpvnet
|
||||
}
|
||||
|
||||
Screen screen = Screen.FromControl(this);
|
||||
int autoFitHeight = Convert.ToInt32(screen.WorkingArea.Height * Core.Autofit);
|
||||
Rectangle workingArea = GetWorkingArea(Handle, screen.WorkingArea);
|
||||
int autoFitHeight = Convert.ToInt32(workingArea.Height * Core.Autofit);
|
||||
|
||||
if (Core.VideoSize.Height == 0 || Core.VideoSize.Width == 0 ||
|
||||
Core.VideoSize.Width / (float)Core.VideoSize.Height < App.MinimumAspectRatio)
|
||||
if (App.AutofitAudio > 1) App.AutofitAudio = 1;
|
||||
if (App.AutofitImage > 1) App.AutofitImage = 1;
|
||||
|
||||
if (Core.IsAudio) autoFitHeight = Convert.ToInt32(workingArea.Height * App.AutofitAudio);
|
||||
if (Core.IsImage) autoFitHeight = Convert.ToInt32(workingArea.Height * App.AutofitImage);
|
||||
|
||||
if (Core.VideoSize.Height == 0 || Core.VideoSize.Width == 0)
|
||||
Core.VideoSize = new Size((int)(autoFitHeight * (16 / 9f)), autoFitHeight);
|
||||
|
||||
float minAspectRatio = Core.IsAudio ? App.MinimumAspectRatioAudio : App.MinimumAspectRatio;
|
||||
|
||||
if (minAspectRatio != 0 && Core.VideoSize.Width / (float)Core.VideoSize.Height < minAspectRatio)
|
||||
Core.VideoSize = new Size((int)(autoFitHeight * minAspectRatio), autoFitHeight);
|
||||
|
||||
Size videoSize = Core.VideoSize;
|
||||
|
||||
int height = videoSize.Height;
|
||||
@@ -473,7 +478,7 @@ namespace mpvnet
|
||||
height = windowSize.Height;
|
||||
width = height * videoSize.Width / videoSize.Height;
|
||||
}
|
||||
else if (App.StartSize == "height-session")
|
||||
else if (App.StartSize == "height-session" || App.StartSize == "session")
|
||||
{
|
||||
height = autoFitHeight;
|
||||
width = height * videoSize.Width / videoSize.Height;
|
||||
@@ -488,7 +493,7 @@ namespace mpvnet
|
||||
width = autoFitHeight / 9 * 16;
|
||||
height = (int)Math.Ceiling(width * videoSize.Height / (double)videoSize.Width);
|
||||
}
|
||||
else if (KeepSize() && windowSize.Height != 0)
|
||||
else if (App.StartSize == "always" && windowSize.Height != 0)
|
||||
{
|
||||
height = windowSize.Height;
|
||||
width = windowSize.Width;
|
||||
@@ -502,8 +507,10 @@ namespace mpvnet
|
||||
|
||||
void SetSize(int width, int height, Screen screen, bool checkAutofit = true)
|
||||
{
|
||||
int maxHeight = screen.WorkingArea.Height - (Height - ClientSize.Height) - 2;
|
||||
int maxWidth = screen.WorkingArea.Width - (Width - ClientSize.Width);
|
||||
Rectangle workingArea = GetWorkingArea(Handle, screen.WorkingArea);
|
||||
|
||||
int maxHeight = workingArea.Height - (Height - ClientSize.Height) - 2;
|
||||
int maxWidth = workingArea.Width - (Width - ClientSize.Width);
|
||||
|
||||
int startWidth = width;
|
||||
int startHeight = height;
|
||||
@@ -558,10 +565,10 @@ namespace mpvnet
|
||||
|
||||
Screen[] screens = Screen.AllScreens;
|
||||
|
||||
int minLeft = screens.Select(val => val.WorkingArea.X).Min();
|
||||
int maxRight = screens.Select(val => val.WorkingArea.Right).Max();
|
||||
int minTop = screens.Select(val => val.WorkingArea.Y).Min();
|
||||
int maxBottom = screens.Select(val => val.WorkingArea.Bottom).Max();
|
||||
int minLeft = screens.Select(val => GetWorkingArea(Handle, val.WorkingArea).X).Min();
|
||||
int maxRight = screens.Select(val => GetWorkingArea(Handle, val.WorkingArea).Right).Max();
|
||||
int minTop = screens.Select(val => GetWorkingArea(Handle, val.WorkingArea).Y).Min();
|
||||
int maxBottom = screens.Select(val => GetWorkingArea(Handle, val.WorkingArea).Bottom).Max();
|
||||
|
||||
if (left < minLeft)
|
||||
left = minLeft;
|
||||
@@ -622,7 +629,7 @@ namespace mpvnet
|
||||
|
||||
public int GetHorizontalLocation(Screen screen)
|
||||
{
|
||||
Rectangle workingArea = screen.WorkingArea;
|
||||
Rectangle workingArea = GetWorkingArea(Handle, screen.WorkingArea);
|
||||
Rectangle rect = new Rectangle(Left - workingArea.X, Top - workingArea.Y, Width, Height);
|
||||
|
||||
if (workingArea.Width / (float)Width < 1.1)
|
||||
@@ -639,7 +646,7 @@ namespace mpvnet
|
||||
|
||||
public int GetVerticalLocation(Screen screen)
|
||||
{
|
||||
Rectangle workingArea = screen.WorkingArea;
|
||||
Rectangle workingArea = GetWorkingArea(Handle, screen.WorkingArea);
|
||||
Rectangle rect = new Rectangle(Left - workingArea.X, Top - workingArea.Y, Width, Height);
|
||||
|
||||
if (workingArea.Height / (float)Height < 1.1)
|
||||
@@ -672,15 +679,23 @@ namespace mpvnet
|
||||
|
||||
foreach (CommandItem item in items)
|
||||
{
|
||||
var tempItem = item;
|
||||
CommandItem tempItem = item;
|
||||
|
||||
if (string.IsNullOrEmpty(tempItem.Path))
|
||||
continue;
|
||||
|
||||
if (MenuItemDuplicate.ContainsKey(tempItem.Path))
|
||||
{
|
||||
var mi = MenuItemDuplicate[tempItem.Path];
|
||||
mi.InputGestureText = mi.InputGestureText + ", " + tempItem.Input;
|
||||
}
|
||||
else
|
||||
{
|
||||
var menuItem = MenuHelp.Add(ContextMenu.Items, tempItem.Path);
|
||||
|
||||
if (menuItem != null)
|
||||
{
|
||||
MenuItemDuplicate[tempItem.Path] = menuItem;
|
||||
menuItem.Click += (sender, args) => {
|
||||
try {
|
||||
App.RunTask(() => {
|
||||
@@ -700,6 +715,7 @@ namespace mpvnet
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Core_FileLoaded()
|
||||
{
|
||||
@@ -720,7 +736,7 @@ namespace mpvnet
|
||||
|
||||
string path = Core.GetPropertyString("path");
|
||||
|
||||
if (path.Contains(":/") && !path.Contains("://"))
|
||||
if ((path.Contains(":/") && !path.Contains("://")) || (path.Contains(":\\") && path.Contains("/")))
|
||||
path = path.Replace("/", "\\");
|
||||
|
||||
if (path.Contains("://"))
|
||||
@@ -824,7 +840,7 @@ namespace mpvnet
|
||||
if (mpvWindowHandle != IntPtr.Zero)
|
||||
m.Result = SendMessage(mpvWindowHandle, m.Msg, m.WParam, m.LParam);
|
||||
break;
|
||||
case 0x051: // WM_INPUTLANGCHANGE
|
||||
case 0x51: // WM_INPUTLANGCHANGE
|
||||
ActivateKeyboardLayout(m.LParam, 0x00000100u /*KLF_SETFORPROCESS*/);
|
||||
break;
|
||||
case 0x319: // WM_APPCOMMAND
|
||||
@@ -839,10 +855,10 @@ namespace mpvnet
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x0312: // WM_HOTKEY
|
||||
case 0x312: // WM_HOTKEY
|
||||
GlobalHotkey.Execute(m.WParam.ToInt32());
|
||||
break;
|
||||
case 0x0200: // WM_MOUSEMOVE
|
||||
case 0x200: // WM_MOUSEMOVE
|
||||
if (Environment.TickCount - LastCycleFullscreen > 500)
|
||||
{
|
||||
Point pos = PointToClient(Cursor.Position);
|
||||
@@ -862,7 +878,7 @@ namespace mpvnet
|
||||
Core.Command($"mouse {pos.X} {pos.Y} 0 double");
|
||||
}
|
||||
break;
|
||||
case 0x02E0: // WM_DPICHANGED
|
||||
case 0x2E0: // WM_DPICHANGED
|
||||
{
|
||||
if (!Core.Shown)
|
||||
break;
|
||||
@@ -871,7 +887,7 @@ namespace mpvnet
|
||||
SetWindowPos(Handle, IntPtr.Zero, rect.Left, rect.Top, rect.Width, rect.Height, 0);
|
||||
}
|
||||
break;
|
||||
case 0x0214: // WM_SIZING
|
||||
case 0x214: // WM_SIZING
|
||||
if (Core.KeepaspectWindow)
|
||||
{
|
||||
RECT rc = Marshal.PtrToStructure<RECT>(m.LParam);
|
||||
@@ -899,7 +915,7 @@ namespace mpvnet
|
||||
m.Result = new IntPtr(1);
|
||||
}
|
||||
return;
|
||||
case 0x004A: // WM_COPYDATA
|
||||
case 0x4A: // WM_COPYDATA
|
||||
{
|
||||
var copyData = (COPYDATASTRUCT)m.GetLParam(typeof(COPYDATASTRUCT));
|
||||
string[] args = copyData.lpData.Split('\n');
|
||||
@@ -923,6 +939,56 @@ namespace mpvnet
|
||||
Activate();
|
||||
}
|
||||
return;
|
||||
case 0x84: // WM_NCHITTEST
|
||||
// resize borderless window
|
||||
if (!Core.Border && !Core.Fullscreen) {
|
||||
const int HTCLIENT = 1;
|
||||
const int HTLEFT = 10;
|
||||
const int HTRIGHT = 11;
|
||||
const int HTTOP = 12;
|
||||
const int HTTOPLEFT = 13;
|
||||
const int HTTOPRIGHT = 14;
|
||||
const int HTBOTTOM = 15;
|
||||
const int HTBOTTOMLEFT = 16;
|
||||
const int HTBOTTOMRIGHT = 17;
|
||||
|
||||
int x = (short)(m.LParam.ToInt32() & 0xFFFF); // LoWord
|
||||
int y = (short)(m.LParam.ToInt32() >> 16); // HiWord
|
||||
|
||||
Point pt = PointToClient(new Point(x, y));
|
||||
Size cs = ClientSize;
|
||||
m.Result = new IntPtr(HTCLIENT);
|
||||
int distance = FontHeight / 3;
|
||||
|
||||
if (pt.X >= cs.Width - distance && pt.Y >= cs.Height - distance && cs.Height >= distance)
|
||||
m.Result = (IntPtr)HTBOTTOMRIGHT;
|
||||
else if (pt.X <= distance && pt.Y >= cs.Height - distance && cs.Height >= distance)
|
||||
m.Result = (IntPtr)HTBOTTOMLEFT;
|
||||
else if (pt.X <= distance && pt.Y <= distance && cs.Height >= distance)
|
||||
m.Result = (IntPtr)HTTOPLEFT;
|
||||
else if (pt.X >= cs.Width - distance && pt.Y <= distance && cs.Height >= distance)
|
||||
m.Result = (IntPtr)HTTOPRIGHT;
|
||||
else if (pt.Y <= distance && cs.Height >= distance)
|
||||
m.Result = (IntPtr)HTTOP;
|
||||
else if (pt.Y >= cs.Height - distance && cs.Height >= distance)
|
||||
m.Result = (IntPtr)HTBOTTOM;
|
||||
else if (pt.X <= distance && cs.Height >= distance)
|
||||
m.Result = (IntPtr)HTLEFT;
|
||||
else if (pt.X >= cs.Width - distance && cs.Height >= distance)
|
||||
m.Result = (IntPtr)HTRIGHT;
|
||||
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case 0x231: // WM_ENTERSIZEMOVE
|
||||
case 0x005: // WM_SIZE
|
||||
if (Core.SnapWindow)
|
||||
SnapManager.OnSizeAndEnterSizeMove(this);
|
||||
break;
|
||||
case 0x216: // WM_MOVING
|
||||
if (Core.SnapWindow)
|
||||
SnapManager.OnMoving(ref m);
|
||||
break;
|
||||
}
|
||||
|
||||
if (m.Msg == TaskbarButtonCreatedMessage && Core.TaskbarProgress)
|
||||
@@ -1255,7 +1321,7 @@ namespace mpvnet
|
||||
if (CommandPaletteHost == null)
|
||||
return;
|
||||
|
||||
CommandPaletteHost.Width = FontHeight * 25;
|
||||
CommandPaletteHost.Width = FontHeight * 26;
|
||||
|
||||
if (CommandPaletteHost.Width > ClientSize.Width)
|
||||
CommandPaletteHost.Width = ClientSize.Width;
|
||||
81
src/WinForms/SnapManager.cs
Normal file
81
src/WinForms/SnapManager.cs
Normal file
@@ -0,0 +1,81 @@
|
||||
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Windows.Forms;
|
||||
|
||||
using static mpvnet.Native;
|
||||
|
||||
namespace mpvnet
|
||||
{
|
||||
public class SnapManager
|
||||
{
|
||||
int DragOffsetX { get; set; }
|
||||
int DragOffsetY { get; set; }
|
||||
|
||||
IntPtr Handle;
|
||||
|
||||
[Flags]
|
||||
public enum SnapLocation
|
||||
{
|
||||
None = 0,
|
||||
Left = 1 << 0,
|
||||
Top = 1 << 1,
|
||||
Right = 1 << 2,
|
||||
Bottom = 1 << 3,
|
||||
All = Left | Top | Right | Bottom
|
||||
}
|
||||
|
||||
public int AnchorDistance { get; set; }
|
||||
|
||||
public int SnapDistance { get; set; }
|
||||
|
||||
bool InSnapRange(int a, int b) => Math.Abs(a - b) < SnapDistance;
|
||||
|
||||
void FindSnap(ref Rectangle effectiveBounds)
|
||||
{
|
||||
Screen currentScreen = Screen.FromPoint(effectiveBounds.Location);
|
||||
Rectangle workingArea = GetWorkingArea(Handle, currentScreen.WorkingArea);
|
||||
|
||||
if (InSnapRange(effectiveBounds.Left, workingArea.Left + AnchorDistance))
|
||||
effectiveBounds.X = workingArea.Left + AnchorDistance;
|
||||
else if (InSnapRange(effectiveBounds.Right, workingArea.Right - AnchorDistance))
|
||||
effectiveBounds.X = workingArea.Right - AnchorDistance - effectiveBounds.Width;
|
||||
if (InSnapRange(effectiveBounds.Top, workingArea.Top + AnchorDistance))
|
||||
effectiveBounds.Y = workingArea.Top + AnchorDistance;
|
||||
else if (InSnapRange(effectiveBounds.Bottom, workingArea.Bottom - AnchorDistance))
|
||||
effectiveBounds.Y = workingArea.Bottom - AnchorDistance - effectiveBounds.Height;
|
||||
}
|
||||
|
||||
public void OnMoving(ref Message m)
|
||||
{
|
||||
if (Handle == IntPtr.Zero)
|
||||
return;
|
||||
|
||||
RECT boundsLtrb = Marshal.PtrToStructure<RECT>(m.LParam);
|
||||
Rectangle bounds = boundsLtrb.ToRectangle();
|
||||
// This is where the window _would_ be located if snapping
|
||||
// had not occurred. This prevents the cursor from sliding
|
||||
// off the title bar if the snap distance is too large.
|
||||
Rectangle effectiveBounds = new Rectangle(
|
||||
Cursor.Position.X - DragOffsetX,
|
||||
Cursor.Position.Y - DragOffsetY,
|
||||
bounds.Width,
|
||||
bounds.Height);
|
||||
FindSnap(ref effectiveBounds);
|
||||
RECT newLtrb = RECT.FromRectangle(effectiveBounds);
|
||||
Marshal.StructureToPtr(newLtrb, m.LParam, false);
|
||||
m.Result = new IntPtr(1);
|
||||
}
|
||||
|
||||
public void OnSizeAndEnterSizeMove(Form form)
|
||||
{
|
||||
Handle = form.Handle;
|
||||
SnapDistance = form.Font.Height;
|
||||
// Need to handle window size changed as well when
|
||||
// un-maximizing the form by dragging the title bar.
|
||||
DragOffsetX = Cursor.Position.X - form.Left;
|
||||
DragOffsetY = Cursor.Position.Y - form.Top;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -93,6 +93,7 @@
|
||||
<Compile Include="Misc\Common.cs" />
|
||||
<Compile Include="Misc\FolderBrowser.cs" />
|
||||
<Compile Include="Misc\JSONParser.cs" />
|
||||
<Compile Include="WinForms\SnapManager.cs" />
|
||||
<Compile Include="WPF\HandyControl\Controls\Attach\BorderElement.cs" />
|
||||
<Compile Include="WPF\HandyControl\Controls\Attach\MenuTopLineAttach.cs" />
|
||||
<Compile Include="WPF\HandyControl\Tools\Converter\BorderCircularConverter.cs" />
|
||||
@@ -186,10 +187,10 @@
|
||||
<DependentUpon>Resources.resx</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Native\libmpv.cs" />
|
||||
<Compile Include="Misc\MainForm.cs">
|
||||
<Compile Include="WinForms\MainForm.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Misc\MainForm.Designer.cs">
|
||||
<Compile Include="WinForms\MainForm.Designer.cs">
|
||||
<DependentUpon>MainForm.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Misc\Misc.cs" />
|
||||
@@ -211,7 +212,7 @@
|
||||
<DependentUpon>InputWindow.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="WPF\WPF.cs" />
|
||||
<EmbeddedResource Include="Misc\MainForm.resx">
|
||||
<EmbeddedResource Include="WinForms\MainForm.resx">
|
||||
<DependentUpon>MainForm.cs</DependentUpon>
|
||||
<SubType>Designer</SubType>
|
||||
</EmbeddedResource>
|
||||
|
||||
Reference in New Issue
Block a user