Compare commits
264 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
660345d18a | ||
|
|
3844db6e79 | ||
|
|
5374e20757 | ||
|
|
bc6167c4ee | ||
|
|
7979f77284 | ||
|
|
71b90ed5cb | ||
|
|
9d2e236b3e | ||
|
|
d42657a3f0 | ||
|
|
e4818fae18 | ||
|
|
7b39bfcbc4 | ||
|
|
fd6f3c94dd | ||
|
|
dd10c07fb5 | ||
|
|
3bbfdcffdd | ||
|
|
6b7c4e1724 | ||
|
|
d3ad1091ec | ||
|
|
65177c448b | ||
|
|
1cdecb3810 | ||
|
|
20ea755a93 | ||
|
|
3b7bc95869 | ||
|
|
5380daad53 | ||
|
|
a5f4d848d4 | ||
|
|
cf0f9bfa01 | ||
|
|
68461e05da | ||
|
|
397b988851 | ||
|
|
eddb95e791 | ||
|
|
fa1183710b | ||
|
|
f468fd9c56 | ||
|
|
22f2aa93a8 | ||
|
|
c2c0a8f190 | ||
|
|
da3e6655c6 | ||
|
|
856959a4d1 | ||
|
|
9053ecb4ee | ||
|
|
33fd7fc09b | ||
|
|
d005f19755 | ||
|
|
1081007009 | ||
|
|
e6c0a67483 | ||
|
|
265e18985d | ||
|
|
8dc204e81a | ||
|
|
b9b604bfe3 | ||
|
|
05027cd458 | ||
|
|
9bbde49a5c | ||
|
|
cfca7786f3 | ||
|
|
be57edf2c5 | ||
|
|
f48901355a | ||
|
|
ca153fecfc | ||
|
|
e3227de8b4 | ||
|
|
4a202245b5 | ||
|
|
b94f9de582 | ||
|
|
7371949730 | ||
|
|
857926696c | ||
|
|
4451a6c185 | ||
|
|
ea6a71b7c3 | ||
|
|
625dddcfbb | ||
|
|
0cd769fc0c | ||
|
|
f5e0c92824 | ||
|
|
327a097bcf | ||
|
|
68626fa536 | ||
|
|
8935101058 | ||
|
|
6947c925b9 | ||
|
|
4562131078 | ||
|
|
21188f0942 | ||
|
|
1316559ebc | ||
|
|
cd576f9211 | ||
|
|
1bac8e8937 | ||
|
|
e6d0449f8f | ||
|
|
e0e40b7918 | ||
|
|
b59f16a425 | ||
|
|
46b110d93b | ||
|
|
7e8a654ada | ||
|
|
c2c33228a0 | ||
|
|
0a28f13d51 | ||
|
|
9f3a1da931 | ||
|
|
05874ad6be | ||
|
|
078e8046bd | ||
|
|
b07901485e | ||
|
|
a37cbef8a8 | ||
|
|
8debcc171c | ||
|
|
e230f0f474 | ||
|
|
558bd67591 | ||
|
|
a7e4892acf | ||
|
|
a0ba69c1aa | ||
|
|
1e7e80577d | ||
|
|
2177308b02 | ||
|
|
a8c2409ed1 | ||
|
|
1ef9e64a41 | ||
|
|
f0546485cf | ||
|
|
032e91e4b4 | ||
|
|
1447636eb7 | ||
|
|
966f96a02b | ||
|
|
954c014708 | ||
|
|
ad30dc5ae2 | ||
|
|
3f74344b99 | ||
|
|
96d8d88d09 | ||
|
|
8626b8283f | ||
|
|
d90025e8fe | ||
|
|
a572bd8553 | ||
|
|
0f5146e58c | ||
|
|
9c6c0f3506 | ||
|
|
8c36cc8b8c | ||
|
|
44435057d7 | ||
|
|
135bdeb638 | ||
|
|
93c93b620d | ||
|
|
247aefbf07 | ||
|
|
0a8397652f | ||
|
|
ecd5b01161 | ||
|
|
1e9893977d | ||
|
|
4fd6b13e0f | ||
|
|
d21d36c196 | ||
|
|
fbffbea641 | ||
|
|
9899c2cd27 | ||
|
|
10370e9ae2 | ||
|
|
d391e24784 | ||
|
|
430fef0ac4 | ||
|
|
8430842679 | ||
|
|
9d37e67901 | ||
|
|
e98ff53058 | ||
|
|
b47d3c34f2 | ||
|
|
54dd261df0 | ||
|
|
8eb7e41d16 | ||
|
|
2068bfb6fa | ||
|
|
dfc1ac712e | ||
|
|
d96587cb7b | ||
|
|
005550af55 | ||
|
|
543e2905cc | ||
|
|
a49b9bea61 | ||
|
|
9ea9cb2757 | ||
|
|
5543381a14 | ||
|
|
cd6dcf4640 | ||
|
|
d321ab477f | ||
|
|
1cd0f87278 | ||
|
|
936274fc3b | ||
|
|
2bbaa30322 | ||
|
|
cedd54d64d | ||
|
|
38604459a6 | ||
|
|
0a48a0dc6f | ||
|
|
85a23fbae1 | ||
|
|
01da76bdc4 | ||
|
|
1f1553e159 | ||
|
|
2af84941ca | ||
|
|
a82f558acf | ||
|
|
d13f7201ba | ||
|
|
89aa0c6133 | ||
|
|
1699467e0d | ||
|
|
7a27ab0513 | ||
|
|
2a0c68e4ec | ||
|
|
91c42d4d3f | ||
|
|
49d56166d7 | ||
|
|
1ac603b904 | ||
|
|
d5b2923c68 | ||
|
|
b80b375df1 | ||
|
|
2b2b60b90f | ||
|
|
3977283ecb | ||
|
|
d27778775d | ||
|
|
5c053bb5eb | ||
|
|
83658aa476 | ||
|
|
e0111b6f12 | ||
|
|
e308bbf928 | ||
|
|
1817fbc0fd | ||
|
|
3b149aea54 | ||
|
|
7575a2d736 | ||
|
|
17c198e711 | ||
|
|
1f8635e9c4 | ||
|
|
37e6c198a1 | ||
|
|
751c8779f4 | ||
|
|
9e2bf46636 | ||
|
|
3529323d93 | ||
|
|
ba52c1f8b5 | ||
|
|
bf2070d758 | ||
|
|
7a1de4cf0f | ||
|
|
caf0bee161 | ||
|
|
cedd694e8e | ||
|
|
d1c58585f5 | ||
|
|
0fce626c46 | ||
|
|
adb8f38c0d | ||
|
|
735ee42580 | ||
|
|
103ae81b8b | ||
|
|
8e351193e1 | ||
|
|
d57b9281a1 | ||
|
|
e07627377e | ||
|
|
8899f4b772 | ||
|
|
e7fd268927 | ||
|
|
c8fe3a4c43 | ||
|
|
19c2502c31 | ||
|
|
56dae4babd | ||
|
|
bc20d7527c | ||
|
|
3d325d4fe5 | ||
|
|
ba0141cfb1 | ||
|
|
d32c7b4056 | ||
|
|
63f064ba1c | ||
|
|
e5c9df31e4 | ||
|
|
c0a8e895f7 | ||
|
|
064ae44ecf | ||
|
|
005ba6e5ea | ||
|
|
9f6aba6cbd | ||
|
|
87e3d9ca3e | ||
|
|
29a0eae3d5 | ||
|
|
01b2492cde | ||
|
|
d2b1ca0c69 | ||
|
|
91b429e6b0 | ||
|
|
fa05e95892 | ||
|
|
701a58a4bf | ||
|
|
387c3f7896 | ||
|
|
eeb0189577 | ||
|
|
de4c2d6d70 | ||
|
|
63ee598ebd | ||
|
|
1bf8e568c5 | ||
|
|
f8f58dba5e | ||
|
|
ebb8ad351a | ||
|
|
0202c34c6f | ||
|
|
c3f2b22ff5 | ||
|
|
c1a03c3e4b | ||
|
|
e041908f04 | ||
|
|
270559c3f7 | ||
|
|
0dfd19eb45 | ||
|
|
9cdba6d2f2 | ||
|
|
50bf09ff8d | ||
|
|
c54fa708f8 | ||
|
|
7698e873ca | ||
|
|
89b8de2c40 | ||
|
|
259d2d882a | ||
|
|
b7fbef5a88 | ||
|
|
0ca9ac93f1 | ||
|
|
f7b3900a0a | ||
|
|
c98036dc42 | ||
|
|
a9e7ae4b97 | ||
|
|
30fb744114 | ||
|
|
d465516a6a | ||
|
|
0b951875e6 | ||
|
|
5ed65733a0 | ||
|
|
caac45a871 | ||
|
|
f4f69816a7 | ||
|
|
1dddf129df | ||
|
|
ca9690c3b3 | ||
|
|
3b0b098bda | ||
|
|
c72080e92c | ||
|
|
237a3cf132 | ||
|
|
562f149fff | ||
|
|
dc85372c36 | ||
|
|
2595465ec7 | ||
|
|
1db733ae13 | ||
|
|
ba3bc48297 | ||
|
|
5e16c47100 | ||
|
|
a13c6648a3 | ||
|
|
5dc244d6f6 | ||
|
|
da9bc4199b | ||
|
|
1868957388 | ||
|
|
0139a1ef70 | ||
|
|
0989b7ef95 | ||
|
|
16924e5a3b | ||
|
|
502e1a9651 | ||
|
|
36a7bbcfab | ||
|
|
8fda90e09a | ||
|
|
269457dbde | ||
|
|
c93647841e | ||
|
|
0f78ea38ac | ||
|
|
7eb60f3e4c | ||
|
|
2636da446e | ||
|
|
c7fab24044 | ||
|
|
2ce1f3d9c1 | ||
|
|
d2f9108c22 | ||
|
|
3a2b9ee542 | ||
|
|
5c93bc00f7 | ||
|
|
19c09da4e1 | ||
|
|
95c9c115b2 |
360
Changelog.md
Normal file
@@ -0,0 +1,360 @@
|
||||
|
||||
### 5.4.4.0
|
||||
|
||||
- new: forecolors in the dark theme are slightly darker now
|
||||
- new: readme/website and manual were improved
|
||||
- new: source code includes now the release script to build the archives and setup files
|
||||
- new: the history feature now uses the full path
|
||||
- new: install via Scoop and Chocolatey added to readme/website (Restia666Ashdoll)
|
||||
- new: update check, it must be enabled first in the conf editor under General
|
||||
- new: update feature, requires PowerShell 5 and curl,
|
||||
an up to date Windows 10 system has both included.
|
||||
Main menu (input.conf) must be reset or updated manually ([defaults](https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/inputConf.txt))
|
||||
|
||||
- update: libmpv shinchiro 2019-11-10
|
||||
|
||||
- fix: often the OSC was shown when fullscreen was entered
|
||||
or on app startup, this is now suppressed
|
||||
- fix: the file association routine uses no longer 'Play with mpv.net' for the
|
||||
default open verb caption because it doesn't support multi selection,
|
||||
it shows now only Open, the manual explains how to get multi selection
|
||||
in File Explorer, read about it [here](https://github.com/stax76/mpv.net/blob/master/Manual.md#open-with)
|
||||
- fix: x86 builds had an older version included because
|
||||
of a misconfiguration in the solution file
|
||||
|
||||
### 5.4.3.0
|
||||
|
||||
- new: the color themes can now be customized ([manual](https://github.com/stax76/mpv.net/blob/master/Manual.md#color-theme))
|
||||
- new: three new sections were added to the [manual](https://github.com/stax76/mpv.net/blob/master/Manual.md):
|
||||
1. [Color Theme](https://github.com/stax76/mpv.net/blob/master/Manual.md#color-theme)
|
||||
2. [Hidden and secret features](https://github.com/stax76/mpv.net/blob/master/Manual.md#hidden-and-secret-features)
|
||||
3. [External Tools](https://github.com/stax76/mpv.net/blob/master/Manual.md#external-tools)
|
||||
|
||||
- fix: window restore from maximized and from minimized was broken
|
||||
- fix: it's possible to multi select files in File Explorer and press
|
||||
enter to open the files, this did however only work when the
|
||||
auto load folder feature was disabled or the shift key was
|
||||
pressed (blocks auto load folder). Now it should also work
|
||||
without shift key and with auto load folder being enabled
|
||||
|
||||
- update: libmpv shinchiro 2019-10-27
|
||||
- update: youtube-dl 2019-10-31
|
||||
|
||||
### 5.4.2.1 Beta
|
||||
|
||||
- pressing shift key suppresses auto-load-folder
|
||||
- switch --queue added, this will not clear the playlist but append
|
||||
and it will suppress auto-load-folder. To get a 'Add to mpv.net playlist'
|
||||
context menu item in explorer with multi selection support use my
|
||||
[Open with++](https://github.com/stax76/OpenWithPlusPlus#add-to-mpvnet-playlist) shell extension, as far as I know multi selection
|
||||
can not be done using the Registry but only via shell extension
|
||||
- window-size mpv property support added ([default bindings](https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/inputConf.txt#L137))
|
||||
- the config editor keeps profiles and comments in mpv.conf intact!
|
||||
- the options in the config editor are better organized
|
||||
|
||||
### 5.4.2
|
||||
|
||||
- new: the [scripting wiki page](https://github.com/stax76/mpv.net/wiki/Scripting#powershell) was improved
|
||||
- new: Toggle Shuffle has been added to the menu defaults
|
||||
- new: for URLs the media title is shown in the title bar and in the info command
|
||||
instead of displaying the URL, mpv.conf defaults were changed to use
|
||||
[protocol.https] osd-playing-msg = '${media-title}'
|
||||
|
||||
- fix: on the very first start volume was set to 0 and mute was set to yes
|
||||
- fix: there was a sound when closed from taskbar
|
||||
- fix: the log feature was not working
|
||||
- fix: clipboard monitoring removed because it was causing to many issues
|
||||
- fix: restore resulted in collapsed window when maximized = yes was used
|
||||
|
||||
- update: libmpv shinchiro 2019-10-06
|
||||
- update: youtube-dl 2019-10-01
|
||||
|
||||
### 5.4.1.1
|
||||
|
||||
- a issue with the taskbar-progress feature was fixed
|
||||
- improved PowerShell scrip host
|
||||
|
||||
### 5.4.1
|
||||
|
||||
- fix ArgumentOutOfRangeException
|
||||
|
||||
### 5.4
|
||||
|
||||
- added taskbar-progress implementation
|
||||
- added new setting to start with maximized window
|
||||
- long file paths work now even if not enabled by the OS
|
||||
- fixed history being written even when history file wasn't created prior
|
||||
- libmpv updated to shinchiro 2019-08-31
|
||||
|
||||
### 5.3
|
||||
|
||||
- added new feature: Open > Open DVD/Blu-ray Drive/Folder...
|
||||
- the default of remember-volume has been set to yes
|
||||
- scale, cscale, dscale defaults have been set to spline36,
|
||||
profile=gpu-hq is not used in the defaults because it starts very slow
|
||||
- new menu items have been added to navigate to the first and
|
||||
last playlist position, key bindings: Home, End
|
||||
- new config setting recent-count added, amount of menu items
|
||||
shown under 'Open > Recent'
|
||||
- in the config dialog the description for keep-open was corrected
|
||||
because unlike mpv, mpv.net will never terminate automatically
|
||||
- there was a rare occasion where the mpv.net logo wasn't shown
|
||||
- fix excessive memory usage using `osd-scale-by-window = no`
|
||||
- mpv setting osd-scale-by-window added to config dialog
|
||||
|
||||
### 5.2.1
|
||||
|
||||
- fixed race condition causing various features to fail
|
||||
|
||||
### 5.2
|
||||
|
||||
- bug fix for single-instance not working with unicode filenames
|
||||
- bug fix for logo not shown on start
|
||||
- osd-visibility.js script was removed because the OSC uses too much memory
|
||||
- youtube-dl was updated
|
||||
- libmpv was updated to shinchiro 2019-08-04
|
||||
- in case mpv.net was started from a terminal it sets now the mpv property input-terminal to yes,
|
||||
this means mpv.net will now receive and handle input keys from the terminal
|
||||
- certain command line properties didn't work (input-terminal, terminal, input-file,
|
||||
config, config-dir, input-conf, load-scripts, script, scripts, player-operation-mode)
|
||||
- the about dialog shows now the mpv version and build date
|
||||
- the dialog that asks for a config folder has now a cancel option
|
||||
|
||||
### 5.1
|
||||
|
||||
- 'Tools > Execute mpv command' was replaced with [mpv-repl](https://github.com/rossy/mpv-repl)
|
||||
- many [wiki pages](https://github.com/stax76/mpv.net/wiki) were improved
|
||||
- the logo/icon had a very small cosmetic change
|
||||
- the help in the context menu was improved,
|
||||
for quick access consider the command palette (F1 key)
|
||||
- config options specific to mpv.net are now available from the command line
|
||||
- the input editor no longer has known limitations, 'alt gr' and ctrl+alt are working now
|
||||
- the help in the input editor was simplified and the filter logic was improved
|
||||
- fixed issue in file associations causing mpv.net not to appear in OS default apps
|
||||
- 'Tools > Manage File Associations' was replaced by 'Tools > OS Setup',
|
||||
it has now a feature to add and remove mpv.net to and from the Path
|
||||
environment variable and the OS default apps settings can be opened (Win 10 only)
|
||||
- startup folder and config folder being identical was causing a critical issue
|
||||
as mpv.net was loading extensions twice and scripts four times, now identical
|
||||
folders are no longer permitted
|
||||
- error messages are shown when unknown scripts and extensions are found in the startup folder
|
||||
because user scripts and extensions are supposed to be located in the config folder instead
|
||||
- changing from maximized to fullscreen did not work
|
||||
- the search field in the config editor was not always remembered
|
||||
- new setting remember-volume added, saves volume and mute on exit
|
||||
and restores it on start.
|
||||
- it's now enforced that mpv properties on the command line and in
|
||||
the mpv.conf config file are lowercase, if not a error is shown
|
||||
- gpu-api vulkan was not working if media files were opened via
|
||||
command line (that included Explorer)
|
||||
- new setting minimum-aspect-ratio added, minimum aspect ratio for the window,
|
||||
this was previously hard coded to 1.3
|
||||
- new setting auto-load-folder added, for single files automatically load
|
||||
the entire directory into the playlist, previously this was forced,
|
||||
now it can be disabled
|
||||
- new setting themed-menu added, follow theme color in context menu,
|
||||
default: no. UI related settings have now a separate UI tab in the config editor
|
||||
|
||||
### 5.0
|
||||
|
||||
- [changed icon design](https://github.com/stax76/mpv.net/blob/master/img/mpvnet.png)
|
||||
- libmpv was updated to shinchiro 2019-07-14
|
||||
- new or improved config editor settings: screenshot-directory,
|
||||
screenshot-format, screenshot-tag-colorspace, screenshot-high-bit-depth,
|
||||
screenshot-jpeg-source-chroma, screenshot-template, screenshot-jpeg-quality,
|
||||
screenshot-png-compression, screenshot-png-filter
|
||||
- mpv.conf preview feature added to config editor, it previews the mpv.conf content
|
||||
- in the entire project the term addon was replaced with the term extension,
|
||||
unfortunately this will break user extensions. The reason for this drastic
|
||||
change is that there exist too many different terms, addons, addins,
|
||||
extensions, modules, packages etc.. mpv.net follows Google Chrome as the worlds
|
||||
most popular extendable app, Chrome uses the term Extension.
|
||||
- a thread synchronization bug was fixed, the shutdown thread was aborted
|
||||
if it was running more than 3 seconds, this caused the rating extension
|
||||
to fail if it was waiting for a drive to wake up
|
||||
- a new JavaScript was included to show the playlist with a smaller font size,
|
||||
the script is located at startup/scripts
|
||||
- terminal support added using mpvnet.com !
|
||||
- script engine performance and error handling was improved
|
||||
- the [scripting wiki page](https://github.com/stax76/mpv.net/wiki/Scripting) was improved
|
||||
- the C# scripting host extension was converted from VB to C# because it's not
|
||||
only used for hosting but I also use it now to code and debug script code
|
||||
- there was a copy paste bug in the file association feature resulting in keys
|
||||
from mpv being overwritten instead of using mpv.net keys. Thanks to floppyD!
|
||||
- there was a exception fixed that happened opening rar files
|
||||
- instead of using the OS theme color there are now default colors
|
||||
for dark-color and light-color
|
||||
|
||||
### 4.7.7
|
||||
|
||||
- on Win 7 the theme color was hardcoded to DarkSlateGrey because
|
||||
WPF was returning a bad color on Win 7, this was fixed by reading
|
||||
the theme color from the Registry on Win 7. If the theme color
|
||||
is identical to the background color it's corrected
|
||||
- dark-color setting was added to overwrite the OS theme color used in dark mode,
|
||||
find the setting on the General tab
|
||||
- light-color setting was added to overwrite the OS theme color used in non dark mode,
|
||||
find the setting on the General tab
|
||||
- various changes regarding input handling, multi media keys and
|
||||
mouse forward/backward were successfully tested
|
||||
- it's now possible to use a custom folder as config folder,
|
||||
A TaskDialog shows five options: 1. appdata mpv.net, 2. appdata mpv (shared with mpv),
|
||||
3. portable_config, 4. startup, 5. custom
|
||||
- slightly increased startup performance, start-threshold setting added.
|
||||
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
|
||||
- autofit-smaller setting added. Minimum window height in percent. Default: 40%
|
||||
- autofit-larger setting added. Maximum window height in percent. Default: 75%
|
||||
|
||||
### 4.7.3
|
||||
|
||||
- fix cursor showing load activity on startup
|
||||
- added file size and type to info command using audio files
|
||||
- added image format support to the info command, to file
|
||||
association management, to folder loading, to Everything
|
||||
- readme/github have a updated features and architecture section
|
||||
|
||||
### 4.7.1
|
||||
|
||||
- few layout problems were fixed, autosize for instance did not work
|
||||
|
||||
### 4.7
|
||||
|
||||
- remember-height was replaced with start-size, when start-size is set
|
||||
to video the main video starts directly with the native video size,
|
||||
before it was starting with the autofit size first and was only
|
||||
afterwards resized to the native video size
|
||||
- on exit the window location can be saved with remember-position
|
||||
- in the learn window of the input editor underscores were stripped
|
||||
because they have a special meaning in WPF labels
|
||||
- fix for keys/input not working for MBTN_LEFT_DBL, MBTN_BACK, MBTN_FORWARD
|
||||
- in the learn window of the input editor support was added for
|
||||
mouse left, mouse left double, mouse mid, mouse forward, mouse back
|
||||
- libmpv was updated to shinchiro 2019-07-07
|
||||
- when border is none it wasn't possible to minimize the window from
|
||||
the task bar because this is the WinForms default behavier. This
|
||||
was fixed by calling Spy++ to the rescue and adding WS_MINIMIZEBOX
|
||||
in CreateParams
|
||||
|
||||
### 4.6
|
||||
|
||||
- fix for middle mouse button not working
|
||||
- fix of logo overlay using a huge amount of memory (thx for the [ghacks article](https://www.ghacks.net/2019/07/05/a-look-at-mpv-net-a-mpv-frontend-with-everything-integration/))
|
||||
- fix config dialog showing a message about app restart without reason
|
||||
- when multiple files are selected in File Explorer and enter is
|
||||
pressed, the files are opened as selected, the order is random though
|
||||
because Explorer starts multiple mpv.net processes concurrently
|
||||
- libmpv was updated to shinchiro 2019-06-30
|
||||
- the [mpv.conf defaults](https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/mpvConf.txt) were changed to show a larger OSC
|
||||
- in case a file is opened that has a aspect ratio smaller then 1.2 then
|
||||
the window size will use a aspect ratio of 1.8
|
||||
- new JavaScript script osc-visibility.js included in the distribution
|
||||
under startup\scripts. It sets the OSC to be always on for audio files
|
||||
and auto for non audio files
|
||||
|
||||
### 4.5
|
||||
|
||||
- opening a URL manually no longer uses a input box but uses the clipboard directly
|
||||
- the manifest was missing the company attribute which caused
|
||||
mpv.net not appearing in the 'Open with' menu of the File Explorer,
|
||||
thanks to 44vince44 for pointing this out!!!
|
||||
- new Python and C# script examples were added to the wiki and the scripting and
|
||||
extension documentation was improved
|
||||
- invalid command line arguments were ignored, now an error message is shown
|
||||
- a description on how to start mpv.net from Google Chrome was added to the
|
||||
manual, it's useful to play videos from sites like YouTube, find the
|
||||
description [here](https://github.com/stax76/mpv.net/blob/master/Manual.md#chrome-extension)
|
||||
- new config setting remember-height added to remember the window height,
|
||||
otherwise the video's native resolution is used
|
||||
- support for protocols other then http added
|
||||
|
||||
### 4.4
|
||||
|
||||
- clipboard-monitoring was replaced by url-whitelist:
|
||||
Keyword whitelist to monitor the clipboard for URLs to play.
|
||||
Default: tube vimeo ard zdf
|
||||
- some settings like colors didn't work because enclosing quotes were missing
|
||||
- when single process queue is used the folder is no longer loaded
|
||||
- the playlist is never cleared whenever the control key is down but
|
||||
files and URLs are appended instead
|
||||
- powershell script hosting bugs were fixed and a new powershell example script
|
||||
was added to the [scripting wiki page](https://github.com/stax76/mpv.net/wiki/Scripting#powershell)
|
||||
- the menu entry for the command palette was renamed to 'Show All Commands' and
|
||||
the default key binding was changed to F1 which is also the default in VS Code
|
||||
- the default key binding of the Everything media search was changed to F3
|
||||
- support for the mpv property 'border' was added to the config editor
|
||||
to show/hide the window decoration (titlebar, border). A toggle menu item and
|
||||
key binding (b) was added as well ([Default Binding](https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/inputConf.txt#L135))
|
||||
|
||||
### 4.3.1
|
||||
|
||||
- there was a old bug setting the screen property
|
||||
|
||||
### 4.3
|
||||
|
||||
- there was new bug in file association feature
|
||||
|
||||
### 4.2
|
||||
|
||||
- the help and layout in the config editor was improved
|
||||
- clipboard monitoring for URLs can be disabled in the settings
|
||||
- the context menu has a new feature: Open > Add files to playlist,
|
||||
it appends files to the playlist [(Default binding)](https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/inputConf.txt#L33)
|
||||
- a setting was added to force using a single mpv.net process instance
|
||||
|
||||
### 4.1
|
||||
|
||||
- drag & drop support for subtitles was added
|
||||
- libmpv was updated
|
||||
- command line support for stdin and URLs was added
|
||||
- there was a crash happening when the player is
|
||||
minimized in the taskbar
|
||||
|
||||
### 4.0
|
||||
|
||||
- on the start screen the mpv.NET icon is shown instead of the mpv icon,
|
||||
feedback and contributions regarding the icon are welcome! The paint.net
|
||||
pdn and png source is located [here](https://github.com/stax76/mpv.net/tree/master/img)
|
||||
- everytime only one file is opened the complete folder is loaded in the playlist
|
||||
- the info command (i key) shows the audio format
|
||||
- new options osd-font-size, sub-font, sub-font-size
|
||||
- new color options with dedicated GUI support: sub-color, sub-border-color, sub-back-color
|
||||
- the config editor no longer shows the command line switches
|
||||
- the github start page was greatly improved
|
||||
- the setup.ps1 PowerShell script was greatly improved in regard of error handling and readability
|
||||
- a [manual to mpv.net](Manual.md) was created
|
||||
|
||||
### 3.7
|
||||
|
||||
- new icon design, probably better then before but still too simple
|
||||
- the radio buttons in the config editor have now a Windows 10 like design,
|
||||
they are larger and use the Windows theme color
|
||||
|
||||
### 3.6.1
|
||||
|
||||
- there was a bug causing an exception if both the input editor and config editor
|
||||
is opened, as soon as one is opened, the other can't be opened
|
||||
|
||||
### 3.6
|
||||
|
||||
- playing files from rar archives caused an exception
|
||||
- there was a bug that caused underscores beeing removed from input like MBTN_LEFT_DBL
|
||||
- the search clear button in the input editor had a render issue in dark mode
|
||||
- new search feature added to search and play media files, requires
|
||||
[Everything](https://www.voidtools.com) to be installed. [Default Binding](https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/inputConf.txt#L29)
|
||||
|
||||
### 3.5
|
||||
|
||||
- when the main windows gets activated and the clipboard content starts with http
|
||||
mpv.net will ask to play the URL, previously this was restricted to YouTube URLs
|
||||
- Python script errors show line and column whenever it is supported by IronPython
|
||||
- if conf files exist in the startup directory mpv.net will use the startup
|
||||
directory as config directory instead of creating default conf files in appdata
|
||||
- renamed commands are handled now by migration code instead of being broken
|
||||
|
||||
### 3.4
|
||||
|
||||
- new feature added to manage file associations from within the app. It can be found in the menu at: Tools > Manage... [Default Binding](https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/inputConf.txt#L149)
|
||||
- new zip download option added
|
||||
- new x86 download option added
|
||||
31
LICENSE.txt
@@ -1,21 +1,24 @@
|
||||
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2017-2019 Frank Skare (stax76)
|
||||
Copyright (c) 2002-2017 Frank Skare (stax76)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and ssociated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following conditions:
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and ssociated documentation
|
||||
files (the "Software"), to deal in the Software without restriction,
|
||||
including without limitation the rights to use, copy, modify, merge,
|
||||
publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH
|
||||
THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
|
||||
THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
909
Manual.md
Normal file
@@ -0,0 +1,909 @@
|
||||
# mpv.net manual
|
||||
|
||||
## Table of contents
|
||||
|
||||
* [About mpv.net](#about-mpvnet)
|
||||
+ [Target Audience](#target-audience)
|
||||
* [Requirements](#requirements)
|
||||
* [Installation](#installation)
|
||||
+ [File Associations](#file-associations)
|
||||
* [External Tools](#external-tools)
|
||||
+ [Play with mpv](#play-with-mpv)
|
||||
+ [External Application Button](#external-application-button)
|
||||
+ [Open with++](#open-with)
|
||||
+ [MediaInfo.NET](#mediainfonet)
|
||||
* [Command Line Interface](#command-line-interface)
|
||||
* [Terminal](#terminal)
|
||||
* [Color Theme](#color-theme)
|
||||
* [Hidden and secret features](#hidden-and-secret-features)
|
||||
* [Context Menu](#context-menu)
|
||||
+ [Open > Open Files](#open--open-files)
|
||||
+ [Open > Open URL](#open--open-url)
|
||||
+ [Open > Show media search](#open--show-media-search)
|
||||
+ [Open > Load external audio files](#open--load-external-audio-files)
|
||||
+ [Open > Load external subtitle files](#open--load-external-subtitle-files)
|
||||
+ [Play/Pause](#play-pause)
|
||||
+ [Stop](#stop)
|
||||
+ [Toggle Fullscreen](#toggle-fullscreen)
|
||||
+ [Navigate > Previous File](#navigate--previous-file)
|
||||
+ [Navigate > Next File](#navigate--next-file)
|
||||
+ [Navigate > Next Chapter](#navigate--next-chapter)
|
||||
+ [Navigate > Previous Chapter](#navigate--previous-chapter)
|
||||
+ [Navigate > Jump Next Frame](#navigate--jump-next-frame)
|
||||
+ [Navigate > Jump Previous Frame](#navigate--jump-previous-frame)
|
||||
+ [Navigate > Jump](#navigate--jump)
|
||||
+ [Pan & Scan > Increase Size](#pan--scan--increase-size)
|
||||
+ [Pan & Scan > Decrease Size](#pan--scan--decrease-size)
|
||||
+ [Pan & Scan > Move Left](#pan--scan--move-left)
|
||||
+ [Pan & Scan > Move Right](#pan--scan--move-right)
|
||||
+ [Pan & Scan > Move Up](#pan--scan--move-up)
|
||||
+ [Pan & Scan > Move Down](#pan--scan--move-down)
|
||||
+ [Pan & Scan > Decrease Height](#pan--scan--decrease-height)
|
||||
+ [Pan & Scan > Increase Height](#pan--scan--increase-height)
|
||||
+ [Pan & Scan > Reset](#pan--scan--reset)
|
||||
+ [Video > Decrease Contrast](#video--decrease-contrast)
|
||||
+ [Video > Increase Contrast](#video--increase-contrast)
|
||||
+ [Video > Decrease Brightness](#video--decrease-brightness)
|
||||
+ [Video > Increase Brightness](#video--increase-brightness)
|
||||
+ [Video > Decrease Gamma](#video--decrease-gamma)
|
||||
+ [Video > Increase Gamma](#video--increase-gamma)
|
||||
+ [Video > Decrease Saturation](#video--decrease-saturation)
|
||||
+ [Video > Increase Saturation](#video--increase-saturation)
|
||||
+ [Video > Take Screenshot](#video--take-screenshot)
|
||||
+ [Video > Toggle Deinterlace](#video--toggle-deinterlace)
|
||||
+ [Video > Cycle Aspect Ratio](#video--cycle-aspect-ratio)
|
||||
+ [Audio > Cycle/Next](#audio--cycle-next)
|
||||
+ [Audio > Delay +0.1](#audio--delay--01)
|
||||
+ [Audio > Delay -0.1](#audio--delay--01)
|
||||
+ [Subtitle > Cycle/Next](#subtitle--cycle-next)
|
||||
+ [Subtitle > Toggle Visibility](#subtitle--toggle-visibility)
|
||||
+ [Subtitle > Delay -0.1](#subtitle--delay--01)
|
||||
+ [Subtitle > Delay 0.1](#subtitle--delay-01)
|
||||
+ [Subtitle > Move Up](#subtitle--move-up)
|
||||
+ [Subtitle > Move Down](#subtitle--move-down)
|
||||
+ [Subtitle > Decrease Subtitle Font Size](#subtitle--decrease-subtitle-font-size)
|
||||
+ [Subtitle > Increase Subtitle Font Size](#subtitle--increase-subtitle-font-size)
|
||||
+ [Volume > Up](#volume--up)
|
||||
+ [Volume > Down](#volume--down)
|
||||
+ [Volume > Mute](#volume--mute)
|
||||
+ [Speed > -10%](#speed---10-)
|
||||
+ [Speed > 10%](#speed--10-)
|
||||
+ [Speed > Half](#speed--half)
|
||||
+ [Speed > Double](#speed--double)
|
||||
+ [Speed > Reset](#speed--reset)
|
||||
+ [Extensions > Rating > 0stars](#extensions--rating--0stars)
|
||||
+ [View > On Top > Enable](#view--on-top--enable)
|
||||
+ [View > On Top > Disable](#view--on-top--disable)
|
||||
+ [View > File Info](#view--file-info)
|
||||
+ [View > Show Statistics](#view--show-statistics)
|
||||
+ [View > Toggle Statistics](#view--toggle-statistics)
|
||||
+ [View > Toggle OSC Visibility](#view--toggle-osc-visibility)
|
||||
+ [View > Show Playlist](#view--show-playlist)
|
||||
+ [View > Show Audio/Video/Subtitle List](#view--show-audio-video-subtitle-list)
|
||||
+ [Settings > Show Config Editor](#settings--show-config-editor)
|
||||
+ [Settings > Show Input Editor](#settings--show-input-editor)
|
||||
+ [Settings > Open Config Folder](#settings--open-config-folder)
|
||||
+ [Tools > Command Palette](#tools--command-palette)
|
||||
+ [Tools > Show History](#tools--show-history)
|
||||
+ [Tools > Set/clear A-B loop points](#tools--set-clear-a-b-loop-points)
|
||||
+ [Tools > Toggle infinite file looping](#tools--toggle-infinite-file-looping)
|
||||
+ [Tools > Toggle Hardware Decoding](#tools--toggle-hardware-decoding)
|
||||
+ [Tools > Show REPL](#tools--show-repl)
|
||||
+ [Tools > OS Setup](#tools--os-setup)
|
||||
+ [Help > Show mpv manual](#help--show-mpv-manual)
|
||||
+ [Help > Show mpv.net manual](#help--show-mpvnet-manual)
|
||||
+ [Help > Check for Updates](#help--check-for-updates)
|
||||
+ [Help > About mpv.net](#help--about-mpvnet)
|
||||
+ [Exit](#exit)
|
||||
+ [Exit Watch Later](#exit-watch-later)
|
||||
|
||||
## About mpv.net
|
||||
|
||||
mpv.net is a modern desktop media player for Windows. mpv is similar to VLC not based on DirectShow like MPC, mpv.net is based on libmpv which in return is based on ffmpeg.
|
||||
|
||||
libmpv provides the majority of the features of the mpv media player, a fork of mplayer. mpv focuses on the usage of the command line interface, mpv.net retains the ability to be used from the command line and adds a modern GUI on top of it.
|
||||
|
||||
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.
|
||||
|
||||
### Target Audience
|
||||
|
||||
The target audience of mpv and mpv.net are programmers, nerds and software enthusiasts that need a desktop player that is more advanced than a normal desktop player. mpv.net is very similar to mpv so it's well suited to learn mpv.
|
||||
|
||||
## Requirements
|
||||
|
||||
mpv.net requires minimum .NET Framework 4.8 and Windows 7. For optimal results a modern graphics card is recommended.
|
||||
|
||||
## Installation
|
||||
|
||||
mpv.net is available as setup and as portable download in the 7zip and Zip archive format, to unpack the portable download 7zip can be used, it is available at www.7-zip.org.
|
||||
|
||||
If you are new to mpv.net the portable download is recommended, for regular mpv.net users the setup is typically more easy to use.
|
||||
|
||||
The x64 editions require more memory and have the advantage of being typically first and better optimized for x64.
|
||||
|
||||
x86 (32-bit) is not recommended but should still be well supported and work but it's not as well tested as x64.
|
||||
|
||||
Stable releases are compiled from the source and can be downloaded from the releases tab:
|
||||
|
||||
<https://github.com/stax76/mpv.net/releases>
|
||||
|
||||
Scoop can be used to install and update it:
|
||||
|
||||
```
|
||||
scoop bucket add extras
|
||||
scoop install mpv.net
|
||||
```
|
||||
|
||||
Alternatively, Chocolatey can also be used:
|
||||
|
||||
`choco install mpvnet.install`
|
||||
|
||||
### File Associations
|
||||
|
||||
File Associations can be created using the setup or with the context menu under 'Tools > OS Setup'.
|
||||
|
||||
After the file associations were registered go to the Windows settings under 'Settings > Apps > Default apps' or shell execute `ms-settings:defaultapps` and choose mpv.net as default app for Video and optionally for Audio and Images.
|
||||
|
||||
It's also possible to change the default application using the 'Open with' feature of the context menu in File Explorer.
|
||||
|
||||
[Open with++](#open-with) can be used to extend the File Explorer context menu to get menu items for 'Play with mpv.net' and 'Add to mpv.net playlist'.
|
||||
|
||||
## External Tools
|
||||
|
||||
### Play with mpv
|
||||
|
||||
In order to play videos from sites such as YouTube the Chrome Extension [Play with mpv](https://chrome.google.com/webstore/detail/play-with-mpv/hahklcmnfgffdlchjigehabfbiigleji) can be used.
|
||||
|
||||
Due to Chrome Extensions not being able to start a app, another app that communicates with the extension is required, this app can be downloaded [here](http://www.mediafire.com/file/lezj8lwqt5zf75v/play-with-mpvnet-server.7z/file). The extension works only when the app is running, to have the app always running a link can be created in the auto start folder located at:
|
||||
|
||||
`C:\Users\%username%\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup`
|
||||
|
||||
This will start the app on system start and have it running in the background. When the file association registration of mpv.net was executed then the app should find the location of mpv.net, alternativly the mpv.net folder can be added to the Path environment variable.
|
||||
|
||||
### External Application Button
|
||||
|
||||
Alternatively the Chrome extension [External Application Button](https://github.com/stax76/mpv.net/issues/106) can be used.
|
||||
|
||||
### Open with++
|
||||
|
||||
Open with++ allows to customize the File Explorer context menu to add menu items 'Play with mpv.net' and 'Add to mpv.net playlist'.
|
||||
|
||||
https://github.com/stax76/OpenWithPlusPlus
|
||||
|
||||
https://github.com/stax76/OpenWithPlusPlus#mpvnet
|
||||
|
||||
https://github.com/stax76/OpenWithPlusPlus#add-to-mpvnet-playlist
|
||||
|
||||
### MediaInfo.NET
|
||||
|
||||
MediaInfo.NET is a media info GUI.
|
||||
|
||||
https://github.com/stax76/MediaInfo.NET
|
||||
|
||||
To start a external application mpv has the run input command (it does not use the shell).
|
||||
|
||||
If the path has spaces then it must be enclosed in quotes and then double backslashes must be used for escaping or alternatively forward slashes.
|
||||
|
||||
`_ run D:\Software\MediaInfoNET.exe "${path}" #menu: Tools > Open file with MediaInfo.NET`
|
||||
|
||||
`_ run "D:\\Soft ware\\MediaInfoNET.exe" "${path}" #menu: Tools > Open file with MediaInfo.NET`
|
||||
|
||||
`_ run "D:/Soft ware/MediaInfoNET.exe" "${path}" #menu: Tools > Open file with MediaInfo.NET`
|
||||
|
||||
## Command Line Interface
|
||||
|
||||
mpvnet implements a command line interface to set mpv commands.
|
||||
|
||||
Supported are all mpv properties which are documented at:
|
||||
|
||||
<https://mpv.io/manual/master>
|
||||
|
||||
Example:
|
||||
|
||||
`mpvnet --mute=yes <file|URL>`
|
||||
|
||||
## Terminal
|
||||
|
||||
When mpv.net is started from a PowerShell terminal it will attach to the terminal and print status and debug messages.
|
||||
|
||||
Certain error and debug messages are only visible on the terminal, JavaScript and Lua scripts must be debugged with the terminal as there is no support for a debugger.
|
||||
|
||||
## Color Theme
|
||||
|
||||
mpv.net supports custom color themes, the definition of the built-in themes can be found at:
|
||||
|
||||
<https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/theme.txt>
|
||||
|
||||
Custom themes can be saved at:
|
||||
|
||||
`<conf folder>\theme.conf`
|
||||
|
||||
The theme.conf file may contain an unlimited amount of themes.
|
||||
|
||||
In the config editor under UI there are the settings dark-theme and light-theme to define the themes used in dark and in light mode.
|
||||
|
||||
## Hidden and secret features
|
||||
|
||||
Selecting multiple files in File Explorer and pressing enter will open the files in mpv.net. Explorer restricts this to maximum 15 files and the order will be random.
|
||||
|
||||
Whenever the control key is pressed when files or URLs are opened, the playlist is not cleared but the files or URLs are appended to the playlist. This works in all mpv.net features that open files or URLs.
|
||||
|
||||
Pressing the shift key while opening a single file will suppress loading all files in the folder.
|
||||
|
||||
## Context Menu
|
||||
|
||||
The most important part of the user interface in mpv.net is the context menu, the menu can be customized as it's defined in the same file where the key and mouse bindings are defined (input.conf).
|
||||
|
||||
### Open > Open Files
|
||||
|
||||
The Open Files menu entry is one way to open files in mpv.net, it supports multi selection.
|
||||
|
||||
Another way to open files is the command line, it is used by the File Explorer if file associations exist.
|
||||
|
||||
When mpv.net is started from a terminal such as PowerShell, mpv.net attaches to the terminal and outputs status and debug messages.
|
||||
|
||||
A third way is to drag and drop files on the main window.
|
||||
|
||||
Whenever the control key is pressed when files or URLs are opened, the playlist is not cleared but the files or URLs are appended to the playlist. This works in all mpv.net features that open files or URLs.
|
||||
|
||||
Pressing the shift key while opening a single file will suppress loading all files in the folder.
|
||||
|
||||
### Open > Open URL
|
||||
|
||||
The Open URL menu entry can be used to open URLs for example from YouTube.
|
||||
|
||||
mpv.net monitors the Windows clipboard and ask if URLs should be played in case it finds a URL in the clipboard. This feature uses a keyword whitelist that can be configured in the config editor.
|
||||
|
||||
When mpv.net is started from a terminal such as PowerShell, mpv.net attaches to the terminal and outputs status and debug messages.
|
||||
|
||||
Whenever the control key is pressed when files or URLs are opened, the playlist is not cleared but the files or URLs are appended to the playlist. This works in all mpv.net features that open files or URLs.
|
||||
|
||||
### Open > Show media search
|
||||
|
||||
mpv.net supports system wide media searches using the Everything indexing service installed by the popular file search tool Everything (www.voidtools.com).
|
||||
|
||||
### Open > Load external audio files
|
||||
|
||||
Allows to load an external audio file. It's also possible to auto detect external audio files based on the file name, the option for this can be found in the settings under 'Settings > Show Config Editor > Audio > audio-file-auto'.
|
||||
|
||||
### Open > Load external subtitle files
|
||||
|
||||
Allows to load an external subtitle file. It's also possible to auto detect external subtitle files based on the file name, the option for this can be found in the settings under 'Settings > Show Config Editor > Subtitles > sub-auto'.
|
||||
|
||||
### Play/Pause
|
||||
|
||||
Play/Pause using the command:
|
||||
|
||||
`cycle pause`
|
||||
|
||||
[cycle command](https://mpv.io/manual/master/#command-interface-cycle-%3Cproperty%3E-[up|down])
|
||||
|
||||
[pause property](https://mpv.io/manual/master/#options-pause)
|
||||
|
||||
### Stop
|
||||
|
||||
Stops the player and unloads the playlist using the command:
|
||||
|
||||
`stop`
|
||||
|
||||
[stop command](https://mpv.io/manual/master/#command-interface-stop)
|
||||
|
||||
### Toggle Fullscreen
|
||||
|
||||
Toggles fullscreen using the command:
|
||||
|
||||
`cycle fullscreen`
|
||||
|
||||
[cycle command](https://mpv.io/manual/master/#command-interface-cycle-%3Cproperty%3E-[up|down])
|
||||
|
||||
[fullscreen property](https://mpv.io/manual/master/#options-fs)
|
||||
|
||||
### Navigate > Previous File
|
||||
|
||||
Navigates to the previous file in the playlist using the command:
|
||||
|
||||
`playlist-prev`
|
||||
|
||||
[playlist-prev command](https://mpv.io/manual/master/#command-interface-playlist-prev)
|
||||
|
||||
### Navigate > Next File
|
||||
|
||||
Navigates to the next file in the playlist using the command:
|
||||
|
||||
`playlist-next`
|
||||
|
||||
[playlist-next command](https://mpv.io/manual/master/#command-interface-playlist-next)
|
||||
|
||||
### Navigate > Next Chapter
|
||||
|
||||
Navigates to the next chapter using the command:
|
||||
|
||||
`add chapter 1`
|
||||
|
||||
[add command](https://mpv.io/manual/master/#command-interface-add-%3Cproperty%3E-[%3Cvalue%3E])
|
||||
|
||||
[chapter property](https://mpv.io/manual/master/#command-interface-chapter)
|
||||
|
||||
### Navigate > Previous Chapter
|
||||
|
||||
Navigates to the previous chapter using the command:
|
||||
|
||||
`add chapter -1`
|
||||
|
||||
[add command](https://mpv.io/manual/master/#command-interface-add-%3Cproperty%3E-[%3Cvalue%3E])
|
||||
|
||||
[chapter property](https://mpv.io/manual/master/#command-interface-chapter)
|
||||
|
||||
### Navigate > Jump Next Frame
|
||||
|
||||
Jumps to the next frame using the command:
|
||||
|
||||
`frame-step`
|
||||
|
||||
[frame-step command](https://mpv.io/manual/master/#command-interface-frame-step)
|
||||
|
||||
### Navigate > Jump Previous Frame
|
||||
|
||||
Jumps to the previous frame using the command:
|
||||
|
||||
`frame-back-step`
|
||||
|
||||
[frame-back-step command](https://mpv.io/manual/master/#command-interface-frame-back-step)
|
||||
|
||||
### Navigate > Jump
|
||||
|
||||
Seeking using the command:
|
||||
|
||||
`no-osd seek sec`
|
||||
|
||||
sec is the relative amount of seconds to jump, the no-osd prefix
|
||||
is used because mpv.net includes a script that shows the position
|
||||
when a seek operation is performed, the script uses a more simple
|
||||
time format.
|
||||
|
||||
[no-osd command prefix](https://mpv.io/manual/master/#command-interface-no-osd)
|
||||
|
||||
[seek command](https://mpv.io/manual/master/#command-interface-[relative|absolute|absolute-percent|relative-percent|exact|keyframes])
|
||||
|
||||
### Pan & Scan > Increase Size
|
||||
|
||||
Adds video zoom using the command:
|
||||
|
||||
`add video-zoom 0.1`
|
||||
|
||||
[add command](https://mpv.io/manual/master/#command-interface-add-%3Cproperty%3E-[%3Cvalue%3E])
|
||||
|
||||
[video-zoom property](https://mpv.io/manual/master/#options-video-zoom)
|
||||
|
||||
### Pan & Scan > Decrease Size
|
||||
|
||||
Adds negative video zoom using the command:
|
||||
|
||||
`add video-zoom -0.1`
|
||||
|
||||
[add command](https://mpv.io/manual/master/#command-interface-add-%3Cproperty%3E-[%3Cvalue%3E])
|
||||
|
||||
[video-zoom property](https://mpv.io/manual/master/#options-video-zoom)
|
||||
|
||||
### Pan & Scan > Move Left
|
||||
|
||||
`add video-pan-x -0.01`
|
||||
|
||||
[add command](https://mpv.io/manual/master/#command-interface-add-%3Cproperty%3E-[%3Cvalue%3E])
|
||||
|
||||
[video-pan-x, video-pan-y property](https://mpv.io/manual/master/#options-video-pan-y)
|
||||
|
||||
### Pan & Scan > Move Right
|
||||
|
||||
`add video-pan-x 0.01`
|
||||
|
||||
[add command](https://mpv.io/manual/master/#command-interface-add-%3Cproperty%3E-[%3Cvalue%3E])
|
||||
|
||||
[video-pan-x, video-pan-y property](https://mpv.io/manual/master/#options-video-pan-y)
|
||||
|
||||
### Pan & Scan > Move Up
|
||||
|
||||
`add video-pan-y -0.01`
|
||||
|
||||
[add command](https://mpv.io/manual/master/#command-interface-add-%3Cproperty%3E-[%3Cvalue%3E])
|
||||
|
||||
[video-pan-x, video-pan-y property](https://mpv.io/manual/master/#options-video-pan-y)
|
||||
|
||||
### Pan & Scan > Move Down
|
||||
|
||||
`add video-pan-y 0.01`
|
||||
|
||||
[add command](https://mpv.io/manual/master/#command-interface-add-%3Cproperty%3E-[%3Cvalue%3E])
|
||||
|
||||
[video-pan-x, video-pan-y property](https://mpv.io/manual/master/#options-video-pan-y)
|
||||
|
||||
### Pan & Scan > Decrease Height
|
||||
|
||||
`add panscan -0.1`
|
||||
|
||||
[add command](https://mpv.io/manual/master/#command-interface-add-%3Cproperty%3E-[%3Cvalue%3E])
|
||||
|
||||
[panscan property](https://mpv.io/manual/master/#options-panscan)
|
||||
|
||||
### Pan & Scan > Increase Height
|
||||
|
||||
`add panscan 0.1`
|
||||
|
||||
[add command](https://mpv.io/manual/master/#command-interface-add-%3Cproperty%3E-[%3Cvalue%3E])
|
||||
|
||||
[panscan property](https://mpv.io/manual/master/#options-panscan)
|
||||
|
||||
### Pan & Scan > Reset
|
||||
|
||||
Resets Pan & Scan, multiple commands in the same line are separated with semicolon.
|
||||
|
||||
`set video-zoom 0; set video-pan-x 0; set video-pan-y 0`
|
||||
|
||||
[video-zoom property](https://mpv.io/manual/master/#options-video-zoom)
|
||||
|
||||
[video-pan-x, video-pan-y property](https://mpv.io/manual/master/#options-video-pan-y)
|
||||
|
||||
### Video > Decrease Contrast
|
||||
|
||||
Decreases contrast with the following command:
|
||||
|
||||
`add contrast -1`
|
||||
|
||||
[add command](https://mpv.io/manual/master/#command-interface-add-%3Cproperty%3E-[%3Cvalue%3E])
|
||||
|
||||
[contrast property](https://mpv.io/manual/master/#options-contrast)
|
||||
|
||||
### Video > Increase Contrast
|
||||
|
||||
Increases contrast with the following command:
|
||||
|
||||
`add contrast 1`
|
||||
|
||||
[add command](https://mpv.io/manual/master/#command-interface-add-%3Cproperty%3E-[%3Cvalue%3E])
|
||||
|
||||
[contrast property](https://mpv.io/manual/master/#options-contrast)
|
||||
|
||||
### Video > Decrease Brightness
|
||||
|
||||
Decreases brightness using the following command:
|
||||
|
||||
`add brightness -1`
|
||||
|
||||
[add command](https://mpv.io/manual/master/#command-interface-add-%3Cproperty%3E-[%3Cvalue%3E])
|
||||
|
||||
[brightness property](https://mpv.io/manual/master/#options-brightness)
|
||||
|
||||
### Video > Increase Brightness
|
||||
|
||||
Increases brightness using the following command:
|
||||
|
||||
`add brightness 1`
|
||||
|
||||
[add command](https://mpv.io/manual/master/#command-interface-add-%3Cproperty%3E-[%3Cvalue%3E])
|
||||
|
||||
[brightness property](https://mpv.io/manual/master/#options-brightness)
|
||||
|
||||
### Video > Decrease Gamma
|
||||
|
||||
Decreases gamma using the following command:
|
||||
|
||||
`add gamma -1`
|
||||
|
||||
[add command](https://mpv.io/manual/master/#command-interface-add-%3Cproperty%3E-[%3Cvalue%3E])
|
||||
|
||||
[gamma property](https://mpv.io/manual/master/#options-gamma)
|
||||
|
||||
### Video > Increase Gamma
|
||||
|
||||
Increases gamma using the following command:
|
||||
|
||||
`add gamma 1`
|
||||
|
||||
[add command](https://mpv.io/manual/master/#command-interface-add-%3Cproperty%3E-[%3Cvalue%3E])
|
||||
|
||||
[gamma property](https://mpv.io/manual/master/#options-gamma)
|
||||
|
||||
### Video > Decrease Saturation
|
||||
|
||||
Decreases saturation using the following command:
|
||||
|
||||
`add saturation -1`
|
||||
|
||||
[add command](https://mpv.io/manual/master/#command-interface-add-%3Cproperty%3E-[%3Cvalue%3E])
|
||||
|
||||
[saturation property](https://mpv.io/manual/master/#options-saturation)
|
||||
|
||||
### Video > Increase Saturation
|
||||
|
||||
Increases saturation using the following command:
|
||||
|
||||
`add saturation 1`
|
||||
|
||||
[add command](https://mpv.io/manual/master/#command-interface-add-%3Cproperty%3E-[%3Cvalue%3E])
|
||||
|
||||
[saturation property](https://mpv.io/manual/master/#options-saturation)
|
||||
|
||||
### Video > Take Screenshot
|
||||
|
||||
`async screenshot`
|
||||
|
||||
[async command prefix](https://mpv.io/manual/master/#command-interface-async)
|
||||
|
||||
[screenshot command](https://mpv.io/manual/master/#command-interface-[subtitles|video|window|single|each-frame])
|
||||
|
||||
### Video > Toggle Deinterlace
|
||||
|
||||
Cycles the deinterlace property using the following command:
|
||||
|
||||
`cycle deinterlace`
|
||||
|
||||
[cycle command](https://mpv.io/manual/master/#command-interface-cycle-%3Cproperty%3E-[up|down])
|
||||
|
||||
[deinterlace property](https://mpv.io/manual/master/#options-deinterlace)
|
||||
|
||||
### Video > Cycle Aspect Ratio
|
||||
|
||||
Cycles the aspect ratio using the following command:
|
||||
|
||||
`cycle-values video-aspect "16:9" "4:3" "2.35:1" "-1"`
|
||||
|
||||
[cycle-values command](https://mpv.io/manual/master/#command-interface-cycle-values)
|
||||
|
||||
[video-aspect property](https://mpv.io/manual/master/#options-video-aspect)
|
||||
|
||||
### Audio > Cycle/Next
|
||||
|
||||
This uses a mpv.net command that shows better info then the mpv preset
|
||||
and also has the advantage of not showing no audio.
|
||||
|
||||
### Audio > Delay +0.1
|
||||
|
||||
Adds a audio delay using the following command:
|
||||
|
||||
`add audio-delay 0.1`
|
||||
|
||||
[add command](https://mpv.io/manual/master/#command-interface-add-%3Cproperty%3E-[%3Cvalue%3E])
|
||||
|
||||
[audio-delay property](https://mpv.io/manual/master/#options-audio-delay)
|
||||
|
||||
### Audio > Delay -0.1
|
||||
|
||||
Adds a negative audio delay using the following command:
|
||||
|
||||
`add audio-delay -0.1`
|
||||
|
||||
[add command](https://mpv.io/manual/master/#command-interface-add-%3Cproperty%3E-[%3Cvalue%3E])
|
||||
|
||||
[audio-delay property](https://mpv.io/manual/master/#options-audio-delay)
|
||||
|
||||
### Subtitle > Cycle/Next
|
||||
|
||||
Shows the next subtitle track using the following command:
|
||||
|
||||
`cycle sub`
|
||||
|
||||
[cycle command](https://mpv.io/manual/master/#command-interface-cycle-%3Cproperty%3E-[up|down])
|
||||
|
||||
[sub/sid property](https://mpv.io/manual/master/#options-sid)
|
||||
|
||||
### Subtitle > Toggle Visibility
|
||||
|
||||
Cycles the subtitle visibility using the following command:
|
||||
|
||||
`cycle sub-visibility`
|
||||
|
||||
[cycle command](https://mpv.io/manual/master/#command-interface-cycle-%3Cproperty%3E-[up|down])
|
||||
|
||||
[sub-visibility property](https://mpv.io/manual/master/#options-no-sub-visibility)
|
||||
|
||||
### Subtitle > Delay -0.1
|
||||
|
||||
Adds a negative subtitle delay using the following command:
|
||||
|
||||
`add sub-delay -0.1`
|
||||
|
||||
[add command](https://mpv.io/manual/master/#command-interface-add-%3Cproperty%3E-[%3Cvalue%3E])
|
||||
|
||||
[sub-delay property](https://mpv.io/manual/master/#options-sub-delay)
|
||||
|
||||
### Subtitle > Delay 0.1
|
||||
|
||||
Adds a positive subtitle delay using the following command:
|
||||
|
||||
`add sub-delay 0.1`
|
||||
|
||||
[add command](https://mpv.io/manual/master/#command-interface-add-%3Cproperty%3E-[%3Cvalue%3E])
|
||||
|
||||
[sub-delay property](https://mpv.io/manual/master/#options-sub-delay)
|
||||
|
||||
### Subtitle > Move Up
|
||||
|
||||
Moves the subtitle up using the following command:
|
||||
|
||||
`add sub-pos -1`
|
||||
|
||||
[add command](https://mpv.io/manual/master/#command-interface-add-%3Cproperty%3E-[%3Cvalue%3E])
|
||||
|
||||
[sub-pos property](https://mpv.io/manual/master/#options-sub-pos)
|
||||
|
||||
### Subtitle > Move Down
|
||||
|
||||
Moves the subtitle down using the following command:
|
||||
|
||||
`add sub-pos 1`
|
||||
|
||||
[add command](https://mpv.io/manual/master/#command-interface-add-%3Cproperty%3E-[%3Cvalue%3E])
|
||||
|
||||
[sub-pos property](https://mpv.io/manual/master/#options-sub-pos)
|
||||
|
||||
### Subtitle > Decrease Subtitle Font Size
|
||||
|
||||
Decreases the subtitle font size using the following command:
|
||||
|
||||
`add sub-scale -0.1`
|
||||
|
||||
[add command](https://mpv.io/manual/master/#command-interface-add-%3Cproperty%3E-[%3Cvalue%3E])
|
||||
|
||||
[sub-scale property](https://mpv.io/manual/master/#options-sub-scale)
|
||||
|
||||
### Subtitle > Increase Subtitle Font Size
|
||||
|
||||
Increases the subtitle font size using the following command:
|
||||
|
||||
`add sub-scale 0.1`
|
||||
|
||||
[add command](https://mpv.io/manual/master/#command-interface-add-%3Cproperty%3E-[%3Cvalue%3E])
|
||||
|
||||
[sub-scale property](https://mpv.io/manual/master/#options-sub-scale)
|
||||
|
||||
### Volume > Up
|
||||
|
||||
Increases the volume using the following command:
|
||||
|
||||
`add volume 10`
|
||||
|
||||
[add command](https://mpv.io/manual/master/#command-interface-add-%3Cproperty%3E-[%3Cvalue%3E])
|
||||
|
||||
[volume property](https://mpv.io/manual/master/#options-volume)
|
||||
|
||||
### Volume > Down
|
||||
|
||||
Decreases the volume using the following command:
|
||||
|
||||
`add volume -10`
|
||||
|
||||
[add command](https://mpv.io/manual/master/#command-interface-add-%3Cproperty%3E-[%3Cvalue%3E])
|
||||
|
||||
[volume property](https://mpv.io/manual/master/#options-volume)
|
||||
|
||||
### Volume > Mute
|
||||
|
||||
Cycles the mute property using the following command:
|
||||
|
||||
`cycle mute`
|
||||
|
||||
[cycle command](https://mpv.io/manual/master/#command-interface-cycle-%3Cproperty%3E-[up|down])
|
||||
|
||||
[mute property](https://mpv.io/manual/master/#options-mute)
|
||||
|
||||
### Speed > -10%
|
||||
|
||||
Decreases the speed by 10% using the following command:
|
||||
|
||||
`multiply speed 1/1.1`
|
||||
|
||||
[multiply command](https://mpv.io/manual/master/#command-interface-multiply-%3Cproperty%3E-%3Cfactor%3E)
|
||||
|
||||
[speed property](https://mpv.io/manual/master/#options-speed)
|
||||
|
||||
### Speed > 10%
|
||||
|
||||
Increases the speed by 10% using the following command:
|
||||
|
||||
`multiply speed 1.1`
|
||||
|
||||
[multiply command](https://mpv.io/manual/master/#command-interface-multiply-%3Cproperty%3E-%3Cfactor%3E)
|
||||
|
||||
[speed property](https://mpv.io/manual/master/#options-speed)
|
||||
|
||||
### Speed > Half
|
||||
|
||||
Halfs the speed using the following command:
|
||||
|
||||
`multiply speed 0.5`
|
||||
|
||||
[multiply command](https://mpv.io/manual/master/#command-interface-multiply-%3Cproperty%3E-%3Cfactor%3E)
|
||||
|
||||
[speed property](https://mpv.io/manual/master/#options-speed)
|
||||
|
||||
### Speed > Double
|
||||
|
||||
Doubles the speed using the following command:
|
||||
|
||||
`multiply speed 2`
|
||||
|
||||
[multiply command](https://mpv.io/manual/master/#command-interface-multiply-%3Cproperty%3E-%3Cfactor%3E)
|
||||
|
||||
[speed property](https://mpv.io/manual/master/#options-speed)
|
||||
|
||||
### Speed > Reset
|
||||
|
||||
Resets the speed using the following command:
|
||||
|
||||
`set speed 1`
|
||||
|
||||
[set command](https://mpv.io/manual/master/#command-interface-set-%3Cproperty%3E-%22%3Cvalue%3E%22)
|
||||
|
||||
[speed property](https://mpv.io/manual/master/#options-speed)
|
||||
|
||||
### Extensions > Rating > 0stars
|
||||
|
||||
A plugin the writes the rating to the filename.
|
||||
|
||||
### View > On Top > Enable
|
||||
|
||||
Forces the player to stay on top of other windows using the following command:
|
||||
|
||||
`set ontop yes`
|
||||
|
||||
[set command](https://mpv.io/manual/master/#command-interface-set-%3Cproperty%3E-%22%3Cvalue%3E%22)
|
||||
|
||||
[ontop property](https://mpv.io/manual/master/#options-ontop)
|
||||
|
||||
### View > On Top > Disable
|
||||
|
||||
Disables the player to stay on top of other windows using the following command:
|
||||
|
||||
`set ontop no`
|
||||
|
||||
[set command](https://mpv.io/manual/master/#command-interface-set-%3Cproperty%3E-%22%3Cvalue%3E%22)
|
||||
|
||||
[ontop property](https://mpv.io/manual/master/#options-ontop)
|
||||
|
||||
### View > File Info
|
||||
|
||||
Shows info using a mpv.net command about the current file, shows length, position, formats, size and filename.
|
||||
|
||||
### View > Show Statistics
|
||||
|
||||
Show statistics using the following command:
|
||||
|
||||
`script-binding stats/display-stats`
|
||||
|
||||
[script-binding command](https://mpv.io/manual/master/#command-interface-script-binding)
|
||||
|
||||
### View > Toggle Statistics
|
||||
|
||||
Toggles statistics using the following command:
|
||||
|
||||
`script-binding stats/display-stats-toggle`
|
||||
|
||||
[script-binding command](https://mpv.io/manual/master/#command-interface-script-binding)
|
||||
|
||||
### View > Toggle OSC Visibility
|
||||
|
||||
Toggles OSC Visibility using the following command:
|
||||
|
||||
`script-binding osc/visibility`
|
||||
|
||||
[script-binding command](https://mpv.io/manual/master/#command-interface-script-binding)
|
||||
|
||||
### View > Show Playlist
|
||||
|
||||
Shows the playlist for 5 seconds using the following command:
|
||||
|
||||
`show-text ${playlist} 5000`
|
||||
|
||||
[show-text command](https://mpv.io/manual/master/#command-interface-show-text)
|
||||
|
||||
### View > Show Audio/Video/Subtitle List
|
||||
|
||||
Shows the Audio/Video/Subtitle list for 5 seconds using the following command:
|
||||
|
||||
`show-text ${track-list} 5000`
|
||||
|
||||
[show-text command](https://mpv.io/manual/master/#command-interface-show-text)
|
||||
|
||||
### Settings > Show Config Editor
|
||||
|
||||
Shows mpv.net's config editor.
|
||||
|
||||
### Settings > Show Input Editor
|
||||
|
||||
Shows mpv.net's key binding editor.
|
||||
|
||||
### Settings > Open Config Folder
|
||||
|
||||
Opens the config folder which contains:
|
||||
|
||||
mpv.conf file containing mpv settings
|
||||
|
||||
mpvnet.conf file containing mpv.net settings
|
||||
|
||||
input.conf containing mpv key and mouse bindings
|
||||
|
||||
User scripts and user extensions
|
||||
|
||||
### Tools > Command Palette
|
||||
|
||||
Shows the command palette window which allows to quickly find and execute commands and key shortcuts.
|
||||
|
||||
### Tools > Show History
|
||||
|
||||
Shows a text file that contains the file history. If the file don't exist it asks if the file should be created in the settings folder. Once the file exist then the history is logged. It logges the playback history containing the time and filename.
|
||||
|
||||
### Tools > Set/clear A-B loop points
|
||||
|
||||
Enables to set loop start and end points using the following command:
|
||||
|
||||
`ab-loop`
|
||||
|
||||
[ab-loop command](https://mpv.io/manual/master/#command-interface-ab-loop)
|
||||
|
||||
### Tools > Toggle infinite file looping
|
||||
|
||||
Loops the current file infinitely using the following command:
|
||||
|
||||
cycle-values loop-file "inf" "no"
|
||||
|
||||
[cycle-values command](https://mpv.io/manual/master/#command-interface-cycle-values)
|
||||
|
||||
[loop-file command](https://mpv.io/manual/master/#options-loop)
|
||||
|
||||
### Tools > Toggle Hardware Decoding
|
||||
|
||||
Cycles the hwdec property to enable/disable hardware decoding using the following command:
|
||||
|
||||
`cycle-values hwdec "auto" "no"`
|
||||
|
||||
[cycle-values command](https://mpv.io/manual/master/#command-interface-cycle-values)
|
||||
|
||||
[hwdec property](https://mpv.io/manual/master/#options-hwdec)
|
||||
|
||||
### Tools > Show REPL
|
||||
|
||||
Shows a on screen REPL.
|
||||
|
||||
https://github.com/rossy/mpv-repl
|
||||
|
||||
### Tools > OS Setup
|
||||
|
||||
Allows to manage file associations.
|
||||
|
||||
### Help > Show mpv manual
|
||||
|
||||
Shows the [mpv manual](https://mpv.io/manual/stable/).
|
||||
|
||||
### Help > Show mpv.net web site
|
||||
|
||||
Shows the [mpv.net web site](https://mpv-net.github.io/mpv.net-web-site/).
|
||||
|
||||
### Help > Show mpv.net manual
|
||||
|
||||
Shows the [mpv.net manual](https://github.com/stax76/mpv.net/blob/master/Manual.md).
|
||||
|
||||
### Help > Check for Updates
|
||||
|
||||
Checks for updates and allows to execute the update routine.
|
||||
|
||||
The update routine requires PowerShell 5 and curl, an up to date Windows 10 system has both included.
|
||||
|
||||
### Help > About mpv.net
|
||||
|
||||
Shows the mpv.net about dialog which shows a copyright notice, the versions of mpv.net and libmpv and a license notice (MIT).
|
||||
|
||||
### Exit
|
||||
|
||||
Exits mpv.net using the following command:
|
||||
|
||||
`quit`
|
||||
|
||||
[quit command](https://mpv.io/manual/master/#command-interface-quit-[%3Ccode%3E])
|
||||
|
||||
### Exit Watch Later
|
||||
|
||||
Exits mpv.net and remembers the position in the file using the following command:
|
||||
|
||||
`quit-watch-later`
|
||||
|
||||
[quit-watch-later command](https://mpv.io/manual/master/#command-interface-quit-watch-later)
|
||||
253
README.md
@@ -1,60 +1,93 @@
|
||||
# mpv.net
|
||||

|
||||
|
||||
mpv.net is a modern media player for Windows that looks and works just like [mpv](https://mpv.io).
|
||||
     [](https://www.paypal.me/stax76)
|
||||
|
||||
#### Based on libmpv
|
||||
# 🎞 mpv.net
|
||||
|
||||
mpv.net is based on libmpv which offers a straightforward C API that was designed from the ground up to make mpv usable as a library and facilitate easy integration into other applications.
|
||||
mpv.net is a modern media player for Windows that works just like [mpv](https://mpv.io).
|
||||
|
||||
#### CLI options
|
||||
#### Graphical User Interface
|
||||
|
||||
mpv.net has the same [CLI options](https://mpv.io/manual/master/#options) as mpv.
|
||||
Modern GUI that supports customizable color themes.
|
||||
|
||||
#### Command Line Interface
|
||||
|
||||
mpv.net has the [CLI of mpv](https://mpv.io/manual/master/#options).
|
||||
|
||||
#### High quality video output
|
||||
|
||||
mpv/libmpv has an OpenGL based video output that is capable of many features loved by videophiles, such as video scaling with popular high quality algorithms, color management, frame timing, interpolation, HDR, and more.
|
||||
libmpv has an OpenGL based video output that is capable of many features loved by videophiles, such as video scaling with popular high quality algorithms, color management, frame timing, interpolation, HDR, and more.
|
||||
|
||||
#### On Screen Controller
|
||||
|
||||
mpv.net uses the OSC of mpv/libmpv offering play controls with a modern flat design.
|
||||
The OSC of libmpv offers play controls with a modern flat design. ([Screenshot](#main-window-screenshot))
|
||||
|
||||
#### GPU video decoding
|
||||
|
||||
mpv/libmpv leverages the FFmpeg hwaccel APIs to support DXVA2 video decoding acceleration.
|
||||
libmpv leverages the FFmpeg hwaccel APIs to support DXVA2 video decoding acceleration.
|
||||
|
||||
#### Active development
|
||||
|
||||
mpv.net is under active development. Want a feature? Post a [patch](https://github.com/stax76/mpv.net/pulls) or [request it](https://github.com/stax76/mpv.net/issues)!
|
||||
|
||||
#### Based on libmpv
|
||||
|
||||
mpv.net is based on libmpv which offers a straightforward C API that was designed from the ground up to make mpv usable as a library and facilitate easy integration into other applications. mpv is like vlc not based on DirectShow or Media Foundation.
|
||||
|
||||
Table of contents
|
||||
-----------------
|
||||
|
||||
- [Features](#features)
|
||||
- [Screenshots](#screenshots)
|
||||
- [Installation](#installation)
|
||||
- [Manual](#manual)
|
||||
- [Context Menu](#context-menu)
|
||||
- [Settings](#settings)
|
||||
- [Scripting](#scripting)
|
||||
- [Add-ons](#add-ons)
|
||||
- [Extensions](#extensions)
|
||||
- [Architecture](#architecture)
|
||||
- [Support](#support)
|
||||
- [Links](#links)
|
||||
- [Download](#download)
|
||||
- [Changelog](#changelog)
|
||||
|
||||
### Features
|
||||
|
||||
- Customizable context menu defined in the same file as the key bindings ([Screenshot](#context-menu-screenshot))
|
||||
- Searchable config dialog ([Screenshot](#config-editor-screenshot))
|
||||
- Searchable input (key/mouse) binding editor ([Screenshot](#input-editor-screenshot))
|
||||
- Searchable command palette to quickly launch commands and look for keys ([Screenshot](#command-palette-screenshot))
|
||||
- Modern UI with dark mode ([Screenshot](#config-editor-screenshot))
|
||||
- Addon/extension API for .NET languages
|
||||
- Scripting API for Python, C#, Lua, JavaScript and PowerShell ([wiki](https://github.com/stax76/mpv.net/wiki/Scripting))
|
||||
- mpv's OSC, IPC and conf files
|
||||
- Support of the same [CLI options](https://mpv.io/manual/master/#options) as mpv
|
||||
- Very high degree of mpv compatibility, almost all mpv features are available
|
||||
- Great usability due to everything in the application being searchable
|
||||
- Open source built with modern tools
|
||||
- Customizable context menu defined in the same file as the key bindings ([Screenshot](#context-menu-screenshot), [Defaults](https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/inputConf.txt))
|
||||
- Searchable config dialog ([Screenshot](#config-editor-screenshot), [Defaults](https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/mpvConf.txt))
|
||||
- Searchable input (key/mouse) binding editor ([Screenshot](#input-editor-screenshot), [Defaults](https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/inputConf.txt))
|
||||
- Configuration files that are easy to read and edit ([Manual](https://mpv.io/manual/master/#configuration-files))
|
||||
- Searchable command palette to quickly find commands and keys ([Screenshot](#command-palette-screenshot))
|
||||
- Modern graphical user interface with customizable color themes ([Screenshot](#config-editor-screenshot))
|
||||
- [Extension API for .NET languages (C#, VB.NET and F#)](https://github.com/stax76/mpv.net/wiki/Extensions)
|
||||
- Scripting API for Python, C#, Lua, JavaScript and PowerShell ([Wiki](https://github.com/stax76/mpv.net/wiki/Scripting))
|
||||
- Language agnostic JSON IPC to control the player with a external programs
|
||||
- On Screen Controler (OSC, play control buttons) ([Screenshot](#main-window-screenshot))
|
||||
- [Command Line Interface](https://mpv.io/manual/master/#options)
|
||||
- If started from a PowerShell terminal mpv.net will attach to the terminal and print status and debug output ([Screenshot](#terminal-and-repl-screenshot))
|
||||
- [OSD REPL](https://github.com/rossy/mpv-repl)
|
||||
- DXVA2 video decoding acceleration
|
||||
- OpenGL based video output capable of features loved by videophiles, such as video scaling with popular high quality algorithms, color management, frame timing, interpolation, HDR, and more
|
||||
- Search feature powered by [Everything](https://www.voidtools.com) to find and play media ([Screenshot](#media-search-screenshot))
|
||||
- Extension to start mpv.net from Google Chrome ([Manual](Manual.md#chrome-extension))
|
||||
- Extremely fast seek performance
|
||||
- Very fast startup performance, video is usally ready to play in less then a second
|
||||
- Usable as video player, audio player and image viewer with a wide range of supported formats
|
||||
- All decoders are built-in, no external codecs have to be installed
|
||||
- Setup and portable download options, setup is recommended but not required
|
||||
- Build-in media streaming via youtube-dl
|
||||
- x64 and x86 Support (64-bit and 32-bit)
|
||||
- File associations can be created by the setup and from the player
|
||||
- External audio and subtitle files can either be loaded manually or automatically
|
||||
- Screenshot feature with many options
|
||||
- File history feature to log time and filename
|
||||
- A-B loop feature
|
||||
- Watch later feature to save the position
|
||||
- Files can be enqueued from File Explorer ([Manual](Manual.md#open-with))
|
||||
- Update check and update routine ([Manual](Manual.md#help--check-for-updates))
|
||||
- [Manual](#manual)
|
||||
|
||||
### Screenshots
|
||||
|
||||
@@ -74,6 +107,12 @@ A searchable config editor as alternative to edit the mpv.conf file manually.
|
||||
|
||||

|
||||
|
||||
#### Terminal and REPL Screenshot
|
||||
|
||||
mpv.net attached to a PowerShell terminal showing the [OSD REPL](https://github.com/rossy/mpv-repl).
|
||||
|
||||

|
||||
|
||||
#### Input Editor Screenshot
|
||||
|
||||
A searchable key and mouse binding editor.
|
||||
@@ -83,7 +122,7 @@ A searchable key and mouse binding editor.
|
||||
#### Command Palette Screenshot
|
||||
|
||||
Forgot where a command in the menu is located or what shortcut key it has?
|
||||
Just press Ctrl+Shift+P and find it easily in the searchable command palette.
|
||||
Just press F1 and find it easily in the searchable command palette.
|
||||
|
||||

|
||||
|
||||
@@ -93,6 +132,29 @@ Media search feature powered by [Everything](https://www.voidtools.com) to find
|
||||
|
||||

|
||||
|
||||
### Installation
|
||||
|
||||
mpv.net requires minimum .NET Framework 4.8 and Windows 7. For optimal results a modern graphics card is recommended.
|
||||
|
||||
Stable releases are compiled from the source and can be downloaded from the releases tab:
|
||||
|
||||
<https://github.com/stax76/mpv.net/releases>
|
||||
|
||||
Scoop can be used to install and update it:
|
||||
|
||||
```
|
||||
scoop bucket add extras
|
||||
scoop install mpv.net
|
||||
```
|
||||
|
||||
Alternatively, Chocolatey can also be used:
|
||||
|
||||
`choco install mpvnet.install`
|
||||
|
||||
### Manual
|
||||
|
||||
[Manual](Manual.md)
|
||||
|
||||
### Context Menu
|
||||
|
||||
The context menu can be customized via input.conf file located in the config directory:
|
||||
@@ -109,55 +171,81 @@ input.conf defines mpv's key and mouse bindings and mpv.net uses comments to def
|
||||
|
||||
### Settings
|
||||
|
||||
mpv.net is able to share the settings with mpv and mpv.net uses the same logic to decide from where the settings are loaded. The default location is:
|
||||
When mpv.net finds no config folder on startup it will ask for a location.
|
||||
|
||||
If a folder named portable_config next to the mpvnet.exe exists,
|
||||
all config will be loaded from this folder only.
|
||||
|
||||
```Text
|
||||
C:\Users\%username%\AppData\Roaming\mpv\mpv.conf
|
||||
<startup>\portable_config\
|
||||
```
|
||||
|
||||
If a directory named portable_config next to the mpvnet.exe exists, all config will be loaded from this directory only.
|
||||
|
||||
```Text
|
||||
<startup>\portable_config\mpv.conf
|
||||
```
|
||||
|
||||
In case there isn't any config folder mpv.net asks where to create it. If no mpv.conf file exists mpv.net generates it with the following defaults:
|
||||
mpv specific settings are stored in the file mpv.conf, if no mpv.conf file exists
|
||||
mpv.net generates it with the following defaults:
|
||||
|
||||
<https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/mpvConf.txt>
|
||||
|
||||
Config files located in the same directory as mpvnet.exe are loaded with lower priority. Some config files are loaded only once, which means that e.g. of 2 input.conf files located in two config directories, only the one from the directory with higher priority will be loaded.
|
||||
mpv.net specific settings are stored in the file mpvnet.conf
|
||||
|
||||
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:
|
||||
|
||||
<https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/inputConf.txt>
|
||||
|
||||
mpv.net supports almost all mpv settings and features,
|
||||
[limitations are listed in the wiki](https://github.com/stax76/mpv.net/wiki/Limitations).
|
||||
|
||||
The config folder can be opened from the context menu.
|
||||
|
||||
### Scripting
|
||||
|
||||
[Scripting wiki page](https://github.com/stax76/mpv.net/wiki/Scripting)
|
||||
|
||||
### Add-ons
|
||||
### Extensions
|
||||
|
||||
[Add-on wiki page](https://github.com/stax76/mpv.net/wiki/Addons)
|
||||
[Extensions wiki page](https://github.com/stax76/mpv.net/wiki/Extensions)
|
||||
|
||||
### Architecture
|
||||
|
||||
mpv.net is written in C# 7.0 and runs on the .NET framework 4.7 or higher.
|
||||
Coding mpv.net was great fun because libmpv is such a awesome
|
||||
library with a very clever design, I'm having a great experience
|
||||
with libmpv.
|
||||
|
||||
The Add-on implementation is based on the Managed Extensibility Framework,
|
||||
the entire application code is accessible for add-ons and Python scripts.
|
||||
The player does not contain any feature that was more work than 1-2 days or
|
||||
was difficult to build, the hard parts are totally covered by libmpv.
|
||||
|
||||
mpv.net is written in C# 7 and runs on .NET 4.7, I've not yet decided
|
||||
if I will port it to C# 8 and .NET 5 once available.
|
||||
|
||||
The Extension implementation is based on the [Managed Extensibility Framework](https://docs.microsoft.com/en-us/dotnet/framework/mef/).
|
||||
|
||||
There are no specific extension or scripting interfaces but instead everyting
|
||||
is accessible for .NET compatible languages (C#, VB.NET, F#, Python, PowerShell),
|
||||
this decision was made to keep the code simple and lightweight.
|
||||
|
||||
Python scripting is implemented with IronPython which uses Python 2.7.
|
||||
|
||||
The main/video window is WinForms based, other windows are WPF based.
|
||||
The main window is WinForms based and uses less than 750 lines of code,
|
||||
all other windows are WPF based and use even less code.
|
||||
|
||||
The config editor adds it's controls dynamically and uses TOML to define it's
|
||||
The config editor adds it's controls dynamically and uses [TOML](https://en.wikipedia.org/wiki/TOML) to define it's
|
||||
content, there are only two simple types, StringSetting and OptionSetting.
|
||||
|
||||
mpv.net was started 2017 and consists of about 9000 lines of code.
|
||||
mpv.net was started 2017 and consists of about 6000 lines of code and markup.
|
||||
|
||||
Third party components are:
|
||||
IDE, Editor: Visual Studio, Visual Studio Code.
|
||||
|
||||
- [libmpv](https://mpv.io/)
|
||||
- [MediaInfo](https://mediaarea.net/en/MediaInfo)
|
||||
- [Tommy (TOML parser)](https://github.com/dezhidki/Tommy)
|
||||
- [IronPython](https://ironpython.net/)
|
||||
- [CS-Script](http://www.csscript.net/)
|
||||
Due to mpv.net being my first WPF app and mpv.net never meant to be a large
|
||||
application best practices and design pattern are not always applied.
|
||||
|
||||
Third party components:
|
||||
|
||||
- [libmpv, the heard and soul of mpv.net](https://mpv.io/)
|
||||
- [MediaInfo, no media related project could do without](https://mediaarea.net/en/MediaInfo)
|
||||
- [Tommy, a single file TOML parser](https://github.com/dezhidki/Tommy)
|
||||
- [IronPython, bringing Python to dotnet](https://ironpython.net/)
|
||||
- [CS-Script, scripting with C#](http://www.csscript.net/)
|
||||
- [Everything, a blazing fast file search service](https://www.voidtools.com)
|
||||
|
||||
### Support
|
||||
|
||||
@@ -165,62 +253,31 @@ Third party components are:
|
||||
|
||||
[Support thread in VideoHelp forum](https://forum.videohelp.com/threads/392514-mpv-net-a-extendable-media-player-for-windows)
|
||||
|
||||
[Issue tracker to report bugs and request features](https://github.com/stax76/mpv.net/issues)
|
||||
[Issue tracker](https://github.com/stax76/mpv.net/issues), feel free to use for anything mpv.net related
|
||||
|
||||
[frank.skare.de@gmail.com](mailto:frank.skare.de@gmail.com?Subject=mpv.net%20support)
|
||||
|
||||
Please click on the star at the top of the page and like mpv.net at [alternativeto.net](https://alternativeto.net/software/mpv-net/).
|
||||
|
||||
If you want to support the development of mpv.net or express your appreciation you can do so with a donation:
|
||||
|
||||
<https://www.paypal.me/stax76>
|
||||
|
||||
### Links
|
||||
|
||||
mpv manual: <https://mpv.io/manual/master/>
|
||||
|
||||
mpv wiki: <https://github.com/mpv-player/mpv/wiki>
|
||||
|
||||
mpv.net wiki: <https://github.com/stax76/mpv.net/wiki>
|
||||
|
||||
mpv apps: <https://github.com/mpv-player/mpv/wiki/Applications-using-mpv>
|
||||
|
||||
mpv user scripts: <https://github.com/mpv-player/mpv/wiki/User-Scripts>
|
||||
|
||||
mpv default key bindings: <https://github.com/mpv-player/mpv/blob/master/etc/input.conf>
|
||||
|
||||
mpv.net default key bindings: <https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/inputConf.txt>
|
||||
|
||||
mpv download: <https://mpv.io/installation/>
|
||||
|
||||
mpv.net download: <https://github.com/stax76/mpv.net/releases>
|
||||
|
||||
mpv bugs and requests: <https://mpv.io/bug-reports/>
|
||||
|
||||
mpv.net bugs and requests: <https://github.com/stax76/mpv.net/issues>
|
||||
|
||||
### Download
|
||||
|
||||
<https://github.com/stax76/mpv.net/releases>
|
||||
- mpv.net wiki: <https://github.com/stax76/mpv.net/wiki>
|
||||
- mpv.net default key bindings: <https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/inputConf.txt>
|
||||
- mpv.net download: <https://github.com/stax76/mpv.net/releases>
|
||||
- mpv.net bugs and requests: <https://github.com/stax76/mpv.net/issues>
|
||||
- mpv website: <https://mpv.io/>
|
||||
- mpv manual: <https://mpv.io/manual/master/>
|
||||
- mpv wiki: <https://github.com/mpv-player/mpv/wiki>
|
||||
- mpv apps: <https://github.com/mpv-player/mpv/wiki/Applications-using-mpv>
|
||||
- mpv user scripts: <https://github.com/mpv-player/mpv/wiki/User-Scripts>
|
||||
- mpv default key bindings: <https://github.com/mpv-player/mpv/blob/master/etc/input.conf>
|
||||
- mpv download: <https://mpv.io/installation/>
|
||||
- mpv bugs and requests: <https://mpv.io/bug-reports/>
|
||||
|
||||
### Changelog
|
||||
|
||||
### 3.6.1
|
||||
|
||||
- there was a bug causing an exception if both the input editor and config editor
|
||||
is opened, as soon as one is opened, the other can't be opened
|
||||
|
||||
### 3.6
|
||||
|
||||
- playing files from rar archives caused an exception
|
||||
- there was a bug that caused underscores beeing removed from input like MBTN_LEFT_DBL
|
||||
- the search clear button in the input editor had a render issue in dark mode
|
||||
- new search feature added to search and play media files, requires
|
||||
[Everything](https://www.voidtools.com) to be installed. [Default Binding](https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/inputConf.txt#L29)
|
||||
|
||||
### 3.5
|
||||
|
||||
- when the main windows gets activated and the clipboard content starts with http
|
||||
mpv.net will ask to play the URL, previously this was restricted to YouTube URLs
|
||||
- Python script errors show line and column whenever it is supported by IronPython
|
||||
- if conf files exist in the startup directory mpv.net will use the startup
|
||||
directory as config directory instead of creating default conf files in appdata
|
||||
- renamed commands are handled now by migration code instead of being broken
|
||||
|
||||
### 3.4
|
||||
|
||||
- new feature added to manage file associations from within the app. It can be found in the menu at: Tools > Manage... [Default Binding](https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/inputConf.txt#L149)
|
||||
- new zip download option added
|
||||
- new x86 download option added
|
||||
[Changelog](Changelog.md)
|
||||
|
||||
66
Release.ps1
Normal file
@@ -0,0 +1,66 @@
|
||||
|
||||
$ErrorActionPreference = 'Stop'
|
||||
|
||||
$desktopDir = [Environment]::GetFolderPath('Desktop')
|
||||
$exePath = (Get-Location).Path + '\mpv.net\bin\x64\mpvnet.exe'
|
||||
$version = [Reflection.Assembly]::LoadFile($exePath).GetName().Version
|
||||
$msbuild = 'C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Current\Bin\MSBuild.exe'
|
||||
$iscc = 'C:\Program Files (x86)\Inno Setup 6\ISCC.exe'
|
||||
$7z = 'C:\Program Files\7-Zip\7z.exe'
|
||||
|
||||
if ($version.Revision -ne 0)
|
||||
{
|
||||
& $msbuild mpv.net.sln /p:Configuration=Debug /p:Platform=x64
|
||||
if ($LastExitCode) { throw $LastExitCode }
|
||||
|
||||
$targetDir = "$desktopDir\mpv.net-portable-x64-$version-beta"
|
||||
Copy-Item .\mpv.net\bin\x64 $targetDir -Recurse -Exclude System.Management.Automation.xml
|
||||
& $7z a -t7z -mx9 "$targetDir.7z" -r "$targetDir\*"
|
||||
if ($LastExitCode) { throw $LastExitCode }
|
||||
|
||||
$targetDirectories = 'C:\Users\frank\OneDrive\StaxRip\TestBuilds\',
|
||||
'C:\Users\frank\Dropbox\public\StaxRip\Builds\'
|
||||
|
||||
foreach ($dir in $targetDirectories)
|
||||
{
|
||||
if (Test-Path $dir)
|
||||
{
|
||||
Copy-Item ($targetDir + '.7z') ($dir + (Split-Path $targetDir -Leaf) + '.7z')
|
||||
Invoke-Item $dir
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
& $msbuild mpv.net.sln /p:Configuration=Debug /p:Platform=x64
|
||||
if ($LastExitCode) { throw $LastExitCode }
|
||||
|
||||
& $msbuild mpv.net.sln /p:Configuration=Debug /p:Platform=x86
|
||||
if ($LastExitCode) { throw $LastExitCode }
|
||||
|
||||
& $iscc /Darch=x64 setup.iss
|
||||
if ($LastExitCode) { throw $LastExitCode }
|
||||
|
||||
& $iscc /Darch=x86 setup.iss
|
||||
if ($LastExitCode) { throw $LastExitCode }
|
||||
|
||||
$targetDir = $desktopDir + "\mpv.net-portable-x64-$version"
|
||||
Copy-Item .\mpv.net\bin\x64 $targetDir -Recurse -Exclude System.Management.Automation.xml
|
||||
|
||||
& $7z a -t7z -mx9 "$targetDir.7z" -r "$targetDir\*"
|
||||
if ($LastExitCode) { throw $LastExitCode }
|
||||
|
||||
& $7z a -tzip -mx9 "$targetDir.zip" -r "$targetDir\*"
|
||||
if ($LastExitCode) { throw $LastExitCode }
|
||||
|
||||
$targetDir = $desktopDir + "\mpv.net-portable-x86-$version"
|
||||
Copy-Item .\mpv.net\bin\x86 $targetDir -Recurse -Exclude System.Management.Automation.xml
|
||||
|
||||
& $7z a -t7z -mx9 "$targetDir.7z" -r "$targetDir\*"
|
||||
if ($LastExitCode) { throw $LastExitCode }
|
||||
|
||||
& $7z a -tzip -mx9 "$targetDir.zip" -r "$targetDir\*"
|
||||
if ($LastExitCode) { throw $LastExitCode }
|
||||
}
|
||||
|
||||
Write-Host 'successfully finished' -ForegroundColor Green
|
||||
@@ -1,35 +0,0 @@
|
||||
Imports System.ComponentModel.Composition
|
||||
Imports System.IO
|
||||
Imports System.Windows.Forms
|
||||
|
||||
Imports mpvnet
|
||||
|
||||
Imports CSScriptLibrary
|
||||
|
||||
<Export(GetType(IAddon))>
|
||||
Public Class CSScriptAddon
|
||||
Implements IAddon
|
||||
|
||||
Sub New()
|
||||
Dim scriptFiles As New List(Of String)
|
||||
|
||||
If Directory.Exists(mp.MpvConfFolder + "scripts") Then
|
||||
scriptFiles.AddRange(Directory.GetFiles(mp.MpvConfFolder + "scripts", "*.cs"))
|
||||
End If
|
||||
|
||||
If Directory.Exists(Application.StartupPath + "\scripts") Then
|
||||
scriptFiles.AddRange(Directory.GetFiles(Application.StartupPath + "\scripts", "*.cs"))
|
||||
End If
|
||||
|
||||
If scriptFiles.Count = 0 Then Return
|
||||
CSScriptLibrary.CSScript.EvaluatorConfig.Engine = EvaluatorEngine.CodeDom
|
||||
|
||||
For Each i In scriptFiles
|
||||
Try
|
||||
CSScriptLibrary.CSScript.Evaluator.LoadCode(File.ReadAllText(i))
|
||||
Catch ex As Exception
|
||||
Msg.ShowException(ex)
|
||||
End Try
|
||||
Next
|
||||
End Sub
|
||||
End Class
|
||||
@@ -1,166 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{71808A87-8B1C-4DF8-957C-D79C3B164CCA}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<RootNamespace>CSScriptAddon</RootNamespace>
|
||||
<AssemblyName>CSScriptAddon</AssemblyName>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<MyType>Windows</MyType>
|
||||
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
|
||||
<TargetFrameworkProfile />
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<DefineDebug>true</DefineDebug>
|
||||
<DefineTrace>true</DefineTrace>
|
||||
<OutputPath>..\mpv.net\bin\Addons\CSScriptAddon\</OutputPath>
|
||||
<DocumentationFile>
|
||||
</DocumentationFile>
|
||||
<NoWarn>42105,42106,42107,42353,42354,42355</NoWarn>
|
||||
<WarningsAsErrors>41999,42016,42017,42018,42019,42020,42021,42022,42032,42036</WarningsAsErrors>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<DefineDebug>false</DefineDebug>
|
||||
<DefineTrace>true</DefineTrace>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>..\mpv.net\bin\Addons\CSScriptAddon\</OutputPath>
|
||||
<DocumentationFile>
|
||||
</DocumentationFile>
|
||||
<NoWarn>42105,42106,42107,42353,42354,42355</NoWarn>
|
||||
<WarningsAsErrors>41999,42016,42017,42018,42019,42020,42021,42022,42032,42036</WarningsAsErrors>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<OptionExplicit>On</OptionExplicit>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<OptionCompare>Binary</OptionCompare>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<OptionStrict>On</OptionStrict>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<OptionInfer>On</OptionInfer>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DefineDebug>true</DefineDebug>
|
||||
<DefineTrace>true</DefineTrace>
|
||||
<OutputPath>..\..\mpv.net\bin\x86\Addons\CSScriptAddon\</OutputPath>
|
||||
<NoWarn>42105,42106,42107,42353,42354,42355</NoWarn>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<WarningsAsErrors>41999,42016,42017,42018,42019,42020,42021,42022,42032,42036</WarningsAsErrors>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
|
||||
<DefineTrace>true</DefineTrace>
|
||||
<OutputPath>..\mpv.net\bin\x86\Addons\CSScriptAddon\</OutputPath>
|
||||
<Optimize>true</Optimize>
|
||||
<NoWarn>42105,42106,42107,42353,42354,42355</NoWarn>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<WarningsAsErrors>41999,42016,42017,42018,42019,42020,42021,42022,42032,42036</WarningsAsErrors>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DefineDebug>true</DefineDebug>
|
||||
<DefineTrace>true</DefineTrace>
|
||||
<OutputPath>..\..\mpv.net\bin\x64\Addons\CSScriptAddon\</OutputPath>
|
||||
<NoWarn>42105,42106,42107,42353,42354,42355</NoWarn>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<WarningsAsErrors>41999,42016,42017,42018,42019,42020,42021,42022,42032,42036</WarningsAsErrors>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
|
||||
<DefineTrace>true</DefineTrace>
|
||||
<OutputPath>..\mpv.net\bin\x64\Addons\CSScriptAddon\</OutputPath>
|
||||
<Optimize>true</Optimize>
|
||||
<NoWarn>42105,42106,42107,42353,42354,42355</NoWarn>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<WarningsAsErrors>41999,42016,42017,42018,42019,42020,42021,42022,42032,42036</WarningsAsErrors>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="CSScriptLibrary, Version=3.27.5.0, Culture=neutral, PublicKeyToken=70fcc3d18c749033, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>.\CSScriptLibrary.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.ComponentModel.Composition" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Windows.Forms" />
|
||||
<Reference Include="System.Xml" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Import Include="Microsoft.VisualBasic" />
|
||||
<Import Include="System" />
|
||||
<Import Include="System.Collections" />
|
||||
<Import Include="System.Collections.Generic" />
|
||||
<Import Include="System.Data" />
|
||||
<Import Include="System.Diagnostics" />
|
||||
<Import Include="System.Linq" />
|
||||
<Import Include="System.Xml.Linq" />
|
||||
<Import Include="System.Threading.Tasks" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="CSScriptAddon.vb" />
|
||||
<Compile Include="My Project\AssemblyInfo.vb" />
|
||||
<Compile Include="My Project\Application.Designer.vb">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Application.myapp</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="My Project\Resources.Designer.vb">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DesignTime>True</DesignTime>
|
||||
<DependentUpon>Resources.resx</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="My Project\Settings.Designer.vb">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Settings.settings</DependentUpon>
|
||||
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="My Project\Resources.resx">
|
||||
<Generator>VbMyResourcesResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>Resources.Designer.vb</LastGenOutput>
|
||||
<CustomToolNamespace>My.Resources</CustomToolNamespace>
|
||||
<SubType>Designer</SubType>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="My Project\Application.myapp">
|
||||
<Generator>MyApplicationCodeGenerator</Generator>
|
||||
<LastGenOutput>Application.Designer.vb</LastGenOutput>
|
||||
</None>
|
||||
<None Include="My Project\Settings.settings">
|
||||
<Generator>SettingsSingleFileGenerator</Generator>
|
||||
<CustomToolNamespace>My</CustomToolNamespace>
|
||||
<LastGenOutput>Settings.Designer.vb</LastGenOutput>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="CSScriptLibrary.dll" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\mpv.net\mpv.net.csproj">
|
||||
<Project>{1751f378-8edf-4b62-be6d-304c7c287089}</Project>
|
||||
<Name>mpv.net</Name>
|
||||
<Private>False</Private>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.VisualBasic.targets" />
|
||||
</Project>
|
||||
@@ -1,13 +0,0 @@
|
||||
'------------------------------------------------------------------------------
|
||||
' <auto-generated>
|
||||
' This code was generated by a tool.
|
||||
' Runtime Version:4.0.30319.42000
|
||||
'
|
||||
' Changes to this file may cause incorrect behavior and will be lost if
|
||||
' the code is regenerated.
|
||||
' </auto-generated>
|
||||
'------------------------------------------------------------------------------
|
||||
|
||||
Option Strict On
|
||||
Option Explicit On
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<MyApplicationData xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
|
||||
<MySubMain>false</MySubMain>
|
||||
<SingleInstance>false</SingleInstance>
|
||||
<ShutdownMode>0</ShutdownMode>
|
||||
<EnableVisualStyles>true</EnableVisualStyles>
|
||||
<AuthenticationMode>0</AuthenticationMode>
|
||||
<ApplicationType>1</ApplicationType>
|
||||
<SaveMySettingsOnExit>true</SaveMySettingsOnExit>
|
||||
</MyApplicationData>
|
||||
@@ -1,35 +0,0 @@
|
||||
Imports System
|
||||
Imports System.Reflection
|
||||
Imports System.Runtime.InteropServices
|
||||
|
||||
' General Information about an assembly is controlled through the following
|
||||
' set of attributes. Change these attribute values to modify the information
|
||||
' associated with an assembly.
|
||||
|
||||
' Review the values of the assembly attributes
|
||||
|
||||
<Assembly: AssemblyTitle("CSScriptAddon")>
|
||||
<Assembly: AssemblyDescription("")>
|
||||
<Assembly: AssemblyCompany("")>
|
||||
<Assembly: AssemblyProduct("CSScriptAddon")>
|
||||
<Assembly: AssemblyCopyright("Copyright © 2019")>
|
||||
<Assembly: AssemblyTrademark("")>
|
||||
|
||||
<Assembly: ComVisible(False)>
|
||||
|
||||
'The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
<Assembly: Guid("4a748201-3948-497d-b156-7d172a332bd6")>
|
||||
|
||||
' Version information for an assembly consists of the following four values:
|
||||
'
|
||||
' Major Version
|
||||
' Minor Version
|
||||
' Build Number
|
||||
' Revision
|
||||
'
|
||||
' You can specify all the values or you can default the Build and Revision Numbers
|
||||
' by using the '*' as shown below:
|
||||
' <Assembly: AssemblyVersion("1.0.*")>
|
||||
|
||||
<Assembly: AssemblyVersion("1.0.0.0")>
|
||||
<Assembly: AssemblyFileVersion("1.0.0.0")>
|
||||
@@ -1,63 +0,0 @@
|
||||
'------------------------------------------------------------------------------
|
||||
' <auto-generated>
|
||||
' This code was generated by a tool.
|
||||
' Runtime Version:4.0.30319.42000
|
||||
'
|
||||
' Changes to this file may cause incorrect behavior and will be lost if
|
||||
' the code is regenerated.
|
||||
' </auto-generated>
|
||||
'------------------------------------------------------------------------------
|
||||
|
||||
Option Strict On
|
||||
Option Explicit On
|
||||
|
||||
Imports System
|
||||
|
||||
Namespace My.Resources
|
||||
|
||||
'This class was auto-generated by the StronglyTypedResourceBuilder
|
||||
'class via a tool like ResGen or Visual Studio.
|
||||
'To add or remove a member, edit your .ResX file then rerun ResGen
|
||||
'with the /str option, or rebuild your VS project.
|
||||
'''<summary>
|
||||
''' A strongly-typed resource class, for looking up localized strings, etc.
|
||||
'''</summary>
|
||||
<Global.System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0"), _
|
||||
Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _
|
||||
Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute(), _
|
||||
Global.Microsoft.VisualBasic.HideModuleNameAttribute()> _
|
||||
Friend Module Resources
|
||||
|
||||
Private resourceMan As Global.System.Resources.ResourceManager
|
||||
|
||||
Private resourceCulture As Global.System.Globalization.CultureInfo
|
||||
|
||||
'''<summary>
|
||||
''' Returns the cached ResourceManager instance used by this class.
|
||||
'''</summary>
|
||||
<Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
|
||||
Friend ReadOnly Property ResourceManager() As Global.System.Resources.ResourceManager
|
||||
Get
|
||||
If Object.ReferenceEquals(resourceMan, Nothing) Then
|
||||
Dim temp As Global.System.Resources.ResourceManager = New Global.System.Resources.ResourceManager("CSScriptAddon.Resources", GetType(Resources).Assembly)
|
||||
resourceMan = temp
|
||||
End If
|
||||
Return resourceMan
|
||||
End Get
|
||||
End Property
|
||||
|
||||
'''<summary>
|
||||
''' Overrides the current thread's CurrentUICulture property for all
|
||||
''' resource lookups using this strongly typed resource class.
|
||||
'''</summary>
|
||||
<Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
|
||||
Friend Property Culture() As Global.System.Globalization.CultureInfo
|
||||
Get
|
||||
Return resourceCulture
|
||||
End Get
|
||||
Set
|
||||
resourceCulture = value
|
||||
End Set
|
||||
End Property
|
||||
End Module
|
||||
End Namespace
|
||||
@@ -1,117 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
||||
73
addons/CSScriptAddon/My Project/Settings.Designer.vb
generated
@@ -1,73 +0,0 @@
|
||||
'------------------------------------------------------------------------------
|
||||
' <auto-generated>
|
||||
' This code was generated by a tool.
|
||||
' Runtime Version:4.0.30319.42000
|
||||
'
|
||||
' Changes to this file may cause incorrect behavior and will be lost if
|
||||
' the code is regenerated.
|
||||
' </auto-generated>
|
||||
'------------------------------------------------------------------------------
|
||||
|
||||
Option Strict On
|
||||
Option Explicit On
|
||||
|
||||
|
||||
Namespace My
|
||||
|
||||
<Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute(), _
|
||||
Global.System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.9.0.0"), _
|
||||
Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
|
||||
Partial Friend NotInheritable Class MySettings
|
||||
Inherits Global.System.Configuration.ApplicationSettingsBase
|
||||
|
||||
Private Shared defaultInstance As MySettings = CType(Global.System.Configuration.ApplicationSettingsBase.Synchronized(New MySettings()),MySettings)
|
||||
|
||||
#Region "My.Settings Auto-Save Functionality"
|
||||
#If _MyType = "WindowsForms" Then
|
||||
Private Shared addedHandler As Boolean
|
||||
|
||||
Private Shared addedHandlerLockObject As New Object
|
||||
|
||||
<Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
|
||||
Private Shared Sub AutoSaveSettings(sender As Global.System.Object, e As Global.System.EventArgs)
|
||||
If My.Application.SaveMySettingsOnExit Then
|
||||
My.Settings.Save()
|
||||
End If
|
||||
End Sub
|
||||
#End If
|
||||
#End Region
|
||||
|
||||
Public Shared ReadOnly Property [Default]() As MySettings
|
||||
Get
|
||||
|
||||
#If _MyType = "WindowsForms" Then
|
||||
If Not addedHandler Then
|
||||
SyncLock addedHandlerLockObject
|
||||
If Not addedHandler Then
|
||||
AddHandler My.Application.Shutdown, AddressOf AutoSaveSettings
|
||||
addedHandler = True
|
||||
End If
|
||||
End SyncLock
|
||||
End If
|
||||
#End If
|
||||
Return defaultInstance
|
||||
End Get
|
||||
End Property
|
||||
End Class
|
||||
End Namespace
|
||||
|
||||
Namespace My
|
||||
|
||||
<Global.Microsoft.VisualBasic.HideModuleNameAttribute(), _
|
||||
Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _
|
||||
Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute()> _
|
||||
Friend Module MySettingsProperty
|
||||
|
||||
<Global.System.ComponentModel.Design.HelpKeywordAttribute("My.Settings")> _
|
||||
Friend ReadOnly Property Settings() As Global.CSScriptAddon.My.MySettings
|
||||
Get
|
||||
Return Global.CSScriptAddon.My.MySettings.Default
|
||||
End Get
|
||||
End Property
|
||||
End Module
|
||||
End Namespace
|
||||
@@ -1,7 +0,0 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)" UseMySettingsClassName="true">
|
||||
<Profiles>
|
||||
<Profile Name="(Default)" />
|
||||
</Profiles>
|
||||
<Settings />
|
||||
</SettingsFile>
|
||||
@@ -1,58 +0,0 @@
|
||||
using System;
|
||||
using System.ComponentModel.Composition;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
using mpvnet;
|
||||
|
||||
namespace RatingAddon
|
||||
{
|
||||
[Export(typeof(IAddon))]
|
||||
public class RatingAddon : IAddon
|
||||
{
|
||||
Dictionary<string, int> Dic = new Dictionary<string, int>();
|
||||
|
||||
public RatingAddon()
|
||||
{
|
||||
mp.ClientMessage += mpv_ClientMessage;
|
||||
mp.Shutdown += mpv_Shutdown;
|
||||
}
|
||||
|
||||
void mpv_Shutdown()
|
||||
{
|
||||
foreach (var i in Dic)
|
||||
{
|
||||
string filepath = i.Key;
|
||||
int rating = i.Value;
|
||||
|
||||
if (String.IsNullOrEmpty(filepath) || ! File.Exists(filepath))
|
||||
return;
|
||||
|
||||
string basename = Path.GetFileNameWithoutExtension(filepath);
|
||||
|
||||
for (int x = 0; x < 6; x++)
|
||||
if (basename.Contains(" (" + x.ToString() + "stars)"))
|
||||
basename = basename.Replace(" (" + x.ToString() + "stars)", "");
|
||||
|
||||
basename += $" ({rating}stars)";
|
||||
string newPath = Path.Combine(Path.GetDirectoryName(filepath), basename + Path.GetExtension(filepath));
|
||||
|
||||
if (filepath.ToLower() != newPath.ToLower())
|
||||
File.Move(filepath, newPath);
|
||||
|
||||
File.SetLastWriteTime(newPath, DateTime.Now);
|
||||
}
|
||||
}
|
||||
|
||||
void mpv_ClientMessage(string[] args)
|
||||
{
|
||||
int rating;
|
||||
|
||||
if (args?.Length != 2 || args[0] != "rate-file" || ! int.TryParse(args[1], out rating))
|
||||
return;
|
||||
|
||||
Dic[mp.get_property_string("path")] = rating;
|
||||
mp.commandv("show-text", $"Rating: {rating}");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
using System.ComponentModel.Composition;
|
||||
|
||||
using mpvnet;
|
||||
|
||||
namespace TestAddon
|
||||
{
|
||||
[Export(typeof(IAddon))]
|
||||
public class TestAddon : IAddon
|
||||
{
|
||||
// do some init work in constructor
|
||||
public TestAddon()
|
||||
{
|
||||
// Observe changes of the fullscreen property.
|
||||
// You can find a list of available mpv properties
|
||||
// in mpv.net's wiki on github or use mpv --list-properties.
|
||||
// You can test properties in mpv.net in the menu at:
|
||||
// Tools > Execute mpv command
|
||||
// where you can enter: show-text ${fullscreen}
|
||||
mp.observe_property_bool("fullscreen", OnFullscreenChange);
|
||||
}
|
||||
|
||||
void OnFullscreenChange(bool val)
|
||||
{
|
||||
mp.commandv("show-text", "fullscreen: " + val.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{06F854B0-00F9-4B53-94D9-0BE65A7C55D8}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>TestAddon</RootNamespace>
|
||||
<AssemblyName>TestAddon</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<Deterministic>true</Deterministic>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.ComponentModel.Composition" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="TestAddon.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\mpv.net\mpv.net.csproj">
|
||||
<Project>{1751f378-8edf-4b62-be6d-304c7c287089}</Project>
|
||||
<Name>mpv.net</Name>
|
||||
<Private>False</Private>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
||||
@@ -5,12 +5,12 @@ using System.Runtime.InteropServices;
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("RatingAddon")]
|
||||
[assembly: AssemblyTitle("RatingExtension")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("RatingAddon")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2017")]
|
||||
[assembly: AssemblyProduct("RatingExtension")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2017-2019 Frank Skare (stax76)")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
65
extensions/RatingExtension/RatingExtension.cs
Normal file
@@ -0,0 +1,65 @@
|
||||
// This extension writes a rating to the filename of rated videos when mpv.net shuts down.
|
||||
|
||||
// The input.conf defaults contain key bindings for this extension to set ratings.
|
||||
|
||||
using System;
|
||||
using System.ComponentModel.Composition;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
using mpvnet;
|
||||
|
||||
namespace RatingExtension // the assembly name must end with 'Extension'
|
||||
{
|
||||
[Export(typeof(IExtension))]
|
||||
public class RatingExtension : IExtension
|
||||
{
|
||||
// dictionory to store the filename and the rating
|
||||
Dictionary<string, int> Dic = new Dictionary<string, int>();
|
||||
|
||||
public RatingExtension() // plugin initialization
|
||||
{
|
||||
mp.ClientMessage += ClientMessage; //handles keys defined in input.conf
|
||||
mp.Shutdown += Shutdown; // handles MPV_EVENT_SHUTDOWN
|
||||
}
|
||||
|
||||
// handles MPV_EVENT_SHUTDOWN
|
||||
void Shutdown()
|
||||
{
|
||||
foreach (var i in Dic)
|
||||
{
|
||||
string filepath = i.Key;
|
||||
int rating = i.Value;
|
||||
if (String.IsNullOrEmpty(filepath) || !File.Exists(filepath))
|
||||
return;
|
||||
string basename = Path.GetFileNameWithoutExtension(filepath);
|
||||
|
||||
for (int x = 0; x < 6; x++)
|
||||
if (basename.Contains(" (" + x + "stars)"))
|
||||
basename = basename.Replace(" (" + x + "stars)", "");
|
||||
|
||||
basename += $" ({rating}stars)";
|
||||
string newPath = Path.Combine(Path.GetDirectoryName(filepath), basename + Path.GetExtension(filepath));
|
||||
if (filepath.ToLower() != newPath.ToLower())
|
||||
File.Move(filepath, newPath);
|
||||
File.SetLastWriteTime(newPath, DateTime.Now);
|
||||
}
|
||||
}
|
||||
|
||||
//handles keys defined in input.conf
|
||||
void ClientMessage(string[] args)
|
||||
{
|
||||
if (args[0] != "rate-file") return;
|
||||
|
||||
if (int.TryParse(args[1], out int rating))
|
||||
{
|
||||
string path = mp.get_property_string("path");
|
||||
if (!File.Exists(path)) return;
|
||||
Dic[path] = rating;
|
||||
mp.commandv("show-text", $"Rating: {rating}");
|
||||
}
|
||||
else if (args[1] == "about")
|
||||
Msg.Show("Rating Extension", "This extension writes a rating to the filename of rated videos when mpv.net shuts down.\n\nThe input.conf defaults contain key bindings for this extension to set ratings.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,32 +7,15 @@
|
||||
<ProjectGuid>{55C88710-539D-4402-84C8-31694841C731}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>RatingAddon</RootNamespace>
|
||||
<AssemblyName>RatingAddon</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
|
||||
<RootNamespace>RatingExtension</RootNamespace>
|
||||
<AssemblyName>RatingExtension</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<TargetFrameworkProfile />
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>..\mpv.net\bin\Addons\RatingAddon\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>..\mpv.net\bin\Addons\RatingAddon\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>..\..\mpv.net\bin\x86\Addons\RatingAddon\</OutputPath>
|
||||
<OutputPath>..\..\mpv.net\bin\x86\Extensions\RatingExtension\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
@@ -40,7 +23,7 @@
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
|
||||
<OutputPath>..\mpv.net\bin\x86\Addons\RatingAddon\</OutputPath>
|
||||
<OutputPath>..\..\mpv.net\bin\x86\Extensions\RatingExtension\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
@@ -50,7 +33,7 @@
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>..\..\mpv.net\bin\x64\Addons\RatingAddon\</OutputPath>
|
||||
<OutputPath>..\..\mpv.net\bin\x64\Extensions\RatingExtension\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
@@ -58,7 +41,7 @@
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
|
||||
<OutputPath>..\mpv.net\bin\x64\Addons\RatingAddon\</OutputPath>
|
||||
<OutputPath>..\..\mpv.net\bin\x64\Extensions\RatingExtension\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
@@ -78,7 +61,7 @@
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="RatingAddon.cs" />
|
||||
<Compile Include="RatingExtension.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
@@ -5,12 +5,12 @@ using System.Runtime.InteropServices;
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("TestAddon")]
|
||||
[assembly: AssemblyTitle("RatingExtension")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("TestAddon")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2019")]
|
||||
[assembly: AssemblyProduct("RatingExtension")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2017-2019 Frank Skare (stax76)")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
@@ -20,7 +20,7 @@ using System.Runtime.InteropServices;
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("06f854b0-00f9-4b53-94d9-0be65a7c55d8")]
|
||||
[assembly: Guid("55c88710-539d-4402-84c8-31694841c731")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
48
extensions/ScriptingExtension/ScriptingExtension.cs
Normal file
@@ -0,0 +1,48 @@
|
||||
// This extension implements the C# scripting feature of mpv.net which
|
||||
// is based on CS-Script (https://www.cs-script.net).
|
||||
|
||||
// I also use this extension to code scripts in order to have full
|
||||
// code completion and debugger support, once the script code is
|
||||
// finished I move it from the extension to a standalone script.
|
||||
|
||||
using System;
|
||||
using System.ComponentModel.Composition;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
using mpvnet;
|
||||
using CSScriptLibrary;
|
||||
|
||||
namespace ScriptingExtension // the file name of extensions must end with 'Extension'
|
||||
{
|
||||
[Export(typeof(IExtension))]
|
||||
public class ScriptingExtension : IExtension
|
||||
{
|
||||
//Script Script;
|
||||
|
||||
public ScriptingExtension()
|
||||
{
|
||||
//Script = new Script();
|
||||
List<string> scriptFiles = new List<string>();
|
||||
|
||||
if (Directory.Exists(mp.ConfigFolder + "scripts"))
|
||||
scriptFiles.AddRange(Directory.GetFiles(mp.ConfigFolder + "scripts", "*.cs"));
|
||||
|
||||
if (Directory.Exists(Folder.Startup + "scripts"))
|
||||
foreach (string path in Directory.GetFiles(Folder.Startup + "scripts", "*.cs"))
|
||||
scriptFiles.AddRange(Directory.GetFiles(Folder.Startup + "scripts", "*.cs"));
|
||||
|
||||
if (scriptFiles.Count == 0) return;
|
||||
CSScriptLibrary.CSScript.EvaluatorConfig.Engine = EvaluatorEngine.CodeDom;
|
||||
|
||||
foreach (var i in scriptFiles)
|
||||
{
|
||||
try {
|
||||
CSScriptLibrary.CSScript.Evaluator.LoadCode(File.ReadAllText(i));
|
||||
} catch (Exception e) {
|
||||
Msg.ShowException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
80
extensions/ScriptingExtension/ScriptingExtension.csproj
Normal file
@@ -0,0 +1,80 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{94255EF2-C823-4D82-9017-0E993CC0F5A1}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>ScriptingExtension</RootNamespace>
|
||||
<AssemblyName>ScriptingExtension</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<TargetFrameworkProfile />
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>..\..\mpv.net\bin\x86\Extensions\ScriptingExtension\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
|
||||
<OutputPath>..\..\mpv.net\bin\x86\Extensions\ScriptingExtension\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>..\..\mpv.net\bin\x64\Extensions\ScriptingExtension\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
|
||||
<OutputPath>..\..\mpv.net\bin\x64\Extensions\ScriptingExtension\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="CSScriptLibrary">
|
||||
<HintPath>.\CSScriptLibrary.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.ComponentModel.Composition" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Windows.Forms" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="ScriptingExtension.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="script.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\mpv.net\mpv.net.csproj">
|
||||
<Project>{1751f378-8edf-4b62-be6d-304c7c287089}</Project>
|
||||
<Name>mpv.net</Name>
|
||||
<Private>False</Private>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
||||
31
extensions/ScriptingExtension/ScriptingExtension.sln
Normal file
@@ -0,0 +1,31 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.29123.88
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ScriptingExtension", "ScriptingExtension.csproj", "{55C88710-539D-4402-84C8-31694841C731}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|x64 = Debug|x64
|
||||
Debug|x86 = Debug|x86
|
||||
Release|x64 = Release|x64
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{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}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{55C88710-539D-4402-84C8-31694841C731}.Debug|x86.Build.0 = Debug|x86
|
||||
{55C88710-539D-4402-84C8-31694841C731}.Release|x64.ActiveCfg = Release|x64
|
||||
{55C88710-539D-4402-84C8-31694841C731}.Release|x64.Build.0 = Release|x64
|
||||
{55C88710-539D-4402-84C8-31694841C731}.Release|x86.ActiveCfg = Release|x86
|
||||
{55C88710-539D-4402-84C8-31694841C731}.Release|x86.Build.0 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {C8A53BF6-B00A-4215-B9D7-801ADB9C8F60}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
17
extensions/ScriptingExtension/script.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
using System.IO;
|
||||
|
||||
using mpvnet;
|
||||
|
||||
class Script
|
||||
{
|
||||
public Script()
|
||||
{
|
||||
mp.Shutdown += Shutdown;
|
||||
}
|
||||
|
||||
private void Shutdown()
|
||||
{
|
||||
foreach (string file in Directory.GetFiles(@"C:\Users\frank\Desktop\aaa"))
|
||||
File.Delete(file);
|
||||
}
|
||||
}
|
||||
BIN
img/Avatar.png
Normal file
|
After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 238 KiB After Width: | Height: | Size: 212 KiB |
|
Before Width: | Height: | Size: 277 KiB After Width: | Height: | Size: 214 KiB |
BIN
img/Main.png
|
Before Width: | Height: | Size: 2.9 MiB After Width: | Height: | Size: 2.5 MiB |
|
Before Width: | Height: | Size: 125 KiB After Width: | Height: | Size: 628 KiB |
BIN
img/Terminal.png
Normal file
|
After Width: | Height: | Size: 2.2 MiB |
BIN
img/mpvnet.ico
Normal file
|
After Width: | Height: | Size: 25 KiB |
BIN
img/mpvnet.pdn
BIN
img/mpvnet.png
|
Before Width: | Height: | Size: 6.6 KiB After Width: | Height: | Size: 8.2 KiB |
48
mpv.net.sln
@@ -5,70 +5,42 @@ VisualStudioVersion = 16.0.28729.10
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "mpv.net", "mpv.net\mpv.net.csproj", "{1751F378-8EDF-4B62-BE6D-304C7C287089}"
|
||||
EndProject
|
||||
Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "CSScriptAddon", "addons\CSScriptAddon\CSScriptAddon.vbproj", "{71808A87-8B1C-4DF8-957C-D79C3B164CCA}"
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RatingExtension", "extensions\RatingExtension\RatingExtension.csproj", "{55C88710-539D-4402-84C8-31694841C731}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RatingAddon", "addons\RatingAddon\RatingAddon.csproj", "{55C88710-539D-4402-84C8-31694841C731}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestAddon", "addons\TestAddon\TestAddon.csproj", "{06F854B0-00F9-4B53-94D9-0BE65A7C55D8}"
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ScriptingExtension", "extensions\ScriptingExtension\ScriptingExtension.csproj", "{94255EF2-C823-4D82-9017-0E993CC0F5A1}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Debug|x64 = Debug|x64
|
||||
Debug|x86 = Debug|x86
|
||||
Release|Any CPU = Release|Any CPU
|
||||
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|x64.ActiveCfg = Debug|x64
|
||||
{1751F378-8EDF-4B62-BE6D-304C7C287089}.Debug|x64.Build.0 = Debug|x64
|
||||
{1751F378-8EDF-4B62-BE6D-304C7C287089}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{1751F378-8EDF-4B62-BE6D-304C7C287089}.Debug|x86.Build.0 = Debug|x86
|
||||
{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|x64.ActiveCfg = Release|x64
|
||||
{1751F378-8EDF-4B62-BE6D-304C7C287089}.Release|x64.Build.0 = Release|x64
|
||||
{1751F378-8EDF-4B62-BE6D-304C7C287089}.Release|x86.ActiveCfg = Release|x86
|
||||
{1751F378-8EDF-4B62-BE6D-304C7C287089}.Release|x86.Build.0 = Release|x86
|
||||
{71808A87-8B1C-4DF8-957C-D79C3B164CCA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{71808A87-8B1C-4DF8-957C-D79C3B164CCA}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{71808A87-8B1C-4DF8-957C-D79C3B164CCA}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{71808A87-8B1C-4DF8-957C-D79C3B164CCA}.Debug|x64.Build.0 = Debug|x64
|
||||
{71808A87-8B1C-4DF8-957C-D79C3B164CCA}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{71808A87-8B1C-4DF8-957C-D79C3B164CCA}.Debug|x86.Build.0 = Debug|x86
|
||||
{71808A87-8B1C-4DF8-957C-D79C3B164CCA}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{71808A87-8B1C-4DF8-957C-D79C3B164CCA}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{71808A87-8B1C-4DF8-957C-D79C3B164CCA}.Release|x64.ActiveCfg = Release|x64
|
||||
{71808A87-8B1C-4DF8-957C-D79C3B164CCA}.Release|x64.Build.0 = Release|x64
|
||||
{71808A87-8B1C-4DF8-957C-D79C3B164CCA}.Release|x86.ActiveCfg = Release|x86
|
||||
{71808A87-8B1C-4DF8-957C-D79C3B164CCA}.Release|x86.Build.0 = Release|x86
|
||||
{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|x64.ActiveCfg = Debug|x64
|
||||
{55C88710-539D-4402-84C8-31694841C731}.Debug|x64.Build.0 = Debug|x64
|
||||
{55C88710-539D-4402-84C8-31694841C731}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{55C88710-539D-4402-84C8-31694841C731}.Debug|x86.Build.0 = Debug|x86
|
||||
{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|x64.ActiveCfg = Release|x64
|
||||
{55C88710-539D-4402-84C8-31694841C731}.Release|x64.Build.0 = Release|x64
|
||||
{55C88710-539D-4402-84C8-31694841C731}.Release|x86.ActiveCfg = Release|x86
|
||||
{55C88710-539D-4402-84C8-31694841C731}.Release|x86.Build.0 = Release|x86
|
||||
{06F854B0-00F9-4B53-94D9-0BE65A7C55D8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{06F854B0-00F9-4B53-94D9-0BE65A7C55D8}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{06F854B0-00F9-4B53-94D9-0BE65A7C55D8}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{06F854B0-00F9-4B53-94D9-0BE65A7C55D8}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{06F854B0-00F9-4B53-94D9-0BE65A7C55D8}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{06F854B0-00F9-4B53-94D9-0BE65A7C55D8}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{06F854B0-00F9-4B53-94D9-0BE65A7C55D8}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{06F854B0-00F9-4B53-94D9-0BE65A7C55D8}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{06F854B0-00F9-4B53-94D9-0BE65A7C55D8}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{06F854B0-00F9-4B53-94D9-0BE65A7C55D8}.Release|x64.Build.0 = Release|Any CPU
|
||||
{06F854B0-00F9-4B53-94D9-0BE65A7C55D8}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{06F854B0-00F9-4B53-94D9-0BE65A7C55D8}.Release|x86.Build.0 = Release|Any CPU
|
||||
{94255EF2-C823-4D82-9017-0E993CC0F5A1}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{94255EF2-C823-4D82-9017-0E993CC0F5A1}.Debug|x64.Build.0 = Debug|x64
|
||||
{94255EF2-C823-4D82-9017-0E993CC0F5A1}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{94255EF2-C823-4D82-9017-0E993CC0F5A1}.Debug|x86.Build.0 = Debug|x86
|
||||
{94255EF2-C823-4D82-9017-0E993CC0F5A1}.Release|x64.ActiveCfg = Release|x64
|
||||
{94255EF2-C823-4D82-9017-0E993CC0F5A1}.Release|x64.Build.0 = Release|x64
|
||||
{94255EF2-C823-4D82-9017-0E993CC0F5A1}.Release|x86.ActiveCfg = Release|x86
|
||||
{94255EF2-C823-4D82-9017-0E993CC0F5A1}.Release|x86.Build.0 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.Composition;
|
||||
using System.ComponentModel.Composition.Hosting;
|
||||
using System.IO;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace mpvnet
|
||||
{
|
||||
public class Addon
|
||||
{
|
||||
[ImportMany]
|
||||
public IEnumerable<IAddon> Addons = null;
|
||||
|
||||
readonly CompositionContainer CompositionContainer;
|
||||
|
||||
public Addon()
|
||||
{
|
||||
try
|
||||
{
|
||||
AggregateCatalog catalog = new AggregateCatalog();
|
||||
|
||||
string dir = Application.StartupPath + "\\Addons";
|
||||
|
||||
if (Directory.Exists(dir))
|
||||
foreach (string i in Directory.GetDirectories(dir))
|
||||
catalog.Catalogs.Add(new DirectoryCatalog(i, "*Addon.dll"));
|
||||
|
||||
dir = mp.MpvConfFolder + "\\Addons";
|
||||
|
||||
if (Directory.Exists(dir))
|
||||
foreach (string i in Directory.GetDirectories(dir))
|
||||
catalog.Catalogs.Add(new DirectoryCatalog(i, "*Addon.dll"));
|
||||
|
||||
if (catalog.Catalogs.Count > 0)
|
||||
{
|
||||
CompositionContainer = new CompositionContainer(catalog);
|
||||
CompositionContainer.ComposeParts(this);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Msg.ShowException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public interface IAddon
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,6 @@
|
||||
<configSections>
|
||||
</configSections>
|
||||
<startup>
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2"/>
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8"/>
|
||||
</startup>
|
||||
</configuration>
|
||||
|
||||
@@ -1,275 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Windows.Forms;
|
||||
using System.Windows.Interop;
|
||||
|
||||
namespace mpvnet
|
||||
{
|
||||
public class Command
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public Action<string[]> Action { get; set; }
|
||||
|
||||
static List<Command> commands;
|
||||
|
||||
public static List<Command> Commands
|
||||
{
|
||||
get
|
||||
{
|
||||
if (commands == null)
|
||||
{
|
||||
commands = new List<Command>();
|
||||
Type type = typeof(Command);
|
||||
MethodInfo[] methods = type.GetMethods(System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public);
|
||||
|
||||
foreach (MethodInfo i in methods)
|
||||
{
|
||||
ParameterInfo[] parameters = i.GetParameters();
|
||||
|
||||
if (parameters == null || parameters.Length != 1 || parameters[0].ParameterType != typeof(string[]))
|
||||
continue;
|
||||
|
||||
Command cmd = new Command() { Name = i.Name.Replace("_","-"), Action = (Action<string[]>)i.CreateDelegate(typeof(Action<string[]>)) };
|
||||
commands.Add(cmd);
|
||||
}
|
||||
}
|
||||
return commands;
|
||||
}
|
||||
}
|
||||
|
||||
public static void open_files(string[] args)
|
||||
{
|
||||
MainForm.Instance.Invoke(new Action(() => {
|
||||
using (var d = new OpenFileDialog() { Multiselect = true })
|
||||
if (d.ShowDialog() == DialogResult.OK)
|
||||
mp.LoadFiles(d.FileNames);
|
||||
}));
|
||||
}
|
||||
|
||||
public static void open_conf_folder(string[] args)
|
||||
{
|
||||
Process.Start(mp.MpvConfFolder);
|
||||
}
|
||||
|
||||
public static void show_input_editor(string[] args)
|
||||
{
|
||||
MainForm.Instance.Invoke(new Action(() => {
|
||||
InputWindow w = new InputWindow();
|
||||
new WindowInteropHelper(w).Owner = MainForm.Instance.Handle;
|
||||
w.ShowDialog();
|
||||
}));
|
||||
}
|
||||
|
||||
public static void show_conf_editor(string[] args)
|
||||
{
|
||||
MainForm.Instance.Invoke(new Action(() => {
|
||||
ConfWindow w = new ConfWindow();
|
||||
new WindowInteropHelper(w).Owner = MainForm.Instance.Handle;
|
||||
w.ShowDialog();
|
||||
}));
|
||||
}
|
||||
|
||||
public static void show_about(string[] args)
|
||||
{
|
||||
MainForm.Instance.Invoke(new Action(() => {
|
||||
AboutWindow w = new AboutWindow();
|
||||
new WindowInteropHelper(w).Owner = MainForm.Instance.Handle;
|
||||
w.ShowDialog();
|
||||
}));
|
||||
}
|
||||
|
||||
public static void show_command_palette(string[] args)
|
||||
{
|
||||
MainForm.Instance.Invoke(new Action(() => {
|
||||
var w = new CommandPaletteWindow();
|
||||
new WindowInteropHelper(w).Owner = MainForm.Instance.Handle;
|
||||
w.ShowDialog();
|
||||
}));
|
||||
}
|
||||
|
||||
public static void show_media_search(string[] args)
|
||||
{
|
||||
MainForm.Instance.Invoke(new Action(() => {
|
||||
var w = new EverythingWindow();
|
||||
new WindowInteropHelper(w).Owner = MainForm.Instance.Handle;
|
||||
w.ShowDialog();
|
||||
}));
|
||||
}
|
||||
|
||||
public static void show_history(string[] args)
|
||||
{
|
||||
var fp = mp.MpvConfFolder + "history.txt";
|
||||
|
||||
if (File.Exists(fp))
|
||||
Process.Start(fp);
|
||||
else
|
||||
if (Msg.ShowQuestion("Create history.txt file in config folder?",
|
||||
"mpv.net will write the date, time and filename of opened files to it.") == MsgResult.OK)
|
||||
File.WriteAllText(fp, "");
|
||||
}
|
||||
|
||||
public static void shell_execute(string[] args) => Process.Start(args[0]);
|
||||
|
||||
public static void show_info(string[] args)
|
||||
{
|
||||
try
|
||||
{
|
||||
string performer, title, album, genre, date, duration, text = "";
|
||||
long fileSize = 0;
|
||||
string path = mp.get_property_string("path");
|
||||
int width = mp.get_property_int("video-params/w");
|
||||
int height = mp.get_property_int("video-params/h");
|
||||
|
||||
if (File.Exists(path))
|
||||
{
|
||||
fileSize = new FileInfo(path).Length;
|
||||
|
||||
if (App.AudioTypes.Contains(Path.GetExtension(path).ToLower().TrimStart('.')))
|
||||
{
|
||||
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";
|
||||
|
||||
mp.commandv("show-text", text, "5000");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TimeSpan position = TimeSpan.FromSeconds(mp.get_property_number("time-pos"));
|
||||
TimeSpan duration2 = TimeSpan.FromSeconds(mp.get_property_number("duration"));
|
||||
string videoCodec = mp.get_property_string("video-format").ToUpper();
|
||||
|
||||
text = Path.GetFileName(path) + "\n" +
|
||||
FormatTime(position.TotalMinutes) + ":" +
|
||||
FormatTime(position.Seconds) + " / " +
|
||||
FormatTime(duration2.TotalMinutes) + ":" +
|
||||
FormatTime(duration2.Seconds) + "\n" +
|
||||
$"{width} x {height}\n";
|
||||
|
||||
if (fileSize > 0)
|
||||
text += Convert.ToInt32(fileSize / 1024.0 / 1024.0).ToString() + " MB\n";
|
||||
|
||||
text += $"{videoCodec}\n";
|
||||
|
||||
mp.commandv("show-text", text, "5000");
|
||||
string FormatTime(double value) => ((int)value).ToString("00");
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public static void execute_mpv_command(string[] args)
|
||||
{
|
||||
MainForm.Instance.Invoke(new Action(() => {
|
||||
string command = Microsoft.VisualBasic.Interaction.InputBox("Enter a mpv command to be executed.", "Execute Command", RegistryHelp.GetString("HKCU\\Software\\" + Application.ProductName, "RecentExecutedCommand"));
|
||||
if (string.IsNullOrEmpty(command)) return;
|
||||
RegistryHelp.SetObject("HKCU\\Software\\" + Application.ProductName, "RecentExecutedCommand", command);
|
||||
mp.command_string(command, false);
|
||||
}));
|
||||
}
|
||||
|
||||
public static void open_url(string[] args)
|
||||
{
|
||||
MainForm.Instance.Invoke(new Action(() => {
|
||||
string command = Microsoft.VisualBasic.Interaction.InputBox("Enter URL to be opened.");
|
||||
if (string.IsNullOrEmpty(command)) return;
|
||||
mp.LoadFiles(command);
|
||||
}));
|
||||
}
|
||||
|
||||
public static void load_sub(string[] args)
|
||||
{
|
||||
MainForm.Instance.Invoke(new Action(() => {
|
||||
using (var d = new OpenFileDialog())
|
||||
{
|
||||
d.InitialDirectory = Path.GetDirectoryName(mp.get_property_string("path", false));
|
||||
d.Multiselect = true;
|
||||
|
||||
if (d.ShowDialog() == DialogResult.OK)
|
||||
foreach (string i in d.FileNames)
|
||||
mp.commandv("sub-add", i);
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
public static void load_audio(string[] args)
|
||||
{
|
||||
MainForm.Instance.Invoke(new Action(() => {
|
||||
using (var d = new OpenFileDialog())
|
||||
{
|
||||
d.InitialDirectory = Path.GetDirectoryName(mp.get_property_string("path", false));
|
||||
d.Multiselect = true;
|
||||
|
||||
if (d.ShowDialog() == DialogResult.OK)
|
||||
foreach (string i in d.FileNames)
|
||||
mp.commandv("audio-add", i);
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
public static void cycle_audio(string[] args)
|
||||
{
|
||||
string filePath = mp.get_property_string("path", false);
|
||||
if (!File.Exists(filePath)) return;
|
||||
|
||||
using (MediaInfo mi = new MediaInfo(filePath))
|
||||
{
|
||||
MediaTrack[] audTracks = mp.MediaTracks.Where(track => track.Type == "a").ToArray();
|
||||
if (audTracks.Length < 2) return;
|
||||
int aid = mp.get_property_int("aid");
|
||||
aid += 1;
|
||||
if (aid > audTracks.Length) aid = 1;
|
||||
mp.commandv("set", "aid", aid.ToString());
|
||||
mp.commandv("show-text", audTracks[aid - 1].Text.Substring(3), "5000");
|
||||
}
|
||||
}
|
||||
|
||||
public static void manage_file_associations(string[] args)
|
||||
{
|
||||
using (var td = new TaskDialog<string>())
|
||||
{
|
||||
td.MainInstruction = "Choose an option.";
|
||||
td.MainIcon = MsgIcon.Shield;
|
||||
|
||||
td.AddCommandLink("Register video file extensions", "video");
|
||||
td.AddCommandLink("Register audio file extensions", "audio");
|
||||
td.AddCommandLink("Unregister file extensions", "unreg");
|
||||
|
||||
string result = td.Show();
|
||||
|
||||
if (!string.IsNullOrEmpty(result))
|
||||
{
|
||||
using (var proc = new Process())
|
||||
{
|
||||
proc.StartInfo.FileName = Application.ExecutablePath;
|
||||
proc.StartInfo.Arguments = "--reg-file-assoc " + result;
|
||||
proc.StartInfo.Verb = "runas";
|
||||
try {
|
||||
proc.Start();
|
||||
}
|
||||
catch (Exception)
|
||||
{ }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
<UserControl x:Class="Controls.SearchTextBoxUserControl"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
<Grid x:Name="SearchTextBoxUserControl1" Background="{Binding Path=Background, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}">
|
||||
<TextBlock x:Name="HintTextBlock" Margin="5,2" Text="Find a setting" Foreground="LightSteelBlue" VerticalAlignment="Center" Background="{Binding Path=Background, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}" />
|
||||
<TextBox Name="SearchTextBox" Height="25" Padding="1,2,0,0" BorderThickness="2" Background="Transparent" TextChanged="SearchTextBox_TextChanged" Foreground="{Binding Path=Foreground, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}" CaretBrush="{Binding Path=Foreground, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}" />
|
||||
<Button x:Name="SearchClearButton" Background="Transparent" HorizontalAlignment="Right" Margin="2,0,4,0" FontSize="10" Width="17" Height="17" Visibility="Hidden" Click="SearchClearButton_Click" FontFamily="Marlett" Foreground="{Binding Path=Foreground2, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}">r</Button>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
@@ -2,6 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Windows;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Navigation;
|
||||
|
||||
@@ -14,8 +15,10 @@ namespace DynamicGUI
|
||||
public static List<SettingBase> LoadSettings(string content)
|
||||
{
|
||||
TomlTable table;
|
||||
|
||||
using (StringReader reader = new StringReader(content))
|
||||
table = TOML.Parse(reader);
|
||||
|
||||
List<SettingBase> settingsList = new List<SettingBase>();
|
||||
|
||||
foreach (TomlTable setting in table["settings"])
|
||||
@@ -28,56 +31,74 @@ namespace DynamicGUI
|
||||
baseSetting = optionSetting;
|
||||
optionSetting.Default = setting["default"];
|
||||
optionSetting.Value = optionSetting.Default;
|
||||
optionSetting.StartValue = optionSetting.Default;
|
||||
|
||||
foreach (TomlTable option in setting["options"])
|
||||
{
|
||||
var opt = new OptionSettingOption();
|
||||
opt.Name = option["name"];
|
||||
|
||||
if (option.HasKey("help"))
|
||||
opt.Help = option["help"];
|
||||
|
||||
if (option.HasKey("text"))
|
||||
opt.Text = option["text"];
|
||||
else if (opt.Name == optionSetting.Default)
|
||||
opt.Text = opt.Name + " (Default)";
|
||||
|
||||
opt.OptionSetting = optionSetting;
|
||||
optionSetting.Options.Add(opt);
|
||||
}
|
||||
}
|
||||
else if (setting["default"].IsString)
|
||||
else
|
||||
{
|
||||
StringSetting stringSetting = new StringSetting();
|
||||
baseSetting = stringSetting;
|
||||
stringSetting.Default = setting["default"];
|
||||
if (setting.HasKey("folder")) stringSetting.IsFolder = true;
|
||||
stringSetting.Default = setting.HasKey("default") ? setting["default"].ToString() : "";
|
||||
}
|
||||
|
||||
baseSetting.Name = setting["name"];
|
||||
baseSetting.File = setting["file"];
|
||||
baseSetting.Filter = setting["filter"];
|
||||
|
||||
if (setting.HasKey("help")) baseSetting.Help = setting["help"];
|
||||
if (setting.HasKey("helpurl")) baseSetting.HelpURL = setting["helpurl"];
|
||||
if (setting.HasKey("url")) baseSetting.URL = setting["url"];
|
||||
if (setting.HasKey("width")) baseSetting.Width = setting["width"];
|
||||
if (setting.HasKey("type")) baseSetting.Type = setting["type"];
|
||||
|
||||
settingsList.Add(baseSetting);
|
||||
}
|
||||
return settingsList;
|
||||
}
|
||||
}
|
||||
|
||||
public class ConfItem
|
||||
{
|
||||
public string Name { get; set; } = "";
|
||||
public string Value { get; set; } = "";
|
||||
public string Comment { get; set; } = "";
|
||||
public string LineComment { get; set; } = "";
|
||||
public string Section { get; set; } = "";
|
||||
public string File { get; set; } = "";
|
||||
public bool IsSectionItem { get; set; }
|
||||
public SettingBase SettingBase { get; set; }
|
||||
}
|
||||
|
||||
public abstract class SettingBase
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public string File { get; set; }
|
||||
public string Value { get; set; }
|
||||
public string StartValue { get; set; }
|
||||
public string Help { get; set; }
|
||||
public string Default { get; set; }
|
||||
public string HelpURL { get; set; }
|
||||
public string URL { get; set; }
|
||||
public string Filter { get; set; }
|
||||
public string Type { get; set; }
|
||||
public int Width { get; set; }
|
||||
public ConfItem ConfItem { get; set; }
|
||||
}
|
||||
|
||||
public class StringSetting : SettingBase
|
||||
{
|
||||
public bool IsFolder { get; set; }
|
||||
}
|
||||
|
||||
public class OptionSetting : SettingBase
|
||||
@@ -100,7 +121,7 @@ namespace DynamicGUI
|
||||
set => _Text = value;
|
||||
}
|
||||
|
||||
public bool IsChecked
|
||||
public bool Checked
|
||||
{
|
||||
get => OptionSetting.Value == Name ;
|
||||
set {
|
||||
@@ -108,6 +129,11 @@ namespace DynamicGUI
|
||||
OptionSetting.Value = Name;
|
||||
}
|
||||
}
|
||||
|
||||
public Visibility Visibility
|
||||
{
|
||||
get => string.IsNullOrEmpty(Help) ? Visibility.Collapsed : Visibility.Visible;
|
||||
}
|
||||
}
|
||||
|
||||
interface ISettingControl
|
||||
|
||||
@@ -4,22 +4,58 @@
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:DynamicGUI"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
xmlns:UI="clr-namespace:UI"
|
||||
mc:Ignorable="d"
|
||||
|
||||
d:DesignHeight="450"
|
||||
d:DesignWidth="800">
|
||||
|
||||
<Grid Margin="20,0">
|
||||
<StackPanel>
|
||||
<TextBox x:Name="TitleTextBox" FontSize="24" Margin="0,10" BorderThickness="0" IsReadOnly="True" Foreground="{Binding Path=Foreground, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}" Background="{Binding Path=Background, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}"></TextBox>
|
||||
<TextBox x:Name="TitleTextBox"
|
||||
FontSize="24"
|
||||
Margin="0,10"
|
||||
BorderThickness="0"
|
||||
IsReadOnly="True"
|
||||
Foreground="{x:Static UI:Theme.Heading}"
|
||||
Background="{x:Static UI:Theme.Background}" />
|
||||
|
||||
<ItemsControl x:Name="ItemsControl">
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<WrapPanel Orientation="Vertical">
|
||||
<RadioButton x:Name="RadioButton" VerticalContentAlignment="Center" IsChecked="{Binding IsChecked}" GroupName="{Binding OptionSetting.Name}" Content="{Binding Text}" FontSize="16" FontWeight="Normal" VerticalAlignment="Top" Foreground="{Binding Path=Foreground, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}"></RadioButton>
|
||||
<TextBox x:Name="ItemHelpTextBox" TextWrapping="WrapWithOverflow" Text="{Binding Help}" Margin="10,0,0,0" BorderThickness="0" IsReadOnly="True" Padding="7,0,0,0" MinHeight="0" Foreground="{Binding Path=Foreground2, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}" Background="{Binding Path=Background, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}"></TextBox>
|
||||
<RadioButton x:Name="RadioButton"
|
||||
VerticalContentAlignment="Center"
|
||||
IsChecked="{Binding Checked}"
|
||||
GroupName="{Binding OptionSetting.Name}"
|
||||
Content="{Binding Text}"
|
||||
FontSize="16"
|
||||
FontWeight="Normal"
|
||||
VerticalAlignment="Top"
|
||||
Foreground="{x:Static UI:Theme.Foreground}"/>
|
||||
|
||||
<TextBox x:Name="ItemHelpTextBox"
|
||||
TextWrapping="WrapWithOverflow"
|
||||
Text="{Binding Help}"
|
||||
Visibility="{Binding Visibility}"
|
||||
Margin="10,0,0,0" BorderThickness="0"
|
||||
IsReadOnly="True" Padding="7,0,0,0"
|
||||
MinHeight="0"
|
||||
Foreground="{x:Static UI:Theme.Foreground2}"
|
||||
Background="{x:Static UI:Theme.Background}"/>
|
||||
|
||||
</WrapPanel>
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
<TextBox x:Name="HelpTextBox" TextWrapping="WrapWithOverflow" BorderThickness="0" IsReadOnly="True" Margin="0,10,0,0" Foreground="{Binding Path=Foreground, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=UserControl}}" Background="{Binding Path=Background, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=UserControl}}"></TextBox>
|
||||
|
||||
<TextBox x:Name="HelpTextBox"
|
||||
TextWrapping="WrapWithOverflow"
|
||||
BorderThickness="0"
|
||||
IsReadOnly="True"
|
||||
Margin="0,10,0,0"
|
||||
Foreground="{x:Static UI:Theme.Foreground}"
|
||||
Background="{x:Static UI:Theme.Background}"/>
|
||||
<TextBlock x:Name="LinkTextBlock" Margin="0,10">
|
||||
<local:HyperlinkEx x:Name="Link"></local:HyperlinkEx>
|
||||
</TextBlock>
|
||||
|
||||
@@ -12,11 +12,13 @@ namespace DynamicGUI
|
||||
OptionSetting = optionSetting;
|
||||
InitializeComponent();
|
||||
TitleTextBox.Text = optionSetting.Name;
|
||||
if (string.IsNullOrEmpty(optionSetting.Help))
|
||||
HelpTextBox.Visibility = Visibility.Collapsed;
|
||||
HelpTextBox.Text = optionSetting.Help;
|
||||
ItemsControl.ItemsSource = optionSetting.Options;
|
||||
Link.SetURL(optionSetting.HelpURL);
|
||||
if (string.IsNullOrEmpty(optionSetting.HelpURL))
|
||||
if (string.IsNullOrEmpty(optionSetting.URL))
|
||||
LinkTextBlock.Visibility = Visibility.Collapsed;
|
||||
Link.SetURL(optionSetting.URL);
|
||||
}
|
||||
|
||||
private string _SearchableText;
|
||||
|
||||
@@ -4,21 +4,52 @@
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:DynamicGUI"
|
||||
xmlns:UI="clr-namespace:UI"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450"
|
||||
d:DesignWidth="800" >
|
||||
d:DesignWidth="800">
|
||||
|
||||
<Grid Margin="20,0">
|
||||
<StackPanel>
|
||||
<TextBox x:Name="TitleTextBox" FontSize="24" Margin="0,10" BorderThickness="0" IsReadOnly="True" Foreground="{Binding Path=Foreground, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}" Background="{Binding Path=Background, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}"></TextBox>
|
||||
<TextBox x:Name="TitleTextBox"
|
||||
FontSize="24"
|
||||
Margin="0,10"
|
||||
BorderThickness="0"
|
||||
IsReadOnly="True"
|
||||
Foreground="{x:Static UI:Theme.Heading}"
|
||||
Background="{x:Static UI:Theme.Background}"/>
|
||||
|
||||
<Grid Margin="0,0,0,10">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBox x:Name="ValueTextBox" Text="{Binding Path=Text, ElementName=StringSettingControl1, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Width="150" HorizontalAlignment="Left" Height="20" Foreground="{Binding Path=Foreground, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}" Background="{Binding Path=Background, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}"/>
|
||||
<Button x:Name="Button" Height="20" Grid.Column="1" Visibility="{Binding Path=Text, ElementName=StringSettingControl1}" Margin="5,0,0,0" Width="20" Click="Button_Click">...</Button>
|
||||
<TextBox x:Name="ValueTextBox"
|
||||
Text="{Binding Path=Text, ElementName=StringSettingControl1, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
|
||||
Width="150"
|
||||
Height="20"
|
||||
HorizontalAlignment="Left"
|
||||
Foreground="{x:Static UI:Theme.Foreground}"
|
||||
Background="{x:Static UI:Theme.Background}"
|
||||
CaretBrush="{x:Static UI:Theme.Foreground}"
|
||||
TextChanged="ValueTextBox_TextChanged"/>
|
||||
|
||||
<Button x:Name="Button"
|
||||
Height="20"
|
||||
Grid.Column="1"
|
||||
Visibility="{Binding Path=Text, ElementName=StringSettingControl1}"
|
||||
Margin="5,0,0,0"
|
||||
Width="20"
|
||||
Click="Button_Click">...</Button>
|
||||
</Grid>
|
||||
<TextBox x:Name="HelpTextBox" TextWrapping="WrapWithOverflow" Margin="0,0,0,10" BorderThickness="0" IsReadOnly="True" Foreground="{Binding Path=Foreground, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}" Background="{Binding Path=Background, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}"></TextBox>
|
||||
|
||||
<TextBox x:Name="HelpTextBox"
|
||||
TextWrapping="WrapWithOverflow"
|
||||
BorderThickness="0"
|
||||
IsReadOnly="True"
|
||||
Foreground="{x:Static UI:Theme.Foreground}"
|
||||
Background="{x:Static UI:Theme.Background}"/>
|
||||
|
||||
<TextBlock x:Name="LinkTextBlock" Margin="0,10">
|
||||
<local:HyperlinkEx x:Name="Link"></local:HyperlinkEx>
|
||||
</TextBlock>
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
using System.Windows;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Media;
|
||||
using WinForms = System.Windows.Forms;
|
||||
|
||||
namespace DynamicGUI
|
||||
{
|
||||
@@ -13,13 +18,13 @@ namespace DynamicGUI
|
||||
InitializeComponent();
|
||||
TitleTextBox.Text = stringSetting.Name;
|
||||
HelpTextBox.Text = stringSetting.Help;
|
||||
ValueTextBox.Text = stringSetting.Value;
|
||||
if (stringSetting.Width > 0)
|
||||
ValueTextBox.Width = stringSetting.Width;
|
||||
if (!StringSetting.IsFolder)
|
||||
ValueTextBox.Text = StringSetting.Value;
|
||||
if (StringSetting.Width > 0)
|
||||
ValueTextBox.Width = StringSetting.Width;
|
||||
if (StringSetting.Type != "folder" && StringSetting.Type != "color")
|
||||
Button.Visibility = Visibility.Hidden;
|
||||
Link.SetURL(StringSetting.HelpURL);
|
||||
if (string.IsNullOrEmpty(stringSetting.HelpURL))
|
||||
Link.SetURL(StringSetting.URL);
|
||||
if (string.IsNullOrEmpty(stringSetting.URL))
|
||||
LinkTextBlock.Visibility = Visibility.Collapsed;
|
||||
}
|
||||
|
||||
@@ -29,7 +34,6 @@ namespace DynamicGUI
|
||||
get {
|
||||
if (_SearchableText is null)
|
||||
_SearchableText = (TitleTextBox.Text + HelpTextBox.Text +ValueTextBox.Text).ToLower();
|
||||
|
||||
return _SearchableText;
|
||||
}
|
||||
}
|
||||
@@ -45,12 +49,63 @@ namespace DynamicGUI
|
||||
|
||||
private void Button_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
using (var d = new System.Windows.Forms.FolderBrowserDialog())
|
||||
switch (StringSetting.Type)
|
||||
{
|
||||
d.Description = "Choose a folder.";
|
||||
d.SelectedPath = ValueTextBox.Text;
|
||||
if (d.ShowDialog() == System.Windows.Forms.DialogResult.OK)
|
||||
ValueTextBox.Text = d.SelectedPath;
|
||||
case "folder":
|
||||
using (var d = new WinForms.FolderBrowserDialog())
|
||||
{
|
||||
d.Description = "Choose a folder.";
|
||||
d.SelectedPath = ValueTextBox.Text;
|
||||
if (d.ShowDialog() == WinForms.DialogResult.OK)
|
||||
ValueTextBox.Text = d.SelectedPath;
|
||||
}
|
||||
break;
|
||||
case "color":
|
||||
using (var dialog = new WinForms.ColorDialog())
|
||||
{
|
||||
dialog.FullOpen = true;
|
||||
|
||||
try {
|
||||
if (!string.IsNullOrEmpty(ValueTextBox.Text))
|
||||
{
|
||||
Color col = GetColor(ValueTextBox.Text);
|
||||
dialog.Color = System.Drawing.Color.FromArgb(col.A, col.R, col.G, col.B);
|
||||
}
|
||||
} catch {}
|
||||
|
||||
if (dialog.ShowDialog() == WinForms.DialogResult.OK)
|
||||
ValueTextBox.Text = "#" + dialog.Color.ToArgb().ToString("X8");
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void ValueTextBox_TextChanged(object sender, TextChangedEventArgs e) => Update();
|
||||
|
||||
Color GetColor(string value)
|
||||
{
|
||||
if (value.Contains("/"))
|
||||
{
|
||||
string[] a = value.Split('/');
|
||||
|
||||
if (a.Length == 3)
|
||||
return Color.FromRgb(ToByte(a[0]), ToByte(a[1]), ToByte(a[2]));
|
||||
else if (a.Length == 4)
|
||||
return Color.FromArgb(ToByte(a[3]), ToByte(a[0]), ToByte(a[1]), ToByte(a[2]));
|
||||
}
|
||||
|
||||
return (Color)ColorConverter.ConvertFromString(value);
|
||||
|
||||
Byte ToByte(string val) => Convert.ToByte(Convert.ToSingle(val, CultureInfo.InvariantCulture) * 255);
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
if (StringSetting.Type == "color")
|
||||
{
|
||||
Color c = Colors.Transparent;
|
||||
if (ValueTextBox.Text != "") try { c = GetColor(ValueTextBox.Text); } catch {}
|
||||
ValueTextBox.Background = new SolidColorBrush(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1752,7 +1752,6 @@ namespace Tommy
|
||||
}
|
||||
else
|
||||
stringBuilder.Append(c);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,587 +0,0 @@
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading;
|
||||
using System.Windows.Forms;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Globalization;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace mpvnet
|
||||
{
|
||||
public partial class MainForm : Form
|
||||
{
|
||||
public static MainForm Instance { get; set; }
|
||||
public static IntPtr Hwnd { get; set; }
|
||||
|
||||
public new ContextMenuStripEx ContextMenu { get; set; }
|
||||
|
||||
Point LastCursorPosChanged;
|
||||
int LastCursorChangedTickCount;
|
||||
bool IgnoreDpiChanged = true;
|
||||
List<string> RecentFiles;
|
||||
|
||||
public string MpvNetDarkMode { get; set; } = "always";
|
||||
public bool MpvFullscreen { get; set; }
|
||||
public float MpvAutofit { get; set; } = 0.50f;
|
||||
public int MpvScreen { get; set; } = -1;
|
||||
public string MpvSid { get; set; } = "";
|
||||
public string MpvAid { get; set; } = "";
|
||||
public string MpvVid { get; set; } = "";
|
||||
public int MpvEdition { get; set; }
|
||||
|
||||
public MainForm()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
try
|
||||
{
|
||||
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
|
||||
Application.ThreadException += Application_ThreadException;
|
||||
Msg.SupportURL = "https://github.com/stax76/mpv.net#support";
|
||||
Instance = this;
|
||||
WPF.WPF.Init();
|
||||
System.Windows.Application.Current.ShutdownMode = System.Windows.ShutdownMode.OnExplicitShutdown;
|
||||
Hwnd = Handle;
|
||||
MinimumSize = new Size(FontHeight * 16, FontHeight * 9);
|
||||
Text += " " + Application.ProductVersion;
|
||||
|
||||
object recent = RegistryHelp.GetObject("HKCU\\Software\\" + Application.ProductName, "Recent");
|
||||
|
||||
if (recent is string[] r)
|
||||
RecentFiles = new List<string>(r);
|
||||
else
|
||||
RecentFiles = new List<string>();
|
||||
|
||||
foreach (var i in mp.mpvConf)
|
||||
ProcessMpvProperty(i.Key, i.Value);
|
||||
|
||||
foreach (var i in mp.mpvNetConf)
|
||||
ProcessMpvNetProperty(i.Key, i.Value);
|
||||
|
||||
ProcessCommandLineEarly();
|
||||
|
||||
if (MpvScreen == -1) MpvScreen = Array.IndexOf(Screen.AllScreens, Screen.PrimaryScreen);
|
||||
SetScreen(MpvScreen);
|
||||
|
||||
ChangeFullscreen(MpvFullscreen);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Msg.ShowException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
void ContextMenu_Opening(object sender, CancelEventArgs e)
|
||||
{
|
||||
lock (mp.MediaTracks)
|
||||
{
|
||||
MenuItem trackMenuItem = FindMenuItem("Track");
|
||||
|
||||
if (trackMenuItem != null)
|
||||
{
|
||||
trackMenuItem.DropDownItems.Clear();
|
||||
|
||||
MediaTrack[] audTracks = mp.MediaTracks.Where(track => track.Type == "a").ToArray();
|
||||
MediaTrack[] subTracks = mp.MediaTracks.Where(track => track.Type == "s").ToArray();
|
||||
MediaTrack[] vidTracks = mp.MediaTracks.Where(track => track.Type == "v").ToArray();
|
||||
MediaTrack[] ediTracks = mp.MediaTracks.Where(track => track.Type == "e").ToArray();
|
||||
|
||||
foreach (MediaTrack track in vidTracks)
|
||||
{
|
||||
MenuItem mi = new MenuItem(track.Text);
|
||||
mi.Action = () => { mp.commandv("set", "vid", track.ID.ToString()); };
|
||||
mi.Checked = MpvVid == track.ID.ToString();
|
||||
trackMenuItem.DropDownItems.Add(mi);
|
||||
}
|
||||
|
||||
if (vidTracks.Length > 0)
|
||||
trackMenuItem.DropDownItems.Add(new ToolStripSeparator());
|
||||
|
||||
foreach (MediaTrack track in audTracks)
|
||||
{
|
||||
MenuItem mi = new MenuItem(track.Text);
|
||||
mi.Action = () => { mp.commandv("set", "aid", track.ID.ToString()); };
|
||||
mi.Checked = MpvAid == track.ID.ToString();
|
||||
trackMenuItem.DropDownItems.Add(mi);
|
||||
}
|
||||
|
||||
if (subTracks.Length > 0)
|
||||
trackMenuItem.DropDownItems.Add(new ToolStripSeparator());
|
||||
|
||||
foreach (MediaTrack track in subTracks)
|
||||
{
|
||||
MenuItem mi = new MenuItem(track.Text);
|
||||
mi.Action = () => { mp.commandv("set", "sid", track.ID.ToString()); };
|
||||
mi.Checked = MpvSid == track.ID.ToString();
|
||||
trackMenuItem.DropDownItems.Add(mi);
|
||||
}
|
||||
|
||||
if (subTracks.Length > 0)
|
||||
{
|
||||
MenuItem mi = new MenuItem("S: No subtitles");
|
||||
mi.Action = () => { mp.commandv("set", "sid", "no"); };
|
||||
mi.Checked = MpvSid == "no";
|
||||
trackMenuItem.DropDownItems.Add(mi);
|
||||
}
|
||||
|
||||
if (ediTracks.Length > 0)
|
||||
trackMenuItem.DropDownItems.Add(new ToolStripSeparator());
|
||||
|
||||
foreach (MediaTrack track in ediTracks)
|
||||
{
|
||||
MenuItem mi = new MenuItem(track.Text);
|
||||
mi.Action = () => { mp.commandv("set", "edition", track.ID.ToString()); };
|
||||
mi.Checked = MpvEdition == track.ID;
|
||||
trackMenuItem.DropDownItems.Add(mi);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
lock (mp.Chapters)
|
||||
{
|
||||
MenuItem chaptersMenuItem = FindMenuItem("Chapters");
|
||||
|
||||
if (chaptersMenuItem != null)
|
||||
{
|
||||
chaptersMenuItem.DropDownItems.Clear();
|
||||
|
||||
foreach (var i in mp.Chapters)
|
||||
{
|
||||
MenuItem mi = new MenuItem(i.Key);
|
||||
mi.ShortcutKeyDisplayString = TimeSpan.FromSeconds(i.Value).ToString().Substring(0, 8) + " ";
|
||||
mi.Action = () => { mp.commandv("seek", i.Value.ToString(CultureInfo.InvariantCulture), "absolute"); };
|
||||
chaptersMenuItem.DropDownItems.Add(mi);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MenuItem recent = FindMenuItem("Recent");
|
||||
|
||||
if (recent != null)
|
||||
{
|
||||
recent.DropDownItems.Clear();
|
||||
|
||||
foreach (string path in RecentFiles)
|
||||
MenuItem.Add(recent.DropDownItems, path, () => mp.LoadFiles(path));
|
||||
|
||||
recent.DropDownItems.Add(new ToolStripSeparator());
|
||||
MenuItem mi = new MenuItem("Clear List");
|
||||
mi.Action = () => RecentFiles.Clear();
|
||||
recent.DropDownItems.Add(mi);
|
||||
}
|
||||
}
|
||||
|
||||
public MenuItem FindMenuItem(string text) => FindMenuItem(text, ContextMenu.Items);
|
||||
|
||||
MenuItem FindMenuItem(string text, ToolStripItemCollection items)
|
||||
{
|
||||
foreach (var item in items)
|
||||
{
|
||||
if (item is MenuItem mi)
|
||||
{
|
||||
if (mi.Text.StartsWith(text) && mi.Text.Trim() == text)
|
||||
return mi;
|
||||
if (mi.DropDownItems.Count > 0)
|
||||
{
|
||||
MenuItem val = FindMenuItem(text, mi.DropDownItems);
|
||||
if (val != null) return val;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected void SetScreen(int targetIndex)
|
||||
{
|
||||
Screen[] screens = Screen.AllScreens;
|
||||
if (targetIndex < 0) targetIndex = 0;
|
||||
if (targetIndex > screens.Length - 1) targetIndex = screens.Length - 1;
|
||||
SetScreen(screens[Array.IndexOf(screens, screens[targetIndex])]);
|
||||
}
|
||||
|
||||
protected void SetScreen(Screen screen)
|
||||
{
|
||||
Rectangle target = screen.Bounds;
|
||||
Left = target.X + Convert.ToInt32((target.Width - Width) / 2.0);
|
||||
Top = target.Y + Convert.ToInt32((target.Height - Height) / 2.0);
|
||||
SetStartFormPositionAndSize();
|
||||
}
|
||||
|
||||
void SetStartFormPositionAndSize()
|
||||
{
|
||||
if (IsFullscreen || mp.VideoSize.Width == 0) return;
|
||||
Screen screen = Screen.FromControl(this);
|
||||
int height = Convert.ToInt32(screen.Bounds.Height * MpvAutofit);
|
||||
int width = Convert.ToInt32(height * mp.VideoSize.Width / (double)mp.VideoSize.Height);
|
||||
Point middlePos = new Point(Left + Width / 2, Top + Height / 2);
|
||||
var rect = new Native.RECT(new Rectangle(screen.Bounds.X, screen.Bounds.Y, width, height));
|
||||
NativeHelp.AddWindowBorders(Handle, ref rect);
|
||||
int left = middlePos.X - rect.Width / 2;
|
||||
int top = middlePos.Y - rect.Height / 2;
|
||||
Native.SetWindowPos(Handle, IntPtr.Zero /* HWND_TOP */, left, top, rect.Width, rect.Height, 4 /* SWP_NOZORDER */);
|
||||
}
|
||||
|
||||
void SetFormPositionAndSizeKeepHeight()
|
||||
{
|
||||
if (IsFullscreen || mp.VideoSize.Width == 0) return;
|
||||
Screen screen = Screen.FromControl(this);
|
||||
int height = ClientSize.Height;
|
||||
if (height > screen.Bounds.Height * 0.9) height = Convert.ToInt32(screen.Bounds.Height * MpvAutofit);
|
||||
int width = Convert.ToInt32(height * mp.VideoSize.Width / (double)mp.VideoSize.Height);
|
||||
Point middlePos = new Point(Left + Width / 2, Top + Height / 2);
|
||||
var rect = new Native.RECT(new Rectangle(screen.Bounds.X, screen.Bounds.Y, width, height));
|
||||
NativeHelp.AddWindowBorders(Handle, ref rect);
|
||||
int left = middlePos.X - rect.Width / 2;
|
||||
int top = middlePos.Y - rect.Height / 2;
|
||||
Screen[] screens = Screen.AllScreens;
|
||||
if (left < screens[0].Bounds.Left) left = screens[0].Bounds.Left;
|
||||
int maxLeft = screens[0].Bounds.Left + screens.Select((sc) => sc.Bounds.Width).Sum() - rect.Width - SystemInformation.CaptionHeight;
|
||||
if (left > maxLeft) left = maxLeft;
|
||||
Native.SetWindowPos(Handle, IntPtr.Zero /* HWND_TOP */, left, top, rect.Width, rect.Height, 4 /* SWP_NOZORDER */);
|
||||
}
|
||||
|
||||
protected void ProcessCommandLineEarly()
|
||||
{
|
||||
var args = Environment.GetCommandLineArgs().Skip(1);
|
||||
|
||||
foreach (string i in args)
|
||||
{
|
||||
if (i.StartsWith("--"))
|
||||
{
|
||||
if (i.Contains("="))
|
||||
{
|
||||
string left = i.Substring(2, i.IndexOf("=") - 2);
|
||||
string right = i.Substring(left.Length + 3);
|
||||
ProcessMpvProperty(left, right);
|
||||
ProcessMpvNetProperty(left, right);
|
||||
}
|
||||
else
|
||||
{
|
||||
string switchName = i.Substring(2);
|
||||
|
||||
switch (switchName)
|
||||
{
|
||||
case "fs":
|
||||
case "fullscreen":
|
||||
MpvFullscreen = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ProcessMpvProperty(string name, string value)
|
||||
{
|
||||
switch (name)
|
||||
{
|
||||
case "autofit":
|
||||
if (value.Length == 3 && value.EndsWith("%"))
|
||||
if (int.TryParse(value.Substring(0, 2), out int result))
|
||||
MpvAutofit = result / 100f;
|
||||
break;
|
||||
case "fs":
|
||||
case "fullscreen":
|
||||
MpvFullscreen = value == "yes";
|
||||
break;
|
||||
case "screen":
|
||||
MpvScreen = Convert.ToInt32(value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ProcessMpvNetProperty(string name, string value)
|
||||
{
|
||||
switch (name)
|
||||
{
|
||||
case "dark-mode":
|
||||
MpvNetDarkMode = value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void BuildMenu()
|
||||
{
|
||||
string content = File.ReadAllText(mp.InputConfPath);
|
||||
var items = CommandItem.GetItems(content);
|
||||
|
||||
if (!content.Contains("#menu:"))
|
||||
{
|
||||
var defaultItems = CommandItem.GetItems(Properties.Resources.inputConf);
|
||||
foreach (CommandItem item in items)
|
||||
foreach (CommandItem defaultItem in defaultItems)
|
||||
if (item.Command == defaultItem.Command)
|
||||
defaultItem.Input = item.Input;
|
||||
items = defaultItems;
|
||||
}
|
||||
|
||||
foreach (CommandItem item in items)
|
||||
{
|
||||
if (string.IsNullOrEmpty(item.Path))
|
||||
continue;
|
||||
string path = item.Path.Replace("&", "&&");
|
||||
MenuItem menuItem = ContextMenu.Add(path, () => {
|
||||
try {
|
||||
mp.command_string(item.Command);
|
||||
} catch (Exception ex) {
|
||||
Msg.ShowException(ex);
|
||||
}
|
||||
});
|
||||
if (menuItem != null)
|
||||
menuItem.ShortcutKeyDisplayString = item.Input + " ";
|
||||
}
|
||||
}
|
||||
|
||||
void ContextMenu_Opened(object sender, EventArgs e) => CursorHelp.Show();
|
||||
|
||||
private void Mp_FileLoaded()
|
||||
{
|
||||
string path = mp.get_property_string("path");
|
||||
BeginInvoke(new Action(() => {
|
||||
if (File.Exists(path) || path.StartsWith("http"))
|
||||
Text = Path.GetFileName(path) + " - mpv.net " + Application.ProductVersion;
|
||||
else
|
||||
Text = "mpv.net " + Application.ProductVersion;
|
||||
}));
|
||||
if (RecentFiles.Contains(path)) RecentFiles.Remove(path);
|
||||
RecentFiles.Insert(0, path);
|
||||
if (RecentFiles.Count > 15) RecentFiles.RemoveAt(15);
|
||||
}
|
||||
|
||||
void Mp_Idle() => BeginInvoke(new Action(() => { Text = "mpv.net " + Application.ProductVersion; }));
|
||||
|
||||
void CM_Popup(object sender, EventArgs e) => CursorHelp.Show();
|
||||
|
||||
void Application_ThreadException(object sender, ThreadExceptionEventArgs e)
|
||||
{
|
||||
Msg.ShowException(e.Exception);
|
||||
}
|
||||
|
||||
void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
|
||||
{
|
||||
Msg.ShowError(e.ExceptionObject.ToString());
|
||||
}
|
||||
|
||||
void mp_VideoSizeChanged()
|
||||
{
|
||||
BeginInvoke(new Action(() => SetFormPositionAndSizeKeepHeight()));
|
||||
}
|
||||
|
||||
void mp_Shutdown()
|
||||
{
|
||||
BeginInvoke(new Action(() => Close()));
|
||||
}
|
||||
|
||||
public bool IsFullscreen => WindowState == FormWindowState.Maximized;
|
||||
|
||||
void mpPropChangeFullscreen(bool value)
|
||||
{
|
||||
BeginInvoke(new Action(() => ChangeFullscreen(value)));
|
||||
}
|
||||
|
||||
void ChangeFullscreen(bool value)
|
||||
{
|
||||
if (value)
|
||||
{
|
||||
if (FormBorderStyle != FormBorderStyle.None)
|
||||
{
|
||||
FormBorderStyle = FormBorderStyle.None;
|
||||
WindowState = FormWindowState.Maximized;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
WindowState = FormWindowState.Normal;
|
||||
FormBorderStyle = FormBorderStyle.Sizable;
|
||||
SetFormPositionAndSizeKeepHeight();
|
||||
}
|
||||
}
|
||||
|
||||
protected override void WndProc(ref Message m)
|
||||
{
|
||||
//Debug.WriteLine(m);
|
||||
|
||||
switch (m.Msg)
|
||||
{
|
||||
case 0x0201: // WM_LBUTTONDOWN
|
||||
case 0x0202: // WM_LBUTTONUP
|
||||
case 0x0100: // WM_KEYDOWN
|
||||
case 0x0101: // WM_KEYUP
|
||||
case 0x0104: // WM_SYSKEYDOWN
|
||||
case 0x0105: // WM_SYSKEYUP
|
||||
case 0x020A: // WM_MOUSEWHEEL
|
||||
if (mp.MpvWindowHandle != IntPtr.Zero)
|
||||
Native.SendMessage(mp.MpvWindowHandle, m.Msg, m.WParam, m.LParam);
|
||||
break;
|
||||
case 0x319: // WM_APPCOMMAND
|
||||
if (mp.MpvWindowHandle != IntPtr.Zero)
|
||||
Native.PostMessage(mp.MpvWindowHandle, m.Msg, m.WParam, m.LParam);
|
||||
break;
|
||||
case 0x203: // Native.WM.LBUTTONDBLCLK
|
||||
if (!IsMouseInOSC())
|
||||
mp.command_string("cycle fullscreen");
|
||||
break;
|
||||
case 0x02E0: // WM_DPICHANGED
|
||||
if (IgnoreDpiChanged) break;
|
||||
var r2 = Marshal.PtrToStructure<Native.RECT>(m.LParam);
|
||||
Native.SetWindowPos(Handle, IntPtr.Zero, r2.Left, r2.Top, r2.Width, r2.Height, 0);
|
||||
break;
|
||||
case 0x0214: // WM_SIZING
|
||||
var rc = Marshal.PtrToStructure<Native.RECT>(m.LParam);
|
||||
var r = rc;
|
||||
NativeHelp.SubtractWindowBorders(Handle, ref r);
|
||||
int c_w = r.Right - r.Left, c_h = r.Bottom - r.Top;
|
||||
float aspect = mp.VideoSize.Width / (float)mp.VideoSize.Height;
|
||||
int d_w = Convert.ToInt32(c_h * aspect - c_w);
|
||||
int d_h = Convert.ToInt32(c_w / aspect - c_h);
|
||||
int[] d_corners = { d_w, d_h, -d_w, -d_h };
|
||||
int[] corners = { rc.Left, rc.Top, rc.Right, rc.Bottom };
|
||||
int corner = NativeHelp.GetResizeBorder(m.WParam.ToInt32());
|
||||
|
||||
if (corner >= 0)
|
||||
corners[corner] -= d_corners[corner];
|
||||
|
||||
Marshal.StructureToPtr<Native.RECT>(new Native.RECT(corners[0], corners[1], corners[2], corners[3]), m.LParam, false);
|
||||
m.Result = new IntPtr(1);
|
||||
return;
|
||||
}
|
||||
base.WndProc(ref m);
|
||||
}
|
||||
|
||||
protected override void OnDragEnter(DragEventArgs e)
|
||||
{
|
||||
base.OnDragEnter(e);
|
||||
if (e.Data.GetDataPresent(DataFormats.FileDrop) || e.Data.GetDataPresent(DataFormats.Text))
|
||||
e.Effect = DragDropEffects.Copy;
|
||||
}
|
||||
|
||||
protected override void OnDragDrop(DragEventArgs e)
|
||||
{
|
||||
base.OnDragDrop(e);
|
||||
if (e.Data.GetDataPresent(DataFormats.FileDrop))
|
||||
mp.LoadFiles(e.Data.GetData(DataFormats.FileDrop) as String[]);
|
||||
if (e.Data.GetDataPresent(DataFormats.Text))
|
||||
mp.LoadFiles(e.Data.GetData(DataFormats.Text).ToString());
|
||||
}
|
||||
|
||||
protected override void OnMouseDown(MouseEventArgs e)
|
||||
{
|
||||
base.OnMouseDown(e);
|
||||
|
||||
if (WindowState == FormWindowState.Normal &&
|
||||
e.Button == MouseButtons.Left &&
|
||||
e.Y < ClientSize.Height * 0.9)
|
||||
{
|
||||
var HTCAPTION = new IntPtr(2);
|
||||
Native.ReleaseCapture();
|
||||
Native.PostMessage(Handle, 0xA1 /* WM_NCLBUTTONDOWN */, HTCAPTION, IntPtr.Zero);
|
||||
}
|
||||
|
||||
if (Width - e.Location.X < 10 && e.Location.Y < 10)
|
||||
mp.commandv("quit");
|
||||
}
|
||||
|
||||
protected override void OnMouseMove(MouseEventArgs e)
|
||||
{
|
||||
base.OnMouseMove(e);
|
||||
mp.command_string($"mouse {e.X} {e.Y}");
|
||||
|
||||
if (CursorHelp.IsPosDifferent(LastCursorPosChanged))
|
||||
CursorHelp.Show();
|
||||
}
|
||||
|
||||
bool IsMouseInOSC() => PointToClient(Control.MousePosition).Y > ClientSize.Height * 0.9;
|
||||
|
||||
void Timer_Tick(object sender, EventArgs e)
|
||||
{
|
||||
if (CursorHelp.IsPosDifferent(LastCursorPosChanged))
|
||||
{
|
||||
LastCursorPosChanged = Control.MousePosition;
|
||||
LastCursorChangedTickCount = Environment.TickCount;
|
||||
}
|
||||
else if (Environment.TickCount - LastCursorChangedTickCount > 1500 &&
|
||||
!IsMouseInOSC() && ClientRectangle.Contains(PointToClient(MousePosition)) &&
|
||||
Form.ActiveForm == this && !ContextMenu.Visible)
|
||||
{
|
||||
CursorHelp.Hide();
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnLoad(EventArgs e)
|
||||
{
|
||||
base.OnLoad(e);
|
||||
mp.Init();
|
||||
mp.observe_property_bool("fullscreen", mpPropChangeFullscreen);
|
||||
mp.observe_property_bool("ontop", mpPropChangeOnTop);
|
||||
mp.observe_property_string("sid", mpPropChangeSid);
|
||||
mp.observe_property_string("aid", mpPropChangeAid);
|
||||
mp.observe_property_string("vid", mpPropChangeVid);
|
||||
mp.observe_property_int("edition", mpPropChangeEdition);
|
||||
mp.Shutdown += mp_Shutdown;
|
||||
mp.VideoSizeChanged += mp_VideoSizeChanged;
|
||||
mp.FileLoaded += Mp_FileLoaded;
|
||||
mp.Idle += Mp_Idle;
|
||||
}
|
||||
|
||||
void mpPropChangeOnTop(bool value) => BeginInvoke(new Action(() => TopMost = value));
|
||||
|
||||
void mpPropChangeAid(string value) => MpvAid = value;
|
||||
|
||||
void mpPropChangeSid(string value) => MpvSid = value;
|
||||
|
||||
void mpPropChangeVid(string value) => MpvVid = value;
|
||||
|
||||
void mpPropChangeEdition(int value) => MpvEdition = value;
|
||||
|
||||
protected override void OnShown(EventArgs e)
|
||||
{
|
||||
base.OnShown(e);
|
||||
if ((MpvNetDarkMode == "system" && Sys.IsDarkTheme) || MpvNetDarkMode == "always")
|
||||
ToolStripRendererEx.ColorTheme = Color.Black;
|
||||
ContextMenu = new ContextMenuStripEx(components);
|
||||
ContextMenu.Opened += ContextMenu_Opened;
|
||||
ContextMenu.Opening += ContextMenu_Opening;
|
||||
BuildMenu();
|
||||
ContextMenuStrip = ContextMenu;
|
||||
IgnoreDpiChanged = false;
|
||||
CheckURL();
|
||||
}
|
||||
|
||||
protected override void OnFormClosed(FormClosedEventArgs e)
|
||||
{
|
||||
base.OnFormClosed(e);
|
||||
RegistryHelp.SetObject("HKCU\\Software\\" + Application.ProductName, "Recent", RecentFiles.ToArray());
|
||||
mp.commandv("quit");
|
||||
mp.AutoResetEvent.WaitOne(3000);
|
||||
}
|
||||
|
||||
protected override void OnLostFocus(EventArgs e)
|
||||
{
|
||||
base.OnLostFocus(e);
|
||||
CursorHelp.Show();
|
||||
}
|
||||
|
||||
protected override void OnActivated(EventArgs e)
|
||||
{
|
||||
base.OnActivated(e);
|
||||
CheckURL();
|
||||
}
|
||||
|
||||
void CheckURL()
|
||||
{
|
||||
string clipboard = Clipboard.GetText();
|
||||
|
||||
if (clipboard.StartsWith("http") && RegistryHelp.GetString("HKCU\\Software\\" + Application.ProductName, "LastURL") != clipboard && Visible)
|
||||
{
|
||||
RegistryHelp.SetObject("HKCU\\Software\\" + Application.ProductName, "LastURL", clipboard);
|
||||
|
||||
if (Msg.ShowQuestion("Play URL?", clipboard) == MsgResult.OK)
|
||||
mp.LoadFiles(clipboard);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,505 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<metadata name="Timer.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>30, 12</value>
|
||||
</metadata>
|
||||
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
AAABAAQAEBAAAAEAIABoBAAARgAAACAgAAABACAAqBAAAK4EAAAwMAAAAQAgAKglAABWFQAAAAAAAAEA
|
||||
IABKHQAA/joAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAQAAMMOAADDDgAAAAAAAAAAAAAAAAAAAAAAAP/c
|
||||
uQD/3LgH/968SP/ct6j/16rk/9Kf+//Sn/v/16rj/9y3qP/evEj/3LgH/9y5AAAAAAAAAAAA/9u1AP/c
|
||||
uQD/3bkY/9y3kv/Ole7/t1j//6Us//+eGv//nhr//6Us//+3WP//zpXu/9y3kv/duRj/3LkA/9u1AP/b
|
||||
tgD/3bkY/9qysP/AcP//nRf//5MA//+TAP//kgD//5IA//+SAP//kwD//50X///AcP//2rKw/925GP/b
|
||||
tgD/3LgG/9y3kv/AcP//lwr//5MA//+UAf//mxL//6Us//+mLv//nBb//5QB//+TAP//lwr//8Bw///c
|
||||
t5L/3LgG/968Sf/OlO3/nRj//5MA//+VBP//sEf//8+X///ZsP//2a///9Gc//+1U///lwj//5MA//+d
|
||||
GP//zpTt/968Sf/ct6f/tlj//5MA//+TAP//r0X//9mv///Xq///0Zz//9y3///cuP//2rP//7ZW//+U
|
||||
Af//kwD//7ZY///ct6f/16ri/6Us//+TAP//mg///82S///duv//zZH//6Ij//+9aP//16v//9y4///S
|
||||
n///nhn//5IA//+lLP//16rj/9Kf+/+eGv//kgD//6Ml///Xq///3Lj//82R//+YC///lAL//6gy///P
|
||||
lv//2rP//6k2//+SAP//nhr//9Kf+//Sn/v/nhr//5IA//+jJf//16v//9y4///Nkv//mAv//5YH//+v
|
||||
RP//0p7//9qz//+pNv//kgD//54a///Sn/v/16ri/6Us//+TAP//mg///82S///duv//zpP//6Yu///D
|
||||
d///2bH//9y4///Sn///nhn//5IA//+lLP//16ri/9y3p/+2WP//kwD//5MA//+vRf//2a///9iu///V
|
||||
pP//3Lf//9y3///as///tlb//5QB//+TAP//tlj//9y3p//evEn/zpTt/50Y//+TAP//lQT//7BH///P
|
||||
lv//2a///9mv///RnP//tVP//5cI//+TAP//nRj//86U7f/evEn/3LgG/9y3kf/AcP//lwr//5MA//+U
|
||||
Af//mxL//6Us//+mLv//nBX//5QB//+TAP//lwr//8Bw///ct5L/3LgG/9u2AP/duRj/2rKw/8Bw//+d
|
||||
F///kwD//5MA//+SAP//kgD//5IA//+TAP//nRf//8Bw///asrD/3bkY/9u2AP/btQD/3LkA/925GP/c
|
||||
t5L/zpXu/7dY//+lLP//nhr//54a//+lLP//t1j//86V7v/ct5L/3bkY/9y5AP/btQAAAAAAAAAAAP/c
|
||||
uQD/3LcH/968SP/ct6j/16rk/9Kf+//Sn/v/16rk/9y3qP/evEj/3LcH/9y5AAAAAAAAAAAA4AcAAMAD
|
||||
AACAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIABAADAAwAA4AcAACgA
|
||||
AAAgAAAAQAAAAAEAIAAAAAAAABAAAMMOAADDDgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAP/btQD/27UE/9u1Kf/btWz/27Ws/9u12f/btvH/3Lf9/9y3/f/btvH/27XY/9u1q//b
|
||||
tWz/27Up/9u1BP/btQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAP/btQD/27UD/9u1N//btZf/27bf/9y4+//ctv//2bD//9Wn///ToP//06D//9Wn///Z
|
||||
sP//3Lb//9y4+//btt//27WX/9u1N//btQP/27UAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAP/btQD/27UA/9u1Gf/btYn/27bq/9y3///WqP//xoD//7RT//+nMv//oCD//50X//+d
|
||||
F///oCD//6cy//+0U///xoD//9ao///ct///27bq/9u1if/btRn/27UA/9u1AAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAD/27UA/9u1AP/btTX/27XC/9y3/v/Wqf//vmv//6Mn//+WBv//kwD//5MA//+T
|
||||
AP//kwD//5MA//+TAP//kwD//5MA//+WBv//oyf//75r///Wqf//3Lf+/9u1wv/btTX/27UA/9u1AAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAA/9u1AP/btQD/27VB/9u12P/btv//y4z//6cw//+VA///kwD//5QA//+U
|
||||
AP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+TAP//lQP//6cw///LjP//27b//9u12P/b
|
||||
tUH/27UA/9u1AAAAAAAAAAAAAAAAAP/btQD/27UA/9u1Nv/btdj/27X//8N4//+cFf//kwD//5QA//+U
|
||||
AP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//kwD//5wV///D
|
||||
eP//27X//9u12P/btTb/27UA/9u1AAAAAAAAAAAA/9u1AP/btRr/27XB/9u2///DeP//mQ7//5MA//+U
|
||||
AP//lAD//5QA//+UAP//lAD//5MA//+TAP//kwD//5MA//+TAP//kwD//5QA//+UAP//lAD//5QA//+U
|
||||
AP//kwD//5kO///DeP//27b//9u1wf/btRr/27UAAAAAAP/btQD/27UC/9u1if/ct///y4z//5wV//+T
|
||||
AP//lAD//5QA//+UAP//lAD//5MA//+VBP//oB7//60///+1VP//tlf//7BG//+jJ///lwn//5MA//+U
|
||||
AP//lAD//5QA//+UAP//kwD//5wV///LjP//3Lf//9u1if/btQL/27UA/9u1AP/btTf/27bo/9ap//+n
|
||||
Mf//kwD//5QA//+UAP//lAD//5QA//+UAf//oyf//8F0///UpP//2rT//9y3///ct///27X//9eq///I
|
||||
hP//qzr//5UF//+UAP//lAD//5QA//+UAP//kwD//6cx///Wqf//27bp/9u1N//btQD/27UC/9u1l//c
|
||||
t///vmv//5UC//+UAP//lAD//5QA//+UAP//lQP//7BH///Uo///3Lj//9u2///btf//27X//9u1///b
|
||||
tf//27b//9y4///Yrv//u2L//5gL//+UAP//lAD//5QA//+UAP//lQL//75r///ct///27WX/9u1A//b
|
||||
tSr/27be/9ao//+jJ///kwD//5QA//+UAP//lAD//5QA//+vRf//2Kz//9y3///btf//27T//9y2///b
|
||||
tv//27X//9u1///btf//27X//9u2///btf//vGX//5YF//+UAP//lAD//5QA//+TAP//oyf//9ao///b
|
||||
tt7/27Uq/9u1bP/cuPv/xoD//5YG//+UAP//lAD//5QA//+TAP//oSL//9Og///ct///27X//9y3///M
|
||||
kP//wHD//9it///ct///27X//9u1///btf//27X//9u2///ZsP//rUH//5MA//+UAP//lAD//5QA//+W
|
||||
Bv//xoD//9y4+//btWz/27Wr/9y2//+0U///kwD//5QA//+UAP//lAD//5QB//++av//3Lj//9u1///b
|
||||
tf//3Lj//8V+//+XCP//qjj//8uN///btf//27b//9u1///btf//27X//9y4///Ljf//mQ3//5QA//+U
|
||||
AP//lAD//5MA//+0U///3Lb//9u1rP/btdj/2bD//6cy//+TAP//lAD//5QA//+TAP//nBb//9Gc///c
|
||||
t///27X//9u1///cuP//xn///5UD//+TAP//mxH//7hb///Vpf//3Lf//9u1///btf//27X//9mv//+o
|
||||
Mv//kwD//5QA//+UAP//kwD//6cy///ZsP//27XY/9u28f/Vp///oCD//5MA//+UAP//lAD//5MA//+n
|
||||
Mf//2a///9u1///btf//27X//9y4///Hgf//lgT//5QA//+UAP//lAH//6Qo///Ffv//2rH//9u2///b
|
||||
tf//3Lf//7ZW//+TAP//lAD//5QA//+TAP//oCD//9Wn///btvH/3Lf9/9Og//+dF///kwD//5QA//+U
|
||||
AP//kwD//65C///btf//27X//9u1///btf//3Lj//8eB//+WBP//lAD//5QA//+UAP//kwD//5cI//+z
|
||||
T///16v//9u2///cuP//vmr//5QA//+UAP//lAD//5MA//+dF///06D//9y3/f/ct/3/06D//50X//+T
|
||||
AP//lAD//5QA//+TAP//rkL//9u1///btf//27X//9u1///cuP//x4L//5YE//+UAP//lAD//5QA//+T
|
||||
AP//oB7//8Fy///ZsP//27X//9y4//++av//lAD//5QA//+UAP//kwD//50X///ToP//3Lf9/9u28f/V
|
||||
p///oCD//5MA//+UAP//lAD//5MA//+nMf//2a///9u1///btf//27X//9y4///Hg///lgX//5QA//+T
|
||||
AP//lwn//7FK///RnP//3Lf//9u1///btf//3Lf//7ZW//+TAP//lAD//5QA//+TAP//oCD//9Wn///b
|
||||
tvH/27XY/9mw//+nMv//kwD//5QA//+UAP//kwD//5wV///RnP//3Lf//9u1///btf//3Lj//8eD//+V
|
||||
Bf//lAH//6Mm///FfP//2rL//9y3///btf//27X//9u1///Zr///qDL//5MA//+UAP//lAD//5MA//+n
|
||||
Mv//2bD//9u12P/btav/3Lb//7RT//+TAP//lAD//5QA//+UAP//lAH//75q///cuP//27X//9u1///c
|
||||
uP//yIT//5sS//+1VP//1KL//9y3///btf//27X//9u1///btf//3Lj//8uN//+ZDf//lAD//5QA//+U
|
||||
AP//kwD//7RT///ctv//27Wr/9u1bP/cuPv/xoD//5YG//+UAP//lAD//5QA//+TAP//oSL//9Of///c
|
||||
t///27X//9y2///RnP//yYj//9u0///ctv//27X//9u1///btf//27X//9u2///ZsP//rUH//5MA//+U
|
||||
AP//lAD//5QA//+WBv//xoD//9y4+//btWz/27Uq/9u23v/WqP//oyf//5MA//+UAP//lAD//5QA//+U
|
||||
AP//r0T//9es///ct///27X//9u2///ct///27X//9u1///btf//27X//9u1///btv//27T//7xl//+W
|
||||
Bf//lAD//5QA//+UAP//kwD//6Mn///WqP//27be/9u1Kv/btQL/27WW/9y3//++a///lQL//5QA//+U
|
||||
AP//lAD//5QA//+VA///sEf//9Sj///cuP//27b//9u1///btf//27X//9u1///btv//3Lj//9iu//+7
|
||||
Yv//mAr//5QA//+UAP//lAD//5QA//+VAv//vmv//9y3///btZb/27UC/9u1AP/btTf/27bo/9ap//+n
|
||||
Mf//kwD//5QA//+UAP//lAD//5QA//+UAf//oyf//8F0///UpP//2rT//9y3///ct///27X//9eq///I
|
||||
hP//qzr//5UF//+UAP//lAD//5QA//+UAP//kwD//6cx///Wqf//27bp/9u1N//btQD/27UA/9u1Av/b
|
||||
tYj/3Lf//8uM//+cFf//kwD//5QA//+UAP//lAD//5QA//+TAP//lQT//6Ae//+tP///tVT//7ZX//+w
|
||||
Rv//oyf//5cJ//+TAP//lAD//5QA//+UAP//lAD//5MA//+cFf//y4z//9y3///btYn/27UC/9u1AAAA
|
||||
AAD/27UA/9u1Gv/btcH/27b//8N4//+ZDv//kwD//5QA//+UAP//lAD//5QA//+UAP//kwD//5MA//+T
|
||||
AP//kwD//5MA//+TAP//lAD//5QA//+UAP//lAD//5QA//+TAP//mQ7//8N4///btv//27XB/9u1Gv/b
|
||||
tQAAAAAAAAAAAP/btQD/27UA/9u1Nf/btdj/27X//8N4//+cFf//kwD//5QA//+UAP//lAD//5QA//+U
|
||||
AP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//kwD//5wV///DeP//27X//9u12P/b
|
||||
tTX/27UA/9u1AAAAAAAAAAAAAAAAAP/btQD/27UA/9u1P//btdj/27b//8uM//+nMf//lQP//5MA//+U
|
||||
AP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//kwD//5UD//+nMf//y4z//9u2///b
|
||||
tdj/27U//9u1AP/btQAAAAAAAAAAAAAAAAAAAAAAAAAAAP/btQD/27UA/9u1Nf/btcL/3Lf+/9ap//++
|
||||
a///oyf//5YG//+TAP//kwD//5MA//+TAP//kwD//5MA//+TAP//kwD//5YG//+jJ///vmv//9ap///c
|
||||
t/7/27XC/9u1Nf/btQD/27UAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/btQD/27UA/9u1Gf/b
|
||||
tYn/27bq/9y3///WqP//xoD//7RT//+nMv//oCD//50X//+dF///oCD//6cy//+0U///xoD//9ao///c
|
||||
t///27bq/9u1if/btRn/27UA/9u1AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAD/27UA/9u1A//btTf/27WX/9u23//cuPv/3Lb//9mw///Vp///06D//9Og///Vp///2bD//9y2///c
|
||||
uPv/27bf/9u1l//btTf/27UD/9u1AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAA/9u1AP/btQT/27Up/9u1bP/btaz/27XZ/9u28f/ct/3/3Lf9/9u28f/b
|
||||
tdn/27Ws/9u1bP/btSn/27UE/9u1AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/4AB//4A
|
||||
AH/8AAA/+AAAH/AAAA/gAAAHwAAAA4AAAAGAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAABgAAAAcAAAAPgAAAH8AAAD/gAAB/8AAA//gAAf/+A
|
||||
Af8oAAAAMAAAAGAAAAABACAAAAAAAAAkAADDDgAAww4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/27UA/9u1AP/btQ3/27U2/9u1bf/b
|
||||
taP/27XL/9u15f/btfX/27X+/9u1/v/btfT/27Xk/9u1y//btaH/27Vs/9u1Nv/btQ3/27UA/9u1AAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/9u1AP/btQP/27Un/9u1c//b
|
||||
tbz/27Xp/9u1/P/btf//27X//9u2///btv//3Lb//9y2///btv//27b//9u1///btf//27X8/9u16f/b
|
||||
tbz/27Vz/9u1J//btQP/27UAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/btQD/27UC/9u1Lf/b
|
||||
tZD/27Xh/9u1/v/btf//3Lb//9y4///ct///2rP//9es///UpP//06D//9Og///UpP//16z//9qz///c
|
||||
t///3Lj//9y2///btf//27X+/9u14f/btZD/27Ut/9u1Av/btQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/27UA/9u1AP/b
|
||||
tRX/27V8/9u14v/btf//27X//9y3///btP//06H//8Z+//+3Wf//qzz//6Qo//+fHf//nRb//50W//+f
|
||||
Hf//pCj//6s8//+3Wf//xn7//9Oh///btP//3Lf//9u1///btf//27Xi/9u1fP/btRX/27UA/9u1AAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/b
|
||||
tQD/27UA/9u1Ov/btb7/27X9/9u1///ct///2a///8mG//+xSv//nhv//5YF//+TAP//kwD//5MA//+T
|
||||
AP//kwD//5MA//+TAP//kwD//5MA//+TAP//lgX//54b//+xSv//yYb//9mv///ct///27X//9u1/f/b
|
||||
tb7/27U6/9u1AP/btQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAA/9u1AP/btQT/27Vc/9u14v/btf//3Lb//9q0///JiP//qzv//5gK//+TAP//kwD//5QA//+U
|
||||
AP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5MA//+TAP//mAr//6s7///J
|
||||
iP//2rT//9y2///btf//27Xi/9u1XP/btQT/27UAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAD/27UA/9u1Bf/btXD/27Xw/9u1///ct///1KP//7RT//+ZDv//kwD//5QA//+U
|
||||
AP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+U
|
||||
AP//lAD//5MA//+ZDv//tFP//9Sj///ct///27X//9u18P/btXD/27UF/9u1AAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/btQD/27UE/9u1cP/btfT/27X//9y3///Mjv//pSv//5QB//+U
|
||||
AP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+U
|
||||
AP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAH//6Ur///Mjv//3Lf//9u1///btfT/27Vw/9u1BP/b
|
||||
tQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/9u1AP/btQD/27Ve/9u18f/btf//27b//8eC//+e
|
||||
Gv//kwD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+U
|
||||
AP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5MA//+eGv//x4L//9u2///b
|
||||
tf//27Xx/9u1Xv/btQD/27UAAAAAAAAAAAAAAAAAAAAAAAAAAAD/27UA/9u1AP/btTv/27Xi/9u1///c
|
||||
t///x4L//5wV//+TAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+U
|
||||
AP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+T
|
||||
AP//nBX//8eC///ct///27X//9u14v/btTv/27UA/9u1AAAAAAAAAAAAAAAAAAAAAAD/27UA/9u1Fv/b
|
||||
tb7/27X//9y3///Mj///nhr//5MA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+U
|
||||
AP//kwD//5MA//+UAf//lQP//5UD//+UAf//kwD//5MA//+TAP//lAD//5QA//+UAP//lAD//5QA//+U
|
||||
AP//lAD//5QA//+UAP//kwD//54a///Mjv//3Lf//9u1///btb7/27UW/9u1AAAAAAAAAAAAAAAAAP/b
|
||||
tQD/27UA/9u1e//btf7/3Lb//9Sj//+lLP//kwD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+U
|
||||
AP//lAD//5MA//+YC///pSz//7RS//+/bf//xHz//8Z////BdP//uV7//6s8//+dF///lAL//5MA//+U
|
||||
AP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5MA//+lLP//1KP//9y2///btf7/27V8/9u1AP/b
|
||||
tQAAAAAAAAAAAP/btQD/27Ut/9u14P/btf//2rP//7RS//+UAP//lAD//5QA//+UAP//lAD//5QA//+U
|
||||
AP//lAD//5QA//+TAP//mQ7//7FL///Li///2K3//9y2///cuP//3Lj//9y4///cuP//3Lj//9qy///R
|
||||
nP//vGf//6Eh//+UAf//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//tFL//9qz///b
|
||||
tf//27Xh/9u1Lv/btQAAAAAA/9u1AP/btQL/27WR/9u1///ct///yYf//5kN//+UAP//lAD//5QA//+U
|
||||
AP//lAD//5QA//+UAP//lAD//5QB//+mLf//yYj//9u0///ct///27b//9u1///btf//27X//9u1///b
|
||||
tf//27X//9u1///ct///3Lf//9Og//+zUP//lwj//5MA//+UAP//lAD//5QA//+UAP//lAD//5QA//+U
|
||||
AP//mQ3//8mH///ct///27X//9u1kf/btQL/27UA/9u1AP/btSj/27Xh/9u1///Zr///qzv//5MA//+U
|
||||
AP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAL//65C///Uo///3Lj//9u1///btf//27X//9u1///b
|
||||
tf//27X//9u1///btf//27X//9u1///btf//27X//9y3///asv//v23//5kO//+TAP//lAD//5QA//+U
|
||||
AP//lAD//5QA//+UAP//kwD//6s7///Zr///27X//9u14f/btSj/27UA/9u1AP/btXL/27X//9y3///J
|
||||
h///mAr//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//rUD//9eq///ct///27X//9u1///b
|
||||
tf//27b//9u2///btf//27X//9u1///btf//27X//9u1///btf//27X//9u1///btv//27b//8Bw//+Y
|
||||
Cv//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5gK///Jhv//3Lf//9u1///btXL/27UA/9u1Df/b
|
||||
tbv/27X//9u0//+xSv//kwD//5QA//+UAP//lAD//5QA//+UAP//lAD//5MA//+jKP//06D//9y3///b
|
||||
tf//27X//9u1///btf//1qf//9it///ct///27X//9u1///btf//27X//9u1///btf//27X//9u1///b
|
||||
tf//27X//9q0//+2WP//lAH//5QA//+UAP//lAD//5QA//+UAP//lAD//5MA//+xSv//27T//9u1///b
|
||||
tbv/27UN/9u1Nv/bten/3Lb//9Oh//+eG///kwD//5QA//+UAP//lAD//5QA//+UAP//lAD//5gK///G
|
||||
f///3Lj//9u1///btf//27X//9u1///cuP//wHD//6s8///Nkf//27b//9u2///btf//27X//9u1///b
|
||||
tf//27X//9u1///btf//27X//9y2///Vpv//pCr//5MA//+UAP//lAD//5QA//+UAP//lAD//5MA//+e
|
||||
G///06H//9y2///bten/27U2/9u1bP/btfz/3Lj//8Z///+WBf//lAD//5QA//+UAP//lAD//5QA//+U
|
||||
AP//kwD//6w9///Zsf//27X//9u1///btf//27X//9u1///cuP//vmv//5MA//+cFP//umD//9Wn///c
|
||||
t///27X//9u1///btf//27X//9u1///btf//27X//9u1///cuP//wnT//5UE//+UAP//lAD//5QA//+U
|
||||
AP//lAD//5QA//+WBf//xn///9y4///btfz/27Vt/9u1of/btf//3Lf//7dZ//+TAP//lAD//5QA//+U
|
||||
AP//lAD//5QA//+UAP//lgX//8V8///cuP//27X//9u1///btf//27X//9u1///cuP//vmv//5QA//+T
|
||||
AP//lAL//6Ut///Hgv//2rP//9y3///btf//27X//9u1///btf//27X//9u1///btv//1ab//6Ej//+T
|
||||
AP//lAD//5QA//+UAP//lAD//5QA//+TAP//t1n//9y3///btf//27Wi/9u1yv/btf//2rP//6s8//+T
|
||||
AP//lAD//5QA//+UAP//lAD//5QA//+TAP//nx3//9Sj///btv//27X//9u1///btf//27X//9u1///c
|
||||
uP//vmz//5QA//+UAP//lAD//5MA//+YC///sk7//9Kd///ct///27b//9u1///btf//27X//9u1///b
|
||||
tf//27b//7NP//+TAP//lAD//5QA//+UAP//lAD//5QA//+TAP//qzz//9qz///btf//27XK/9u15P/b
|
||||
tv//16z//6Qo//+TAP//lAD//5QA//+UAP//lAD//5QA//+TAP//qzv//9qy///btf//27X//9u1///b
|
||||
tf//27X//9u1///cuP//v27//5QA//+UAP//lAD//5QA//+UAP//kwD//6Af///Acf//2K7//9y3///b
|
||||
tf//27X//9u1///btf//3Lj//8J1//+VAf//lAD//5QA//+UAP//lAD//5QA//+TAP//pCj//9es///b
|
||||
tv//27Xk/9u19f/btv//1KT//58c//+TAP//lAD//5QA//+UAP//lAD//5QA//+TAP//tVP//9y3///b
|
||||
tf//27X//9u1///btf//27X//9u1///cuP//v2///5QA//+UAP//lAD//5QA//+UAP//lAD//5MA//+W
|
||||
Bv//qzz//82Q///btP//27X//9u1///btf//3Lf//8uL//+XCf//lAD//5QA//+UAP//lAD//5QA//+T
|
||||
AP//nx3//9Sk///btv//27X1/9u1/v/ctv//06D//50W//+TAP//lAD//5QA//+UAP//lAD//5QA//+T
|
||||
AP//umH//9y4///btf//27X//9u1///btf//27X//9u1///cuP//v2///5QA//+UAP//lAD//5QA//+U
|
||||
AP//lAD//5QA//+UAP//kwD//5sS///BdP//27X//9u1///btf//3Lf//8+W//+aDv//lAD//5QA//+U
|
||||
AP//lAD//5QA//+TAP//nRb//9Og///ctv//27X+/9u1/v/ctv//06D//50W//+TAP//lAD//5QA//+U
|
||||
AP//lAD//5QA//+TAP//umH//9y4///btf//27X//9u1///btf//27X//9u1///cuP//wG///5QA//+U
|
||||
AP//lAD//5QA//+UAP//lAD//5QA//+TAP//lwj//69E///QmP//27X//9u1///btf//3Lf//8+W//+a
|
||||
Dv//lAD//5QA//+UAP//lAD//5QA//+TAP//nRb//9Og///ctv//27X+/9u19f/btv//1KT//58d//+T
|
||||
AP//lAD//5QA//+UAP//lAD//5QA//+TAP//tVP//9y3///btf//27X//9u1///btf//27X//9u1///c
|
||||
uP//wHL//5QA//+UAP//lAD//5QA//+UAP//lAD//5QB//+hIv//w3f//9mx///ct///27X//9u1///b
|
||||
tf//3Lf//8uL//+XCf//lAD//5QA//+UAP//lAD//5QA//+TAP//nx3//9Sk///btv//27X1/9u15P/b
|
||||
tv//16z//6Qo//+TAP//lAD//5QA//+UAP//lAD//5QA//+TAP//qzv//9qy///btf//27X//9u1///b
|
||||
tf//27X//9u1///cuP//wXL//5QA//+UAP//lAD//5QA//+TAP//mAv//7NP///Sn///3Lf//9u1///b
|
||||
tf//27X//9u1///btf//3Lj//8J1//+VAf//lAD//5QA//+UAP//lAD//5QA//+TAP//pCj//9es///b
|
||||
tv//27Xk/9u1yv/btf//2rP//6s8//+TAP//lAD//5QA//+UAP//lAD//5QA//+TAP//nxz//9Sj///b
|
||||
tv//27X//9u1///btf//27X//9u1///cuP//wXL//5QA//+UAP//lAD//5QB//+kKf//xoH//9qz///c
|
||||
t///27X//9u1///btf//27X//9u1///btf//27b//7NP//+TAP//lAD//5QA//+UAP//lAD//5QA//+T
|
||||
AP//qzz//9qz///btf//27XK/9u1of/btf//3Lf//7dZ//+TAP//lAD//5QA//+UAP//lAD//5QA//+U
|
||||
AP//lgX//8V8///cuP//27X//9u1///btf//27X//9u1///cuP//wXL//5QA//+TAP//mg///7dZ///V
|
||||
pf//3Lf//9u1///btf//27X//9u1///btf//27X//9u1///btv//1ab//6Ej//+TAP//lAD//5QA//+U
|
||||
AP//lAD//5QA//+TAP//t1n//9y3///btf//27Wh/9u1bP/btfz/3Lj//8Z///+WBf//lAD//5QA//+U
|
||||
AP//lAD//5QA//+UAP//kwD//6w9///Zsf//27X//9u1///btf//27X//9u1///cuP//wXX//5UE//+n
|
||||
Mv//yon//9u1///btv//27X//9u1///btf//27X//9u1///btf//27X//9u1///cuP//wnT//5UE//+U
|
||||
AP//lAD//5QA//+UAP//lAD//5QA//+WBf//xn///9y4///btfz/27Vs/9u1Nv/bten/3Lb//9Oh//+e
|
||||
G///kwD//5QA//+UAP//lAD//5QA//+UAP//lAD//5gK///Gf///3Lj//9u1///btf//27X//9u1///c
|
||||
t///yIX//7tk///Wqf//3Lf//9u1///btf//27X//9u1///btf//27X//9u1///btf//27X//9y2///V
|
||||
pv//pCr//5MA//+UAP//lAD//5QA//+UAP//lAD//5MA//+eG///06H//9y2///bten/27U2/9u1Df/b
|
||||
tbv/27X//9u0//+xSv//kwD//5QA//+UAP//lAD//5QA//+UAP//lAD//5MA//+jJ///06D//9y3///b
|
||||
tf//27X//9u1///btf//2rL//9u1///btv//27X//9u1///btf//27X//9u1///btf//27X//9u1///b
|
||||
tf//27X//9q0//+2V///lAH//5QA//+UAP//lAD//5QA//+UAP//lAD//5MA//+xSv//27T//9u1///b
|
||||
tbv/27UN/9u1AP/btXL/27X//9y3///Jh///mAr//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+U
|
||||
AP//rUD//9ap///ct///27X//9u1///btf//27X//9u1///btf//27X//9u1///btf//27X//9u1///b
|
||||
tf//27X//9u1///btv//27X//8Bv//+YCv//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5gK///J
|
||||
h///3Lf//9u1///btXL/27UA/9u1AP/btSf/27Xg/9u1///Zr///qzv//5MA//+UAP//lAD//5QA//+U
|
||||
AP//lAD//5QA//+UAP//lAL//65C///Uo///3Lj//9u1///btf//27X//9u1///btf//27X//9u1///b
|
||||
tf//27X//9u1///btf//27X//9y3///asv//vmz//5kO//+TAP//lAD//5QA//+UAP//lAD//5QA//+U
|
||||
AP//kwD//6s7///Zr///27X//9u14P/btSf/27UA/9u1AP/btQH/27WQ/9u1///ct///yYf//5kN//+U
|
||||
AP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QB//+mLf//yYj//9u0///ct///27b//9u1///b
|
||||
tf//27X//9u1///btf//27X//9u1///ct///3Lf//9Og//+zUP//lwj//5MA//+UAP//lAD//5QA//+U
|
||||
AP//lAD//5QA//+UAP//mQ3//8mH///ct///27X//9u1kP/btQH/27UAAAAAAP/btQD/27Ut/9u14P/b
|
||||
tf//2rP//7RS//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+TAP//mQ7//7FL///K
|
||||
i///2Kz//9y2///cuP//3Lj//9y4///cuP//3Lj//9qy///RnP//vGf//6Eh//+UAf//lAD//5QA//+U
|
||||
AP//lAD//5QA//+UAP//lAD//5QA//+UAP//tFL//9qz///btf//27Xh/9u1Lv/btQAAAAAAAAAAAP/b
|
||||
tQD/27UA/9u1e//btf3/3Lb//9Sj//+lLP//kwD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+U
|
||||
AP//lAD//5MA//+YC///pSz//7RS//+/bf//xHz//8Z////BdP//uV7//6s7//+dFv//lAL//5MA//+U
|
||||
AP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5MA//+lLP//1KP//9y2///btf3/27V8/9u1AP/b
|
||||
tQAAAAAAAAAAAAAAAAD/27UA/9u1Fv/btb3/27X//9y3///Mj///nhr//5MA//+UAP//lAD//5QA//+U
|
||||
AP//lAD//5QA//+UAP//lAD//5QA//+UAP//kwD//5MA//+UAf//lQP//5UD//+UAf//kwD//5MA//+T
|
||||
AP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//kwD//54a///Mjv//3Lf//9u1///b
|
||||
tb3/27UW/9u1AAAAAAAAAAAAAAAAAAAAAAD/27UA/9u1AP/btTv/27Xh/9u1///ct///x4L//5wV//+T
|
||||
AP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+U
|
||||
AP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+TAP//nBX//8eC///c
|
||||
t///27X//9u14f/btTv/27UA/9u1AAAAAAAAAAAAAAAAAAAAAAAAAAAA/9u1AP/btQD/27Vc/9u18P/b
|
||||
tf//27b//8eC//+eGv//kwD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+U
|
||||
AP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5MA//+e
|
||||
Gv//x4L//9u2///btf//27Xw/9u1XP/btQD/27UAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/b
|
||||
tQD/27UD/9u1b//btfL/27X//9y3///Mjv//pSv//5QB//+UAP//lAD//5QA//+UAP//lAD//5QA//+U
|
||||
AP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+U
|
||||
AP//lAH//6Ur///Mjv//3Lf//9u1///btfL/27Vv/9u1A//btQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAD/27UA/9u1Bf/btW7/27Xw/9u1///ct///1KP//7VT//+ZDv//kwD//5QA//+U
|
||||
AP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+U
|
||||
AP//lAD//5MA//+ZDv//tVP//9Sj///ct///27X//9u18P/btW7/27UF/9u1AAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/9u1AP/btQT/27Vc/9u14v/btf//3Lb//9u0///J
|
||||
iP//qzv//5gK//+TAP//kwD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+UAP//lAD//5QA//+U
|
||||
AP//lAD//5MA//+TAP//mAr//6s7///JiP//27T//9y2///btf//27Xi/9u1XP/btQT/27UAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/btQD/27UA/9u1Ov/b
|
||||
tb7/27X9/9u1///ct///2a///8mG//+xSv//nhv//5YF//+TAP//kwD//5MA//+TAP//kwD//5MA//+T
|
||||
AP//kwD//5MA//+TAP//lgX//54b//+xSv//yYb//9mv///ct///27X//9u1/f/btb7/27U6/9u1AP/b
|
||||
tQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAD/27UA/9u1AP/btRX/27V8/9u14v/btf//27X//9y3///btP//06H//8Z+//+3Wf//qzz//6Qo//+f
|
||||
HP//nRb//50W//+fHf//pCj//6s8//+3Wf//xn7//9Oh///btP//3Lf//9u1///btf//27Xi/9u1fP/b
|
||||
tRX/27UA/9u1AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/btQD/27UC/9u1Lf/btZD/27Xh/9u1/v/btf//3Lb//9y4///c
|
||||
t///2rP//9es///UpP//06D//9Og///UpP//16z//9qz///ct///3Lj//9y2///btf//27X+/9u14f/b
|
||||
tZD/27Ut/9u1Av/btQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/9u1AP/btQP/27Un/9u1c//b
|
||||
tbz/27Xp/9u1/P/btf//27X//9u2///btv//3Lb//9y2///btv//27b//9u1///btf//27X8/9u16f/b
|
||||
tbz/27Vz/9u1J//btQP/27UAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAD/27UA/9u1AP/btQ3/27U2/9u1bf/btaP/27XL/9u15f/btfX/27X+/9u1/v/btfX/27Xl/9u1y//b
|
||||
taP/27Vu/9u1Nv/btQ3/27UA/9u1AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAA//8AAP//AAD/+AAAH/8AAP/gAAAH/wAA/8AAAAP/AAD/gAAAAf8AAP4A
|
||||
AAAAfwAA/AAAAAA/AAD4AAAAAB8AAPgAAAAAHwAA8AAAAAAPAADgAAAAAAcAAOAAAAAABwAAwAAAAAAD
|
||||
AACAAAAAAAEAAIAAAAAAAQAAgAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAQAAgAAAAAABAACAAAAAAAEAAMAA
|
||||
AAAAAwAA4AAAAAAHAADgAAAAAAcAAPAAAAAADwAA+AAAAAAfAAD4AAAAAB8AAPwAAAAAPwAA/gAAAAB/
|
||||
AAD/gAAAAf8AAP/AAAAD/wAA/+AAAAf/AAD/+AAAH/8AAP//AAD//wAAiVBORw0KGgoAAAANSUhEUgAA
|
||||
AQAAAAEACAYAAABccqhmAAAdEUlEQVR42u2dbXBc1XnHf3ZsVi1UsiXjF2L8QmQsmZiYmSTIwYD41JkN
|
||||
ndrGMA0TmM6UlwKlxAQ6kDqddsJAM5A4mUyghEynJZR0kIP9wdGHdqYIbLIGJsXBgIxRwBgFW2DZkosn
|
||||
Mg64H85es1rtSrt7nnvPOfc+v5lMJAF3z717///zPM957rnTTp06hRI2vQNcAJxd/HUWcG2Ff+3qOg/b
|
||||
U+FvTwIjxZ8/yLfzmutzV+yYpgYQBkWRLwMuAxYW/1yvqOMiMotB4DngTTWHMFAD8JDeAbqBFUA3Ruyr
|
||||
XY+pQQoYU+gDXs+30+d6QMp41AA8oHeAtZiZvYtwxV4rBWAXJlJ4Pt/OB64HlGXUAByQMcFPxWlDyLez
|
||||
zfVgsoYaQAL0DnA2Jl/vxp+83Vd6MClDj0YH8aMGEBMlov86Oss3SgF4AjWD2FADEERFHytqBjGgBiBA
|
||||
7wBfAu5Gw/uk6AEezLfzkuuBhI4aQIOUzPb38um6vJIsg8ADaFTQMGoAdVKc7b8GbHQ9FmUcm4Gfa1RQ
|
||||
H2oANVIU/g/R3N53CsAdagS1oQYwBb0D3IoW9UKkADyRb+dh1wPxGTWAKhSFr/l9+AwCD6gRVEYNoIxi
|
||||
qP80Kvy0MQis19RgPGoARTTHzwxaIygh8wbQO8A5wBYCF/7oR/DOh+bnAx/CniOf/rPDY7B3tL7jrZk3
|
||||
/veVrbDoLPPz4rOg5QzXZ2xNAdiQb+c91wNxSWYNoCj8uwhsOe+VI+MFvnPI7Xgio4gM4sJWt+NpgM3A
|
||||
Q1k1gkwaQCgFvsIQvHrUzOCuhV4va+bBnCb4/GxYPc/+eDGT2UJhpgzA93C/MAR9BxsL2X2no8UYQvcC
|
||||
rw0hc2lBZgygOOv/2PU4SnmnGMo/8176BD8VHS1wxTkmdVh8luvRTOC2rEQDqTcA36r7+0bh2YOw4xAM
|
||||
n3A9Gj9oy8Gl8+HyBXB+i+vRnCYTqwWpNgBfZn0Vfe14aAapjgZSaQC+5PrbD2QzvJciShOuXOR6JOmt
|
||||
DaTOAIr77f0IRxX+aLbf9o7rK5Eu1i52HhUMArenbd/CVBlA7wBP4WhTjsIQbHlbZ/u46WiBDUudriT0
|
||||
5Nu5xvV1kCIVBlAM+V/Away//QA89Zbm9knTloNrznOWHgwCF6chJQjeAFyF/Cp8P3BoBKlICYI2ABdV
|
||||
fhW+nzg0gqBXCYI1gKTzfRV+GDgygmDrAsEZQNJLfPtG4dF+Le6FRkcL3NyZ6KpBkEuFQRlAksW+4TF4
|
||||
er8u54XO2sWwfgm0NSXyccEVB4MxgCSLfYUheKRfw/200JaDWzoTWzoMqjgYhAEUxb817s8ZHoP7d2u4
|
||||
n1Y6WuBbqxKLBtaFYALeG0BS4n9sr4b7WWHtYrixI5GP8t4EvDaAJMS/bxTue1nD/azRloNNFyVSJPTa
|
||||
BLw1gCTEr7O+klA04K0JeGkAvQNsBL4f1/E111dKSag2cGe+nc2uz7Uc7wwg7pm/MAT37XZ9loqPbFoV
|
||||
+0qBd5GAVwYQt/gf2B3e5ppKsqyZB/euivUjvDIBbwwgTvFryK/UQwIpgTcm4IUBxCl+rfIrjZDAKoEX
|
||||
JuDcAOIUv+b7ii0x1wWcm4BTA4izt3/7AdPOqyi23NIZ29OFzp8dcGYAcYpfi32KNDEWB52awHQXH1pk
|
||||
Cyp+JRB2Dpl7KwYWYrTgBCcGUNzMQ/x5fhW/EicxmsDqoiYSJ/EUII5tvIbH4Cd7VfxKMqyZBzd1xLJM
|
||||
mPj2YokaQBwV/+Ex2LhLl/mUZGnLweauWEwg0ZWBxAwgjqKfil9xSUwmkGhRMMkagHjF/yd7VfyKO4ZP
|
||||
mHtQmIUYrSRCIgZQLHCIil8LfooPxFQYXJhUUTD2FCCOvF/Fr/hGTH0CsdcDYjWAOPJ+Fb/iKzGYQOz1
|
||||
gLhTANFmn+0HVPyKv+wcMveoILE3CcVmAMX1frFmn2irbkXxmUf6zb0qyOqilmIhlhSgd4AvAS9KHW/f
|
||||
qFnuU5RQ2Nwl/ijxl/PtvCQ9zrgigB9KHWh4zDzPryghcd/L5t4VRExTpYgbgHTof/9uXetXwmP4hLl3
|
||||
BYklFRBNAYpV/99JHU+37VZCJ4aVgc9KrgrMED5fsYplYUjFb8vK2XDmTOheMPGfXTq/8n+z49DEv/Ud
|
||||
hOMnYc9R12cUHjuHzL0suKvQFuArUgcTiwAkG36Gx+D6Z6VOMf00z4QVs43Q5zRB56x4P69/BA6PwZ4j
|
||||
xjCOnXR9Bfzn8ctFnxkQe2pQ0gDeRWjN/5u7dAffySgVfOcsI3qXHB4zptB3EF4/qoZQiY4W+F6X2OHE
|
||||
GoREDKB3gO8DGyXOTPP+yjTPNGH7FefEP8Pb0j8Cz7yn0UE5wq8h25xv507bg1gbgGThT9f7J9I1FzYs
|
||||
9V/01YjM4Jfvuh6JHwj3B1gXBCUM4Cngaomzub5Pl/wAWnOwfgmsW+J6JLJs3Q/PHoQ3j7keiTvacvB4
|
||||
t9jhCvl2u4KglQFIdvxp6A/LmuGqpdUr9GmhfwQe7c+uEQinAlYdgrYG8CsEmn6yHvova4abO8MN8xsl
|
||||
y0YgmApYRQENG4Dk7J/V0L81Z95BlzXhl9M/YrrmjmToHhBOBRqOAmxagZ+WGPljGd3W64bl8LNuFT+Y
|
||||
a/CzbnNNssLwCXPvC9GwFhsygGJPsvWa//BY9vL+Zc3w75enr8Anwbol5tp0zXU9kmTY9o7YA0MLG31O
|
||||
oNEI4F6JUcewoaK3tObgni/AD1a7b9zxmTlN8O2L4KGLzTVLO4IaaEiTdRuA1Oy/bzQ7u/t0zTVFn7RX
|
||||
9yXpnGWuWdqjgZ1DRgsCNBQFNBIBfF1itI9mZHefG5abGU1n/fqJooG01wYEtVC3NusygGLl33rZb/uB
|
||||
9Pf6t+ZMGKu5vj3rlqQ7Jdg7KraX4OqiRmum3ghAZFeSp94SOVlviUJ+rfDLkfaUQFATdWm0ZgOQnP3T
|
||||
vOzXNVdD/riIUoI0msDwCTdRQD0RwNckRpfm2T8SvxIvaTUBQW3UrNWaDKB3gLMReNw3zbP/V89V8SfJ
|
||||
ty8y1zxNCEYBG4uanZJaIwCRp/3SOvvf8wW4dYXrUWSPW1eYa58mBDVSk2ZrNQDrxp+0zv73fEHX911y
|
||||
6fx0mYBgFFCTZqc0gGJBwbrxJ42z/w3LVfw+cOn8dPUKCGllYS3FwFoigLttR1IYSt/s3zVX1/h9Yt2S
|
||||
9BQGh0+IvV5sSu3WYgDW+f+Wt0VOxhu02u8naVodENLMlNqd1AAk3kSybzRdXX8qfr9JiwnsHZV5RmAq
|
||||
DU8VAVj3/T97UPS6OKU1B7d0uh6FMhW3dKajbVhIO5NquKoBFNcRrTv/0vS8/7dWaYdfCMxpMt9V6Ahp
|
||||
Z/VkPQGTRQDWub/QcoYX3LBce/tDonNWOlYGhDRUVcuTGYB1+P+M2CsM3bKsWSv+IZKGlQEhDVXVckUD
|
||||
kAj/01L8a83BJi36BUvo9QChYmDVNKBaBGAd/qel+HdTh595/0cfux5BGMxpMt9hyAhpqaKmqxlAt+2n
|
||||
VXrNdGgsa/a30++7r8B/i7yQLf1cOj/sVEBIS92V/hhLBLBvNB2dfz6H/sdPwg9ehXtehKHfux6N/4S8
|
||||
fDt8QiQNqC0C6B1gre0npSH8v2G5n6F/OXuOws074Rdvw8efuB6Nv8xpCntVQEJTlbRdKQK4zPaDQg//
|
||||
W3NhVf1PfgL/ug/ufAF+m8HXbNXKuiXhFgSFNDVB25UMoMvmE975MPzwP9QmkoFj8I1d8G/7tEhYjVC/
|
||||
2+ETRluWTNB2JQOwWv7bcyS5ixIHy5rDbvj55BT0vA23F+CVwL+LOOicZb7jEBHQ1gRtjzMAifw/9Oaf
|
||||
mwMuFpUyeBzufQke6YcPT7oejV+E+h1LaKtc4+URgHX+H3LzT+izfyW2H4Bbn4cX33c9En8INQoQ0tY4
|
||||
jZcbgFX+L7SJgTOuWup6BPEwfAL+6WXzCu7Rj1yPxg9C/a4FNDZO4+UGYJX/9wW8/Nea87fpR4rnh+DG
|
||||
HdpABOa7DnFFQEBj4zR+2gB6B7jA9siHZV517IT1S1yPoD5+32CV//gfTAPR37+kDUShfecgo7FSrZdG
|
||||
AMtsDxxy/h/Suj/AMctQfvcRUxvIcgNRaN85iGnstNZLDeBamyOGnP+H3Cduw9jHpoHo7hez20AU4ncv
|
||||
oLXTWi81AKutv1896u6C2LIh0IKQFG+Mmgain72ZvQaiEL97Aa2d1nqpAVgVAEPN/5tnpm/prxE+OQX/
|
||||
+ZZpIHotYDOvl85Z5h4ICQGtndb6dDi9AYgVOwNNAdJe+a+XwePwdy9mq4EotHtAQmuR5qMI4BLXJ+WK
|
||||
K85xPQI/yVID0TXnuR6BEy6BTw3AqgMw1J5zDf8nJysNRHOawksDBDR3GXxqAFYFwAP2Tyk5YcVs1yMI
|
||||
gyw0EIV2LwhobiHU/nbgSQn1CcDuBa5HEA5RA9E//DqdDUSh3QtSmosMwHoT0BDR8L9+fn3Y1Aa27U9X
|
||||
A1EG74WrQSgCCHEFoHlmGFt++cjYx/DYG6aBaP//uR6NDKHVAaQ0N11iCTBEQsv5fOSNUdM38B8D6Wgg
|
||||
yto90TvA2dPB7iGgUKvDoeV8vvLJKXjyt8YI9o64Ho0dod0TAtq7wDoFENinzAka/ssyeBy++YJpIPr9
|
||||
H1yPpjFCuycktDcdmOX6RFyQwaJPImw/YLYpD7GBKIP3xKzpWD4FGGoPgBIfUQPRd38TbooYAgLau9Y6
|
||||
BQixB2Blxoo9rnjuEPz1zrAaiEK6NyS0J7IMGBpnBrTcEzrHTobVQJS1eyOTBhBatTcNhNJAlLV7I5MG
|
||||
oLghjQ1EoTMdyzbgELsAFbeUNhD5HA34joD2rtYIIFCOBb5ZR9RAdOuvwm8gCplMGkBoDR+VGEtB6y2Y
|
||||
BqK7X/SngSgN90Y9ZNIAMtjw4TWfnPJnB6Ks3RuZNADFT94fMw1ED72iDURJoQageMczB00D0f8E/qbp
|
||||
EFADULzk2En43h74x/8No4EoVNQAFK/59WH4r0HXo0gvM1wPQFGq0d4Mf7MClrW4Hkl6yaQB9I9kr9ob
|
||||
Ek2fgeva4c8WwWcSjlH7R1yffbJk0gBCfY1ZFuiaC7d0uluPz9q9kUkDUPyjLWeEv3qe65Fki+lAj80B
|
||||
OjQ/UyyYPg3+fDE8ukbFXy9r7K9Xj3UEMKcJGHV9KZQQWd4Ct62AzzW7Hkl2yWQK0HcwvDfCpokzZ5gi
|
||||
X/7c5It8U9F30PUIkiWTBnA88CfpQuaSeXBTh78P3WTt3rA2gJWt4e0JsOeo6xFkj7lNpsj35bmuRzI5
|
||||
Id0bK1vtjzEDeBKLTUEWneX6Mig+M30arF0M134O/iiT8WZ8CGjvyRnAiOsTcYE2A8VPaEW+rDUBASPW
|
||||
nrw40Aggaw0fSeJzkW8yQrsnJLQ3A3jN5gAtZ7i+DI2hKwHx4HuRbzJCWwEQ0N5rM/LtfNA74PpUkuf1
|
||||
gIo9IRBKkW8ysnZP5Nv5QCRAE+hISpxjJ8ML+Xxk+jRYvwQeviRs8R8eC2ujVSnNRQZg1Q4cKqEWfXwx
|
||||
ruUt8KPV8FfLw6/wh3ovWNADQhuCSKxHuiC0nC/i41NuP//MGaa6//0uWPInrq+GDKHdC1Kai3zbas+V
|
||||
UHsBspbzSXDZfLixA1pzrkciS2j3goDmBuFTA3gO2NjokS4MNAKI6gAhVqyTZm6TmfW/eLbrkcgTWv4P
|
||||
Ipp7Dj5NAZ53fUKueOot1yPwm+nT4Oql5nHdNIofMnsPPA9FA8i384Ht0UJcCQDYccj1CPwlKvL95flw
|
||||
xmdcjyY+QrsHJLQWab60dlsAVjd6wFDD6GMntS24nDNnGNHnz3U9kvjpHwkv/BfQWiH6oXQVwKoQ+PnZ
|
||||
7i6ILVvedj0Cf7hsPvzLmmyIH8L87gW0dlrrpRGA1VOBIW/ntMvx++h8IM1FvskI8bsX0Fpf9ENpBPCm
|
||||
7VFD3h9w637XI3BDFop81QjxOxfS2OvRD6cNIN9u91AQhFsHAHh6v+sRJE9WinzVCPE7l9BYvr1yBAAl
|
||||
xYFG6F7g4pLIcOREeNXgRjlzBvztBenq5KuXHYfMdx4aAhobp/FyA9hlc+SQ6wAAvwiwIFQvVyyAxy6F
|
||||
P13oeiRuCfW7FtDYOI2XG8BztkcPuQ7w5rH0PhSy4I/hvi/CXReGu4eDFP0j5rsODSFtjdP4OAPIt7PN
|
||||
9uhXnJPkJZHn0X7XI5Bl+jT4i/Pg4a/ARW2uR+MHoX7HEtoq13ilpwGt6gChPhkYkaYoYMUsI/zrlmWz
|
||||
yFeJUGd/ENHWBG1XMgCrOsDis8x73kLm/t2uR2BHVOR78GI4N9AnNeMi1O+2LSeyB+AEbVcyAOs6QOh7
|
||||
7R05EeYaMWiRbzK27g+z8g9impqg7QkGIFEHuDzg5cCIn77hz847taBFvsk5PGa+01CR0FQlbVfbEchq
|
||||
i7DzW8JPAwAeCaBYpEW+2gjhu6xGW85oypKKmq5mAH22nxZ6GgCmT9zn5iAt8tVG/0iYPf8RQlrqq/TH
|
||||
WCIASEcaAPCTvf6lAjOna5GvVg6PhVv4ixDSUu0RQHGzAKvlwPNbwm4Kijhywr/wsTWnRb5aeaQ/3MIf
|
||||
GA0JhP+Fapv+TLYr8BO2nxp6U1DErvfDXRXIMlv3hx36g5iGqmp5MgOwTgOuXCR/QVzx0zfS0yCUBfpH
|
||||
wq76RwhpqKqWqxqARBoA5tXQaeH+3f7VA5SJpCHvB7F9NguT7fk51YtBrNOAtBQDwc96gDKR0PP+iKuW
|
||||
ihxmUg1PagD5dh62/fS0FAMjdr0P33nZ9SiUanzn5fDzfhAr/sEUqXwtrwazrgVskHEyb1AT8JO0iB/E
|
||||
NNMz1Zb/tRjAg7ajWD0vHZ2BpfjeJJQ1dhxKj/jbcmKb60yp3SkNIN/OS1huGQ5wzXkiJ+QV//wbNQEf
|
||||
2HHIfBdpQUgrg0XtTkqtbwd+wHY0Vy5KXxQAagKuSZv423JiS381abZWA7CuA0A6owAwN6A2CiXP1v3p
|
||||
Ej+IaqQmzdZkAMVCwmbbEaU1CgDTdKKFweT4zsvpaPQpRXD2n7L4F1FrBADwc4mRpTUKAF0dSIo0VftL
|
||||
EdRGzYX7mg2gWFCw7gxMcxQAn5qAdgzKc3gsveIXnP0LtRT/IuqJAADukBhhmqMAMDfoxl367IAk/SPm
|
||||
mqZR/CCqibo0Ou3UqVN1Hb13gHcB64dRv7kL9o6KnbS33LAc1i1xPYqw2bo/ffl+KW05eLxb5FCD+Xbq
|
||||
eq9zvREACCwJAtzcKXLC3hMVBzUlqJ8o5E+z+AE2XSR2qLq1WXcEAHJRwAO7YeeQ2Ml7TWsObupIx1Zp
|
||||
SdA/Yp7oS8NDPZPR0QLf6xI5VN2zPzQWAYBQFHBTh8iJB8GRE2bN+hsFjQYmI5r173oh/eIH+NYqsUM1
|
||||
pMmGIgCQiwIe2wvb3hG7CMGgtYGJpD3XL2ftYrhRZhJsaPaHxiMAgPUSI7+xI93LgtX46RtwXZ+uFIC5
|
||||
Btf1ZUv8bTkx8YOFFhuOAAB6B/gVsNp29PtGzRJPVlnWbIqinbNcjyRZ+kfMizpDfVefDZu7xJ73L+Tb
|
||||
+Uqj//EMyw+/A3jR9gzObzHhUBZTATACuOsFYwRXLU1/oTDLwgdzrwuJHyx7c6wiAIDeAZ4CrpY4k+v7
|
||||
YDgDhZ+paM3B+iXpqxFs3Q/PHsyu8EF0zR8sZ3+QMYBzgN9JnE3WU4FKfPVcszV0qOlB/wg88x788l3X
|
||||
I/EDwdAf4LP5dt6zOYC1AQD0DvB9YKPEGWV1VWAqmmea1OCa82BOk+vRTM7hMfOc/tP7s7GUVyuCVX+A
|
||||
zfl27rQ9iIgBgNyyIGSnTbhRmmfCitnQvcBEBq4N4fCYmen7DsLrR+HYSddXyD8EG37A7NB1se3sD7IG
|
||||
sBbYKnGs4TG4/lmRYWWCUkOY0xR/utA/YkS/54j534Hjrq+A/zx+ObTJGfVtEjt2g6ABgNyyIEBhCO7b
|
||||
LTa0TLJyNpw50xhDOdVWGiptb9Z3EI6fhD1HXZ9RmGxaJbbJJwgU/kqRNgCxgiBoPUAJnzXz4N5Vooe0
|
||||
LvyVYtMJOIHiwG6TOt6NHel6qYiSLTpaxMV/m6T4QTgCiJAsCA6PmaVB7Q9QQqItZ5b8BPP+hvv9J0M0
|
||||
AihB5DkBMBdQ8HlpRUmETReJih8ENVVKLAZQ3JNMLBU4v8UUUhQlBDatEm32ARP617zPXz3EkgJESK4K
|
||||
AGw/oG/nVfzmlk6xzT0jRKv+5cSVAkRsQOC1YhFXLhJ7Z7qiiLNmnrj4BzEaio1YDaBYsbxd8pj3rlIT
|
||||
UPwjhuU+gNulq/7lxB0BkG9nG0KvFotQE1B8Iibx9xS1Eyux1gBKkVwajMjSpqKKn8Qk/liW/CoRewRQ
|
||||
wsUI1gPAbCqaxe3EFD9oy8Wyse0gRiuJkJgBxFEPaGsqNluoCSgJE0OjT0TseX8pSUYAUT3A+i3DpUQm
|
||||
oDUBJSnWzItN/JuTyPtLSawGUIrkNmKlaE1AiZuYcn4wRb9rkj4fJwYA8RQFQU1AiY8YxZ9Y0a+cRFOA
|
||||
MsSLgqBLhEo8xCl+Eiz6leMsAgD5/QNK0bZhRYoY2ntLEX2+v15cRgDRysC6OI595SJ9gEixZ9OqWMW/
|
||||
zqX4wXEEECG5n2A5+0bhvpd1PwGlPtpy5pFe4af6SlmXdMW/El4YAMRrAsNj5lXTutOwUgsdLeatvTEs
|
||||
80V4IX7wyAAgXhMAXSFQpibGYl+EN+IHzwwAoHeAW4Efx3V83W1YqYbw7r2VENvOWwrvDADiaxSK0H0G
|
||||
lVJibOstxUmjz1R4aQAQfyQAuu24Iv66rmp4N/NHeGsAEH9NAHSVIKskUOWP8CrnL8drA4BkTAA0GsgS
|
||||
Cc364Ln4IQADgORMYN8oPNqvy4VppaMFbu5MZNaHAMQPgRgAnDaBHxHDA0TlbD8AT72laUFaaMuZ16rH
|
||||
2NFXyiDmmf5trs+7FoIxADj97MALJGACw2Pm/faaFoTN2sWwfknsFf4Isdd2J0VQBgCnTWALgu8bmAxN
|
||||
C8Ik4XAfoABsCEn8EKABRMTdK1COpgVhkHC4H+HlGn8tBGsAkEyvQDlqBH7iSPjg8Rp/LQRtAJBscbAU
|
||||
NQI/cCj8oIp91QjeACDZ4mA5agRucCh8CLDYV41UGEBE0nWBUgpDsOVtLRbGTUcLbFga+0M7kxFsvl+J
|
||||
VBkAuEsJIvaNwrMHdflQmrWL4fIFiVb1y0lFyF9O6gwAkl8qrMb2A/DMexoVNEpHC1xxjrMwv5Qgl/hq
|
||||
IZUGEOFilaASUVSw45DWCqaiLQeXznc+25cSdJV/KlJtAAC9A3wJ+CGOo4EINYOJeCh6MLP+Hfl2XnI9
|
||||
kDhJvQFE+BINlPLOh7DnSDbThCi8X9kKi89yPZoJpHrWLyUzBgD+1AaqURiCvoNweCx9htDRAnOaoHuB
|
||||
0wr+VKQ2169GpgwgohgN3IujlYJaKQzBq0eNIYS2memaeUbwn5/tteAjBoEHsjLrl5JJA4DT0cBdwEbX
|
||||
Y6mHV47AgWLqAO6NIXoN28pWWHQWXNjqdjwNsBl4KEuzfimZNYAI39OCWhn9yNQUYLxBRNRrFOXvV4wE
|
||||
DiZnbznD9Rlbk7lwvxKZN4AI31YLlNjIRHW/VtQAyigawdN4Xh9Q6mYQWK/CH48aQBVCKRQqU5LZAl8t
|
||||
qAFMQdEIvo6mBqFRAJ5Q4U+OGkCNaI0gGDTHrwM1gDopGsHXCGz5MANsBn6uwq8PNYAG6R3gbMzeA1on
|
||||
cMcg8ADmGf0PXA8mRNQABChGBXfjaDOSDNIDPKizvT1qAIKURAVaNJSnADyBzvaiqAHEhJqBCCr6mFED
|
||||
SIASM+hG04Sp6AH6UNEnghqAA4r7Fl4GdKHRQQHYBTyXtv32QkANwAMyZggqeI9QA/CQ3gG6gRWYlGEh
|
||||
4ZpCAbNU9yTwZr6d11wPSBmPGkAg9A5wAbAMEylEfQe+1BN6iv8/CDwHPK/5exioAaSAojmcXfx1FnBt
|
||||
hX+tXrPoKfs9EvdI8ffXVOTh8//e05wCkY3eQAAAAABJRU5ErkJggg==
|
||||
</value>
|
||||
</data>
|
||||
</root>
|
||||
149
mpv.net/Misc/App.cs
Normal file
@@ -0,0 +1,149 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Windows.Forms;
|
||||
using UI;
|
||||
|
||||
namespace mpvnet
|
||||
{
|
||||
public static class App
|
||||
{
|
||||
public static string[] VideoTypes { get; } = "264 265 asf avc avi avs flv h264 h265 hevc m2ts m2v m4v mkv mov mp4 mpeg mpg mpv mts ts vob vpy webm wmv y4m".Split(' ');
|
||||
public static string[] AudioTypes { get; } = "mp3 mp2 ac3 ogg opus flac wav w64 m4a dts dtsma dtshr dtshd eac3 thd thd+ac3 mka aac mpa".Split(' ');
|
||||
public static string[] ImageTypes { get; } = {"jpg", "bmp", "gif", "png"};
|
||||
public static string[] SubtitleTypes { get; } = { "srt", "ass", "idx", "sup", "ttxt", "ssa", "smi" };
|
||||
|
||||
public static string RegPath { get; } = @"HKCU\Software\" + Application.ProductName;
|
||||
public static string ConfPath { get => mp.ConfigFolder + "mpvnet.conf"; }
|
||||
public static string ProcessInstance { get; set; } = "single";
|
||||
public static string DarkMode { get; set; } = "always";
|
||||
public static string DarkTheme { get; set; } = "dark";
|
||||
public static string LightTheme { get; set; } = "light";
|
||||
|
||||
public static bool RememberHeight { get; set; } = true;
|
||||
public static bool RememberPosition { get; set; }
|
||||
public static bool Maximized { get; set; }
|
||||
public static bool DebugMode { get; set; }
|
||||
public static bool IsStartedFromTerminal { get; } = Environment.GetEnvironmentVariable("_started_from_console") == "yes";
|
||||
public static bool RememberVolume { get; set; } = true;
|
||||
public static bool AutoLoadFolder { get; set; } = true;
|
||||
public static bool Queue { get; set; }
|
||||
public static bool UpdateCheck { get; set; }
|
||||
|
||||
public static int StartThreshold { get; set; } = 1500;
|
||||
public static int RecentCount { get; set; } = 15;
|
||||
|
||||
public static float MinimumAspectRatio { get; set; } = 1.3f;
|
||||
|
||||
public static Extension Extension { get; set; }
|
||||
|
||||
public static bool IsDarkMode {
|
||||
get => (DarkMode == "system" && Sys.IsDarkTheme) || DarkMode == "always";
|
||||
}
|
||||
|
||||
public static void Init()
|
||||
{
|
||||
string dummy = mp.ConfigFolder;
|
||||
var dummy2 = mp.Conf;
|
||||
|
||||
foreach (var i in Conf)
|
||||
ProcessProperty(i.Key, i.Value, true);
|
||||
|
||||
if (App.DebugMode)
|
||||
{
|
||||
try
|
||||
{
|
||||
string filePath = mp.ConfigFolder + "mpvnet-debug.log";
|
||||
|
||||
if (File.Exists(filePath))
|
||||
File.Delete(filePath);
|
||||
|
||||
Trace.Listeners.Add(new TextWriterTraceListener(filePath));
|
||||
Trace.AutoFlush = true;
|
||||
|
||||
//if (App.DebugMode)
|
||||
// Trace.WriteLine("");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Msg.ShowException(e);
|
||||
}
|
||||
}
|
||||
|
||||
string themeContent = null;
|
||||
|
||||
if (File.Exists(mp.ConfigFolder + "theme.conf"))
|
||||
themeContent = File.ReadAllText(mp.ConfigFolder + "theme.conf");
|
||||
|
||||
Theme.Init(
|
||||
themeContent,
|
||||
Properties.Resources.theme,
|
||||
IsDarkMode ? DarkTheme : LightTheme);
|
||||
|
||||
mp.Shutdown += Shutdown;
|
||||
mp.Initialized += Initialized;
|
||||
}
|
||||
|
||||
private static void Initialized()
|
||||
{
|
||||
if (RememberVolume)
|
||||
{
|
||||
mp.set_property_int("volume", RegistryHelp.GetInt(App.RegPath, "Volume", 70));
|
||||
mp.set_property_string("mute", RegistryHelp.GetString(App.RegPath, "Mute", "no"));
|
||||
}
|
||||
}
|
||||
|
||||
private static void Shutdown()
|
||||
{
|
||||
if (RememberVolume)
|
||||
{
|
||||
RegistryHelp.SetValue(App.RegPath, "Volume", mp.get_property_int("volume"));
|
||||
RegistryHelp.SetValue(App.RegPath, "Mute", mp.get_property_string("mute"));
|
||||
}
|
||||
}
|
||||
|
||||
static Dictionary<string, string> _Conf;
|
||||
|
||||
public static Dictionary<string, string> Conf {
|
||||
get {
|
||||
if (_Conf == null)
|
||||
{
|
||||
_Conf = new Dictionary<string, string>();
|
||||
|
||||
if (File.Exists(ConfPath))
|
||||
foreach (string i in File.ReadAllLines(ConfPath))
|
||||
if (i.Contains("=") && !i.StartsWith("#"))
|
||||
_Conf[i.Substring(0, i.IndexOf("=")).Trim()] = i.Substring(i.IndexOf("=") + 1).Trim();
|
||||
}
|
||||
return _Conf;
|
||||
}
|
||||
}
|
||||
|
||||
public static bool ProcessProperty(string name, string value, bool writeError = false)
|
||||
{
|
||||
switch (name)
|
||||
{
|
||||
case "remember-position": RememberPosition = value == "yes"; return true;
|
||||
case "maximized": Maximized = value == "yes"; return true;
|
||||
case "debug-mode": DebugMode = value == "yes"; return true;
|
||||
case "remember-volume": RememberVolume = value == "yes"; return true;
|
||||
case "queue": Queue = value == "yes"; return true;
|
||||
case "auto-load-folder": AutoLoadFolder = value == "yes"; return true;
|
||||
case "update-check": UpdateCheck = value == "yes"; return true;
|
||||
case "start-size": RememberHeight = value == "previous"; return true;
|
||||
case "process-instance": ProcessInstance = value; return true;
|
||||
case "dark-mode": DarkMode = value; return true;
|
||||
case "start-threshold": StartThreshold = value.Int(); return true;
|
||||
case "recent-count": RecentCount = value.Int(); return true;
|
||||
case "minimum-aspect-ratio": MinimumAspectRatio = value.Float(); return true;
|
||||
case "dark-theme": DarkTheme = value.Trim('\'', '"'); return true;
|
||||
case "light-theme": LightTheme = value.Trim('\'', '"'); return true;
|
||||
default:
|
||||
if (writeError)
|
||||
ConsoleHelp.WriteError($"unknown mpvnet.conf property: {name}");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
275
mpv.net/Misc/Command.cs
Normal file
@@ -0,0 +1,275 @@
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Windows;
|
||||
using System.Windows.Forms;
|
||||
using System.Windows.Interop;
|
||||
|
||||
using VB = Microsoft.VisualBasic;
|
||||
|
||||
namespace mpvnet
|
||||
{
|
||||
public class Command
|
||||
{
|
||||
public static void Execute(string id, string[] args)
|
||||
{
|
||||
switch (id)
|
||||
{
|
||||
case "open-files": OpenFiles(args); break;
|
||||
case "update-check": UpdateCheck.CheckOnline(true); break;
|
||||
case "open-url": OpenURL(); break;
|
||||
case "open-optical-media": Open_DVD_Or_BD_Folder(); break;
|
||||
case "manage-file-associations": // deprecated 2019
|
||||
case "show-setup-dialog": ShowDialog(typeof(SetupWindow)); break;
|
||||
case "cycle-audio": CycleAudio(); break;
|
||||
case "load-audio": LoadAudio(); break;
|
||||
case "load-sub": LoadSubtitle(); break;
|
||||
case "execute-mpv-command": ExecuteMpvCommand(); break;
|
||||
case "show-history": ShowHistory(); break;
|
||||
case "show-media-search": ShowDialog(typeof(EverythingWindow)); break;
|
||||
case "show-command-palette": ShowDialog(typeof(CommandPaletteWindow)); break;
|
||||
case "show-about": ShowDialog(typeof(AboutWindow)); break;
|
||||
case "show-conf-editor": ShowDialog(typeof(ConfWindow)); break;
|
||||
case "show-input-editor": ShowDialog(typeof(InputWindow)); break;
|
||||
case "open-conf-folder": Process.Start(mp.ConfigFolder); break;
|
||||
case "shell-execute": Process.Start(args[0]); break;
|
||||
case "show-info": ShowInfo(); break;
|
||||
case "playlist-last": PlaylistLast(); break;
|
||||
case "add-files-to-playlist": OpenFiles("append"); break; // deprecated 2019
|
||||
default: Msg.ShowError($"No command '{id}' found."); break;
|
||||
}
|
||||
|
||||
MainForm.Instance.BeginInvoke(new Action(() => {
|
||||
Message m = new Message() { Msg = 0x0202 }; // WM_LBUTTONUP
|
||||
Native.SendMessage(MainForm.Instance.Handle, m.Msg, m.WParam, m.LParam);
|
||||
}));
|
||||
}
|
||||
|
||||
public static void InvokeOnMainThread(Action action) => MainForm.Instance.Invoke(action);
|
||||
|
||||
public static void ShowDialog(Type winType)
|
||||
{
|
||||
InvokeOnMainThread(new Action(() => {
|
||||
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);
|
||||
bool loadFolder = true;
|
||||
|
||||
foreach (string arg in args)
|
||||
{
|
||||
if (arg == "append") append = true;
|
||||
if (arg == "no-folder") loadFolder = false;
|
||||
}
|
||||
|
||||
InvokeOnMainThread(new Action(() => {
|
||||
using (var d = new OpenFileDialog() { Multiselect = true })
|
||||
if (d.ShowDialog() == DialogResult.OK)
|
||||
mp.Load(d.FileNames, loadFolder, append);
|
||||
}));
|
||||
}
|
||||
|
||||
public static void Open_DVD_Or_BD_Folder()
|
||||
{
|
||||
InvokeOnMainThread(new Action(() => {
|
||||
using (var d = new FolderBrowserDialog())
|
||||
{
|
||||
d.Description = "Select a DVD or Blu-ray folder.";
|
||||
d.ShowNewFolderButton = false;
|
||||
|
||||
if (d.ShowDialog() == DialogResult.OK)
|
||||
{
|
||||
if (Directory.Exists(d.SelectedPath + "\\BDMV"))
|
||||
{
|
||||
mp.set_property_string("bluray-device", d.SelectedPath);
|
||||
mp.Load(new[] { @"bd://" }, false, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
mp.set_property_string("dvd-device", d.SelectedPath);
|
||||
mp.Load(new[] { @"dvd://" }, false, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
public static void PlaylistLast() => mp.set_property_int("playlist-pos", mp.get_property_int("playlist-count") - 1);
|
||||
|
||||
public static void ShowHistory()
|
||||
{
|
||||
if (File.Exists(mp.ConfigFolder + "history.txt"))
|
||||
Process.Start(mp.ConfigFolder + "history.txt");
|
||||
else
|
||||
{
|
||||
if (Msg.ShowQuestion("Create history.txt file in config folder?",
|
||||
"mpv.net will write the date, time and filename of opened files to it.") == MsgResult.OK)
|
||||
|
||||
File.WriteAllText(mp.ConfigFolder + "history.txt", "");
|
||||
}
|
||||
}
|
||||
|
||||
public static void ShowInfo()
|
||||
{
|
||||
try
|
||||
{
|
||||
string performer, title, album, genre, date, duration, text = "";
|
||||
long fileSize = 0;
|
||||
string path = mp.get_property_string("path");
|
||||
|
||||
if (path.Contains("://"))
|
||||
path = mp.get_property_string("media-title");
|
||||
|
||||
int width = mp.get_property_int("video-params/w");
|
||||
int height = mp.get_property_int("video-params/h");
|
||||
|
||||
if (File.Exists(path))
|
||||
{
|
||||
fileSize = new FileInfo(path).Length;
|
||||
|
||||
if (App.AudioTypes.Contains(path.ShortExt()))
|
||||
{
|
||||
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.ShortExt().ToUpper();
|
||||
|
||||
mp.commandv("show-text", text, "5000");
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (App.ImageTypes.Contains(path.ShortExt()))
|
||||
{
|
||||
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.ShortExt().ToUpper();
|
||||
|
||||
mp.commandv("show-text", text, "5000");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TimeSpan position = TimeSpan.FromSeconds(mp.get_property_number("time-pos"));
|
||||
TimeSpan duration2 = TimeSpan.FromSeconds(mp.get_property_number("duration"));
|
||||
string videoFormat = mp.get_property_string("video-format").ToUpper();
|
||||
string audioCodec = mp.get_property_string("audio-codec-name").ToUpper();
|
||||
|
||||
text = path.FileName() + "\n" +
|
||||
FormatTime(position.TotalMinutes) + ":" +
|
||||
FormatTime(position.Seconds) + " / " +
|
||||
FormatTime(duration2.TotalMinutes) + ":" +
|
||||
FormatTime(duration2.Seconds) + "\n" +
|
||||
$"{width} x {height}\n";
|
||||
|
||||
if (fileSize > 0)
|
||||
text += Convert.ToInt32(fileSize / 1024.0 / 1024.0) + " MB\n";
|
||||
|
||||
text += $"{videoFormat}\n{audioCodec}";
|
||||
|
||||
mp.commandv("show-text", text, "5000");
|
||||
string FormatTime(double value) => ((int)value).ToString("00");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Msg.ShowException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void ExecuteMpvCommand() // deprecated 2019
|
||||
{
|
||||
InvokeOnMainThread(new Action(() => {
|
||||
string command = VB.Interaction.InputBox("Enter a mpv command to be executed.", "Execute Command", RegistryHelp.GetString(App.RegPath, "RecentExecutedCommand"));
|
||||
if (string.IsNullOrEmpty(command)) return;
|
||||
RegistryHelp.SetValue(App.RegPath, "RecentExecutedCommand", command);
|
||||
mp.command(command, false);
|
||||
}));
|
||||
}
|
||||
|
||||
public static void OpenURL()
|
||||
{
|
||||
InvokeOnMainThread(new Action(() => {
|
||||
string clipboard = System.Windows.Forms.Clipboard.GetText();
|
||||
if (string.IsNullOrEmpty(clipboard) || (!clipboard.Contains("://") && !File.Exists(clipboard)) || clipboard.Contains("\n"))
|
||||
{
|
||||
Msg.ShowError("The clipboard does not contain a valid URL or file, URLs have to contain :// and are not allowed to contain a newline character.");
|
||||
return;
|
||||
}
|
||||
mp.Load(new [] { clipboard }, false, Control.ModifierKeys.HasFlag(Keys.Control));
|
||||
}));
|
||||
}
|
||||
|
||||
public static void LoadSubtitle()
|
||||
{
|
||||
InvokeOnMainThread(new Action(() => {
|
||||
using (var d = new OpenFileDialog())
|
||||
{
|
||||
string path = mp.get_property_string("path");
|
||||
if (File.Exists(path)) d.InitialDirectory = Path.GetDirectoryName(path);
|
||||
d.Multiselect = true;
|
||||
if (d.ShowDialog() == DialogResult.OK)
|
||||
foreach (string i in d.FileNames)
|
||||
mp.commandv("sub-add", i);
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
public static void LoadAudio()
|
||||
{
|
||||
InvokeOnMainThread(new Action(() => {
|
||||
using (var d = new OpenFileDialog())
|
||||
{
|
||||
string path = mp.get_property_string("path");
|
||||
if (File.Exists(path))
|
||||
d.InitialDirectory = Path.GetDirectoryName(path);
|
||||
d.Multiselect = true;
|
||||
|
||||
if (d.ShowDialog() == DialogResult.OK)
|
||||
foreach (string i in d.FileNames)
|
||||
mp.commandv("audio-add", i);
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
public static void CycleAudio()
|
||||
{
|
||||
string path = mp.get_property_string("path");
|
||||
if (!File.Exists(path)) return;
|
||||
|
||||
using (MediaInfo mi = new MediaInfo(path))
|
||||
{
|
||||
MediaTrack[] audTracks = mp.MediaTracks.Where(track => track.Type == "a").ToArray();
|
||||
if (audTracks.Length < 2) return;
|
||||
int aid = mp.get_property_int("aid");
|
||||
aid += 1;
|
||||
if (aid > audTracks.Length) aid = 1;
|
||||
mp.commandv("set", "aid", aid.ToString());
|
||||
mp.commandv("show-text", audTracks[aid - 1].Text.Substring(3), "5000");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
59
mpv.net/Misc/Extension.cs
Normal file
@@ -0,0 +1,59 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.Composition;
|
||||
using System.ComponentModel.Composition.Hosting;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
namespace mpvnet
|
||||
{
|
||||
public class Extension
|
||||
{
|
||||
[ImportMany]
|
||||
public IEnumerable<IExtension> Extensions = null;
|
||||
|
||||
readonly CompositionContainer CompositionContainer;
|
||||
|
||||
public Extension()
|
||||
{
|
||||
try
|
||||
{
|
||||
AggregateCatalog catalog = new AggregateCatalog();
|
||||
string dir = Folder.Startup + "Extensions";
|
||||
|
||||
if (Directory.Exists(dir))
|
||||
{
|
||||
string[] knownExtensions = { "RatingExtension", "ScriptingExtension" };
|
||||
|
||||
foreach (string path in Directory.GetDirectories(dir))
|
||||
{
|
||||
if (knownExtensions.Contains(Path.GetFileName(path)))
|
||||
catalog.Catalogs.Add(new DirectoryCatalog(path, "*Extension.dll"));
|
||||
else
|
||||
Msg.ShowError("Failed to load extension", path + "\n\nOnly extensions that ship with mpv.net are allowed in <startup>\\extensions\n\nUser extensions have to use <config folder>\\extensions\n\nNever copy or install a new mpv.net version over a old mpv.net version.");
|
||||
}
|
||||
}
|
||||
|
||||
dir = mp.ConfigFolder + "extensions";
|
||||
|
||||
if (Directory.Exists(dir))
|
||||
foreach (string i in Directory.GetDirectories(dir))
|
||||
catalog.Catalogs.Add(new DirectoryCatalog(i, "*Extension.dll"));
|
||||
|
||||
if (catalog.Catalogs.Count > 0)
|
||||
{
|
||||
CompositionContainer = new CompositionContainer(catalog);
|
||||
CompositionContainer.ComposeParts(this);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Msg.ShowException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public interface IExtension
|
||||
{
|
||||
}
|
||||
}
|
||||
32
mpv.net/Misc/ExtensionMethods.cs
Normal file
@@ -0,0 +1,32 @@
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
|
||||
public static class Extensions
|
||||
{
|
||||
public static string FileName(this string path)
|
||||
{
|
||||
if (string.IsNullOrEmpty(path)) return "";
|
||||
int index = path.LastIndexOf('\\');
|
||||
if (index > -1) return path.Substring(index + 1);
|
||||
index = path.LastIndexOf('/');
|
||||
if (index > -1) return path.Substring(index + 1);
|
||||
return path;
|
||||
}
|
||||
|
||||
public static string ShortExt(this string path)
|
||||
{
|
||||
return Path.GetExtension(path).ToLower().TrimStart('.');
|
||||
}
|
||||
|
||||
public static int Int(this string value)
|
||||
{
|
||||
int.TryParse(value, out int result);
|
||||
return result;
|
||||
}
|
||||
|
||||
public static float Float(this string value)
|
||||
{
|
||||
float.TryParse(value.Replace(",", "."), NumberStyles.Float, CultureInfo.InvariantCulture, out float result);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
14
mpv.net/Misc/Help.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
|
||||
class ConsoleHelp
|
||||
{
|
||||
public static void WriteError(object obj)
|
||||
{
|
||||
Console.ForegroundColor = ConsoleColor.Red;
|
||||
Console.WriteLine(obj);
|
||||
Console.ResetColor();
|
||||
Trace.WriteLine(obj);
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
@@ -15,42 +16,18 @@ using Microsoft.Win32;
|
||||
|
||||
namespace mpvnet
|
||||
{
|
||||
public class App
|
||||
{
|
||||
public static string[] VideoTypes { get; } = "mkv mp4 mpg avi mov webm vob wmv flv avs 264 h264 asf webm mpeg mpv y4m avc hevc 265 h265 m2v m2ts vpy mts m4v".Split(" ".ToCharArray());
|
||||
public static string[] AudioTypes { get; } = "mp3 mp2 ac3 ogg opus flac wav w64 m4a dts dtsma dtshr dtshd eac3 thd thd+ac3 mka aac mpa".Split(" ".ToCharArray());
|
||||
|
||||
public static bool IsDarkMode {
|
||||
get {
|
||||
string darkMode = MainForm.Instance.MpvNetDarkMode;
|
||||
return (darkMode == "system" && Sys.IsDarkTheme) || darkMode == "always";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class Sys
|
||||
{
|
||||
public static bool IsDarkTheme {
|
||||
get {
|
||||
object value = Registry.GetValue(@"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Themes\Personalize", "AppsUseLightTheme", 1);
|
||||
if (value is null) value = 1;
|
||||
|
||||
if (value is null)
|
||||
value = 1;
|
||||
|
||||
return (int)value == 0;
|
||||
}
|
||||
}
|
||||
|
||||
public static bool IsDirectoryWritable(string dirPath)
|
||||
{
|
||||
try
|
||||
{
|
||||
using (FileStream fs = File.Create(Path.Combine(dirPath,
|
||||
Path.GetRandomFileName()), 1, FileOptions.DeleteOnClose))
|
||||
{ }
|
||||
return true;
|
||||
}
|
||||
catch
|
||||
{ }
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public class StringLogicalComparer : IComparer, IComparer<string>
|
||||
@@ -75,92 +52,51 @@ namespace mpvnet
|
||||
{
|
||||
Types = types;
|
||||
|
||||
RegistryHelp.SetObject(@"HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\" + ExeFilename, null, ExePath);
|
||||
RegistryHelp.SetObject($"HKCR\\Applications\\{ExeFilename}", "FriendlyAppName", "mpv.net media player");
|
||||
RegistryHelp.SetObject($"HKCR\\Applications\\{ExeFilename}\\shell\\open\\command", null, $"\"{ExePath}\" \"%1\"");
|
||||
RegistryHelp.SetObject(@"HKLM\SOFTWARE\Clients\Media\mpv\Capabilities", "ApplicationDescription", "mpv.net media player");
|
||||
RegistryHelp.SetObject(@"HKLM\SOFTWARE\Clients\Media\mpv\Capabilities", "ApplicationName", "mpv.net");
|
||||
RegistryHelp.SetObject($"HKCR\\SystemFileAssociations\\video\\OpenWithList\\{ExeFilename}", null, "");
|
||||
RegistryHelp.SetObject($"HKCR\\SystemFileAssociations\\audio\\OpenWithList\\{ExeFilename}", null, "");
|
||||
RegistryHelp.SetValue(@"HKCU\Software\Microsoft\Windows\CurrentVersion\App Paths\" + ExeFilename, null, ExePath);
|
||||
RegistryHelp.SetValue(@"HKCR\Applications\" + ExeFilename, "FriendlyAppName", "mpv.net media player");
|
||||
RegistryHelp.SetValue($@"HKCR\Applications\{ExeFilename}\shell\open\command", null, $"\"{ExePath}\" \"%1\"");
|
||||
RegistryHelp.SetValue(@"HKLM\SOFTWARE\Clients\Media\mpv.net\Capabilities", "ApplicationDescription", "mpv.net media player");
|
||||
RegistryHelp.SetValue(@"HKLM\SOFTWARE\Clients\Media\mpv.net\Capabilities", "ApplicationName", "mpv.net");
|
||||
RegistryHelp.SetValue(@"HKCR\SystemFileAssociations\video\OpenWithList\" + ExeFilename, null, "");
|
||||
RegistryHelp.SetValue(@"HKCR\SystemFileAssociations\audio\OpenWithList\" + ExeFilename, null, "");
|
||||
RegistryHelp.SetValue(@"HKLM\SOFTWARE\RegisteredApplications", "mpv.net", @"SOFTWARE\Clients\Media\mpv.net\Capabilities");
|
||||
|
||||
foreach (string ext in Types)
|
||||
{
|
||||
RegistryHelp.SetObject($"HKCR\\Applications\\{ExeFilename}\\SupportedTypes", "." + ext, "");
|
||||
RegistryHelp.SetObject($"HKCR\\" + "." + ext, null, ExeFilenameNoExt + "." + ext);
|
||||
RegistryHelp.SetObject($"HKCR\\" + "." + ext + "\\OpenWithProgIDs", ExeFilenameNoExt + "." + ext, "");
|
||||
RegistryHelp.SetValue($@"HKCR\Applications\{ExeFilename}\SupportedTypes", "." + ext, "");
|
||||
RegistryHelp.SetValue($@"HKCR\" + "." + ext, null, ExeFilenameNoExt + "." + ext);
|
||||
RegistryHelp.SetValue($@"HKCR\" + "." + ext + @"\OpenWithProgIDs", ExeFilenameNoExt + "." + ext, "");
|
||||
|
||||
if (App.VideoTypes.Contains(ext))
|
||||
RegistryHelp.SetObject($"HKCR\\" + "." + ext, "PerceivedType", "video");
|
||||
RegistryHelp.SetValue(@"HKCR\" + "." + ext, "PerceivedType", "video");
|
||||
|
||||
if (App.AudioTypes.Contains(ext))
|
||||
RegistryHelp.SetObject($"HKCR\\" + "." + ext, "PerceivedType", "audio");
|
||||
RegistryHelp.SetObject($"HKCR\\" + ExeFilenameNoExt + "." + ext + "\\shell\\open", null, "Play with " + Application.ProductName);
|
||||
RegistryHelp.SetObject($"HKCR\\" + ExeFilenameNoExt + "." + ext + "\\shell\\open\\command", null, $"\"{ExePath}\" \"%1\"");
|
||||
RegistryHelp.SetObject(@"HKLM\SOFTWARE\Clients\Media\mpv.net\Capabilities\FileAssociations", "." + ext, ExeFilenameNoExt + "." + ext);
|
||||
RegistryHelp.SetValue(@"HKCR\" + "." + ext, "PerceivedType", "audio");
|
||||
|
||||
if (App.ImageTypes.Contains(ext))
|
||||
RegistryHelp.SetValue(@"HKCR\" + "." + ext, "PerceivedType", "image");
|
||||
|
||||
RegistryHelp.SetValue($@"HKCR\" + ExeFilenameNoExt + "." + ext + @"\shell\open\command", null, $"\"{ExePath}\" \"%1\"");
|
||||
RegistryHelp.SetValue(@"HKLM\SOFTWARE\Clients\Media\mpv.net\Capabilities\FileAssociations", "." + ext, ExeFilenameNoExt + "." + ext);
|
||||
}
|
||||
}
|
||||
|
||||
public static void Unregister()
|
||||
{
|
||||
RegistryHelp.RemoveKey(@"HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\" + ExeFilename);
|
||||
RegistryHelp.RemoveKey($"HKCR\\Applications\\{ExeFilename}");
|
||||
RegistryHelp.RemoveKey(@"HKLM\SOFTWARE\Clients\Media\mpv.net");
|
||||
RegistryHelp.RemoveKey($"HKCR\\SystemFileAssociations\\video\\OpenWithList\\{ExeFilename}");
|
||||
RegistryHelp.RemoveKey($"HKCR\\SystemFileAssociations\\audio\\OpenWithList\\{ExeFilename}");
|
||||
RegistryHelp.RemoveKey($@"HKCU\Software\Microsoft\Windows\CurrentVersion\App Paths\" + ExeFilename);
|
||||
RegistryHelp.RemoveKey($@"HKCR\Applications\" + ExeFilename);
|
||||
RegistryHelp.RemoveKey($@"HKLM\SOFTWARE\Clients\Media\mpv.net");
|
||||
RegistryHelp.RemoveKey($@"HKCR\SystemFileAssociations\video\OpenWithList\" + ExeFilename);
|
||||
RegistryHelp.RemoveKey($@"HKCR\SystemFileAssociations\audio\OpenWithList\" + ExeFilename);
|
||||
RegistryHelp.RemoveValue(@"HKLM\SOFTWARE\RegisteredApplications", "mpv.net");
|
||||
|
||||
foreach (string id in Registry.ClassesRoot.GetSubKeyNames())
|
||||
{
|
||||
if (id.StartsWith(ExeFilenameNoExt + "."))
|
||||
Registry.ClassesRoot.DeleteSubKeyTree(id);
|
||||
|
||||
RegistryHelp.RemoveValue($"HKCR\\Software\\Classes\\" + id + "\\OpenWithProgIDs", ExeFilenameNoExt + id);
|
||||
RegistryHelp.RemoveValue($"HKLM\\Software\\Classes\\" + id + "\\OpenWithProgIDs", ExeFilenameNoExt + id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class RegistryHelp
|
||||
{
|
||||
public static void SetObject(string path, string name, object value)
|
||||
{
|
||||
using (RegistryKey rk = GetRootKey(path).CreateSubKey(path.Substring(5), RegistryKeyPermissionCheck.ReadWriteSubTree))
|
||||
rk.SetValue(name, value);
|
||||
}
|
||||
|
||||
public static string GetString(string path, string name)
|
||||
{
|
||||
object val = GetObject(path, name);
|
||||
if (val == null || !(val is string)) return "";
|
||||
return val.ToString();
|
||||
}
|
||||
|
||||
public static object GetObject(string path, string name)
|
||||
{
|
||||
using (RegistryKey rk = GetRootKey(path).OpenSubKey(path.Substring(5)))
|
||||
if (rk != null)
|
||||
return rk.GetValue(name, "");
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void RemoveKey(string path)
|
||||
{
|
||||
GetRootKey(path).DeleteSubKeyTree(path.Substring(5), false);
|
||||
}
|
||||
|
||||
public static void RemoveValue(string path, string name)
|
||||
{
|
||||
using (RegistryKey rk = GetRootKey(path).OpenSubKey(path.Substring(5), true))
|
||||
if (!(rk is null))
|
||||
rk.DeleteValue(name, false);
|
||||
}
|
||||
|
||||
static RegistryKey GetRootKey(string path)
|
||||
{
|
||||
switch (path.Substring(0, 4))
|
||||
{
|
||||
case "HKLM": return Registry.LocalMachine;
|
||||
case "HKCU": return Registry.CurrentUser;
|
||||
case "HKCR": return Registry.ClassesRoot;
|
||||
default: throw new Exception();
|
||||
RegistryHelp.RemoveValue($@"HKCR\Software\Classes\{id}\OpenWithProgIDs", ExeFilenameNoExt + id);
|
||||
RegistryHelp.RemoveValue($@"HKLM\Software\Classes\{id}\OpenWithProgIDs", ExeFilenameNoExt + id);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -207,26 +143,38 @@ namespace mpvnet
|
||||
foreach (string line in content.Split('\r', '\n'))
|
||||
{
|
||||
string val = line.Trim();
|
||||
if (val.StartsWith("#")) continue;
|
||||
if (!val.Contains(" ")) continue;
|
||||
|
||||
if (val.StartsWith("#"))
|
||||
continue;
|
||||
|
||||
if (!val.Contains(" "))
|
||||
continue;
|
||||
|
||||
CommandItem item = new CommandItem();
|
||||
item.Input = val.Substring(0, val.IndexOf(" "));
|
||||
if (item.Input == "_") item.Input = "";
|
||||
|
||||
if (item.Input == "_")
|
||||
item.Input = "";
|
||||
|
||||
val = val.Substring(val.IndexOf(" ") + 1);
|
||||
|
||||
if (val.Contains("#menu:"))
|
||||
{
|
||||
item.Path = val.Substring(val.IndexOf("#menu:") + 6).Trim();
|
||||
val = val.Substring(0, val.IndexOf("#menu:"));
|
||||
|
||||
if (item.Path.Contains(";"))
|
||||
item.Path = item.Path.Substring(item.Path.IndexOf(";") + 1).Trim();
|
||||
}
|
||||
|
||||
item.Command = val.Trim();
|
||||
|
||||
if (item.Command == "")
|
||||
continue;
|
||||
|
||||
if (item.Command.ToLower() == "ignore")
|
||||
item.Command = "";
|
||||
|
||||
MigrateCommands(item);
|
||||
items.Add(item);
|
||||
}
|
||||
@@ -240,10 +188,12 @@ namespace mpvnet
|
||||
get {
|
||||
if (_Items is null)
|
||||
_Items = GetItems(File.ReadAllText(mp.InputConfPath));
|
||||
|
||||
return _Items;
|
||||
}
|
||||
}
|
||||
|
||||
// last change 2019
|
||||
public static void MigrateCommands(CommandItem item)
|
||||
{
|
||||
switch (item.Command)
|
||||
@@ -293,4 +243,9 @@ namespace mpvnet
|
||||
Math.Abs(screenPos.Y - Control.MousePosition.Y) > 10;
|
||||
}
|
||||
}
|
||||
|
||||
public class Folder
|
||||
{
|
||||
public static string Startup { get; } = Application.StartupPath + @"\";
|
||||
}
|
||||
}
|
||||
98
mpv.net/Misc/Program.cs
Normal file
@@ -0,0 +1,98 @@
|
||||
|
||||
using System;
|
||||
using System.Windows.Forms;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace mpvnet
|
||||
{
|
||||
static class Program
|
||||
{
|
||||
[STAThread]
|
||||
static void Main()
|
||||
{
|
||||
try
|
||||
{
|
||||
Application.EnableVisualStyles();
|
||||
Application.SetCompatibleTextRenderingDefault(false);
|
||||
|
||||
if (App.IsStartedFromTerminal)
|
||||
Native.AttachConsole(-1 /*ATTACH_PARENT_PROCESS*/);
|
||||
|
||||
if (mp.ConfigFolder == "")
|
||||
return;
|
||||
|
||||
string[] args = Environment.GetCommandLineArgs().Skip(1).ToArray();
|
||||
|
||||
if (args.Length == 2 && args[0] == "--reg-file-assoc")
|
||||
{
|
||||
if (args[1] == "audio") FileAssociation.Register(App.AudioTypes);
|
||||
if (args[1] == "video") FileAssociation.Register(App.VideoTypes);
|
||||
if (args[1] == "image") FileAssociation.Register(App.ImageTypes);
|
||||
if (args[1] == "unreg") FileAssociation.Unregister();
|
||||
return;
|
||||
}
|
||||
|
||||
App.Init();
|
||||
Mutex mutex = new Mutex(true, "mpvnetProcessInstance", out bool isFirst);
|
||||
|
||||
if ((App.ProcessInstance == "single" || App.ProcessInstance == "queue") && !isFirst)
|
||||
{
|
||||
List<string> files = new List<string>();
|
||||
files.Add(App.ProcessInstance);
|
||||
|
||||
foreach (string arg in args)
|
||||
{
|
||||
if (!arg.StartsWith("--") && (arg == "-" || arg.Contains("://") ||
|
||||
arg.Contains(":\\") || arg.StartsWith("\\\\")))
|
||||
|
||||
files.Add(arg);
|
||||
else if (arg == "--queue")
|
||||
files[0] = "queue";
|
||||
}
|
||||
|
||||
Process[] procs = Process.GetProcessesByName("mpvnet");
|
||||
|
||||
for (int i = 0; i < 20; i++)
|
||||
{
|
||||
foreach (Process proc in procs)
|
||||
{
|
||||
if (proc.MainWindowHandle != IntPtr.Zero)
|
||||
{
|
||||
Native.AllowSetForegroundWindow(proc.Id);
|
||||
var data = new Native.COPYDATASTRUCT();
|
||||
data.lpData = string.Join("\n", files.ToArray());
|
||||
data.cbData = data.lpData.Length * 2 + 1;
|
||||
Native.SendMessage(proc.MainWindowHandle, 0x004A /*WM_COPYDATA*/, IntPtr.Zero, ref data);
|
||||
mutex.Dispose();
|
||||
|
||||
if (App.IsStartedFromTerminal)
|
||||
Native.FreeConsole();
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Thread.Sleep(50);
|
||||
}
|
||||
|
||||
mutex.Dispose();
|
||||
return;
|
||||
}
|
||||
|
||||
Application.Run(new MainForm());
|
||||
|
||||
if (App.IsStartedFromTerminal)
|
||||
Native.FreeConsole();
|
||||
|
||||
mutex.Dispose();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Msg.ShowException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
70
mpv.net/Misc/RegistryHelp.cs
Normal file
@@ -0,0 +1,70 @@
|
||||
|
||||
using System;
|
||||
using Microsoft.Win32;
|
||||
using System.Windows.Forms;
|
||||
|
||||
public class RegistryHelp
|
||||
{
|
||||
public static string ApplicationKey { get; } = @"HKCU\Software\" + Application.ProductName;
|
||||
|
||||
public static void SetValue(string path, string name, object value)
|
||||
{
|
||||
using (RegistryKey regKey = GetRootKey(path).CreateSubKey(path.Substring(5), RegistryKeyPermissionCheck.ReadWriteSubTree))
|
||||
regKey.SetValue(name, value);
|
||||
}
|
||||
|
||||
public static string GetString(string path, string name, string defaultValue = "")
|
||||
{
|
||||
object value = GetValue(path, name, defaultValue);
|
||||
return !(value is string) ? defaultValue : value.ToString();
|
||||
}
|
||||
|
||||
public static int GetInt(string path, string name, int defaultValue = 0)
|
||||
{
|
||||
object value = GetValue(path, name, defaultValue);
|
||||
return !(value is int) ? defaultValue : (int)value;
|
||||
}
|
||||
|
||||
public static bool GetBool(string path, string name, bool defaultValue = false)
|
||||
{
|
||||
object val = GetValue(path, name, defaultValue);
|
||||
return val is bool ? (bool)val : defaultValue;
|
||||
}
|
||||
|
||||
public static object GetValue(string path, string name, object defaultValue = null)
|
||||
{
|
||||
using (RegistryKey regKey = GetRootKey(path).OpenSubKey(path.Substring(5)))
|
||||
return regKey == null ? null : regKey.GetValue(name, defaultValue);
|
||||
}
|
||||
|
||||
public static void RemoveKey(string path)
|
||||
{
|
||||
try
|
||||
{
|
||||
GetRootKey(path).DeleteSubKeyTree(path.Substring(5), false);
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
|
||||
public static void RemoveValue(string path, string name)
|
||||
{
|
||||
try
|
||||
{
|
||||
using (RegistryKey regKey = GetRootKey(path).OpenSubKey(path.Substring(5), true))
|
||||
if (regKey != null)
|
||||
regKey.DeleteValue(name, false);
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
|
||||
static RegistryKey GetRootKey(string path)
|
||||
{
|
||||
switch (path.Substring(0, 4))
|
||||
{
|
||||
case "HKLM": return Registry.LocalMachine;
|
||||
case "HKCU": return Registry.CurrentUser;
|
||||
case "HKCR": return Registry.ClassesRoot;
|
||||
default: throw new Exception();
|
||||
}
|
||||
}
|
||||
}
|
||||
96
mpv.net/Misc/Theme.cs
Normal file
@@ -0,0 +1,96 @@
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Windows.Media;
|
||||
|
||||
namespace UI
|
||||
{
|
||||
public class Theme
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public Dictionary<string, string> Dictionary { get; } = new Dictionary<string, string>();
|
||||
|
||||
public static List<Theme> DefaultThemes { get; set; }
|
||||
public static List<Theme> CustomThemes { get; set; }
|
||||
|
||||
public static Theme Current { get; set; }
|
||||
|
||||
public static Brush Foreground { get; set; }
|
||||
public static Brush Foreground2 { get; set; }
|
||||
public static Brush Background { get; set; }
|
||||
public static Brush Heading { get; set; }
|
||||
|
||||
public System.Drawing.Color GetWinFormsColor(string key)
|
||||
{
|
||||
return System.Drawing.ColorTranslator.FromHtml(Dictionary[key]);
|
||||
}
|
||||
|
||||
public Brush GetBrush(string key)
|
||||
{
|
||||
return new SolidColorBrush((Color)ColorConverter.ConvertFromString(Dictionary[key]));
|
||||
}
|
||||
|
||||
public static void Init(string customContent, string defaultContent, string activeTheme)
|
||||
{
|
||||
DefaultThemes = Load(defaultContent);
|
||||
CustomThemes = Load(customContent);
|
||||
|
||||
foreach (Theme theme in CustomThemes)
|
||||
{
|
||||
if (theme.Name == activeTheme)
|
||||
{
|
||||
bool isKeyMissing = false;
|
||||
|
||||
foreach (string key in DefaultThemes[0].Dictionary.Keys)
|
||||
{
|
||||
if (!theme.Dictionary.ContainsKey(key))
|
||||
{
|
||||
isKeyMissing = true;
|
||||
ConsoleHelp.WriteError($"Theme '{activeTheme}' misses '{key}'");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!isKeyMissing)
|
||||
Current = theme;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (Current == null)
|
||||
foreach (Theme theme in DefaultThemes)
|
||||
if (theme.Name == activeTheme)
|
||||
Current = theme;
|
||||
|
||||
if (Current == null)
|
||||
Current = DefaultThemes[0];
|
||||
|
||||
Foreground = Current.GetBrush("foreground");
|
||||
Foreground2 = Current.GetBrush("foreground2");
|
||||
Background = Current.GetBrush("background");
|
||||
Heading = Current.GetBrush("heading");
|
||||
}
|
||||
|
||||
static List<Theme> Load(string content)
|
||||
{
|
||||
List<Theme> list = new List<Theme>();
|
||||
Theme theme = null;
|
||||
|
||||
foreach (string currentLine in (content ?? "").Split(new [] { '\r', '\n' }))
|
||||
{
|
||||
string line = currentLine.Trim();
|
||||
|
||||
if (line.StartsWith("[") && line.EndsWith("]"))
|
||||
list.Add(theme = new Theme() { Name = line.Substring(1, line.Length - 2).Trim() });
|
||||
|
||||
if (line.Contains("=") && theme != null)
|
||||
{
|
||||
string left = line.Substring(0, line.IndexOf("=")).Trim();
|
||||
theme.Dictionary[left] = line.Substring(line.IndexOf("=") + 1).Trim();
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
}
|
||||
}
|
||||
74
mpv.net/Misc/UpdateCheck.cs
Normal file
@@ -0,0 +1,74 @@
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Net.Http;
|
||||
using System.Reflection;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace mpvnet
|
||||
{
|
||||
class UpdateCheck
|
||||
{
|
||||
public static void DailyCheck()
|
||||
{
|
||||
if (App.UpdateCheck && RegistryHelp.GetInt(RegistryHelp.ApplicationKey, "UpdateCheckLast")
|
||||
!= DateTime.Now.DayOfYear)
|
||||
|
||||
CheckOnline();
|
||||
}
|
||||
|
||||
public static async void CheckOnline(bool showUpToDateMessage = false)
|
||||
{
|
||||
try
|
||||
{
|
||||
using (HttpClient client = new HttpClient())
|
||||
{
|
||||
RegistryHelp.SetValue(RegistryHelp.ApplicationKey, "UpdateCheckLast", DateTime.Now.DayOfYear);
|
||||
client.DefaultRequestHeaders.Add("User-Agent", "mpv.net");
|
||||
var response = await client.GetAsync("https://api.github.com/repos/stax76/mpv.net/releases/latest");
|
||||
response.EnsureSuccessStatusCode();
|
||||
string content = await response.Content.ReadAsStringAsync();
|
||||
Match match = Regex.Match(content, @"""mpv\.net-portable-x64-([\d\.]+)\.7z""");
|
||||
Version onlineVersion = Version.Parse(match.Groups[1].Value);
|
||||
Version currentVersion = Assembly.GetEntryAssembly().GetName().Version;
|
||||
|
||||
if (onlineVersion == currentVersion)
|
||||
{
|
||||
if (showUpToDateMessage)
|
||||
Msg.Show($"{Application.ProductName} is up to date.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (RegistryHelp.GetString(RegistryHelp.ApplicationKey, "UpdateCheckVersion")
|
||||
!= onlineVersion.ToString() && Msg.ShowQuestion(
|
||||
$"New version {onlineVersion} is available, update now?") == MsgResult.OK)
|
||||
{
|
||||
string arch = IntPtr.Size == 8 ? "64" : "86";
|
||||
string url = $"https://github.com/stax76/mpv.net/releases/download/{onlineVersion}/mpv.net-portable-x{arch}-{onlineVersion}.7z";
|
||||
|
||||
using (Process proc = new Process())
|
||||
{
|
||||
proc.StartInfo.FileName = "PowerShell";
|
||||
proc.StartInfo.Arguments = $"-NoLogo -NoExit -File \"{Folder.Startup + "Update.ps1"}\" \"{url}\" \"{Application.StartupPath}\"";
|
||||
|
||||
if (Folder.Startup.Contains("Program Files"))
|
||||
proc.StartInfo.Verb = "runas";
|
||||
|
||||
proc.Start();
|
||||
}
|
||||
|
||||
mp.command("quit");
|
||||
}
|
||||
|
||||
RegistryHelp.SetValue(RegistryHelp.ApplicationKey, "UpdateCheckVersion", onlineVersion.ToString());
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (showUpToDateMessage)
|
||||
Msg.ShowException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,74 +0,0 @@
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace mpvnet
|
||||
{
|
||||
public class Native
|
||||
{
|
||||
[DllImport("kernel32.dll")]
|
||||
public static extern IntPtr LoadLibrary(string dllToLoad);
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
|
||||
public static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter, string lclassName, string windowTitle);
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
|
||||
public static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam);
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
|
||||
public static extern IntPtr PostMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
public static extern void ReleaseCapture();
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
public static extern bool AdjustWindowRect(ref RECT lpRect, uint dwStyle, bool bMenu);
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, int uFlags);
|
||||
|
||||
[DllImport("user32.dll", EntryPoint = "GetWindowLong")]
|
||||
private static extern IntPtr GetWindowLong32(IntPtr hWnd, int nIndex);
|
||||
|
||||
[DllImport("user32.dll", EntryPoint = "GetWindowLongPtr")]
|
||||
private static extern IntPtr GetWindowLong64(IntPtr hWnd, int nIndex);
|
||||
|
||||
public static IntPtr GetWindowLongPtr(IntPtr hWnd, int nIndex)
|
||||
{
|
||||
if (IntPtr.Size == 8)
|
||||
return GetWindowLong64(hWnd, nIndex);
|
||||
else
|
||||
return GetWindowLong32(hWnd, nIndex);
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct RECT
|
||||
{
|
||||
public int Left;
|
||||
public int Top;
|
||||
public int Right;
|
||||
public int Bottom;
|
||||
|
||||
public RECT(Rectangle r)
|
||||
{
|
||||
Left = r.Left;
|
||||
Top = r.Top;
|
||||
Right = r.Right;
|
||||
Bottom = r.Bottom;
|
||||
}
|
||||
|
||||
public RECT(int left, int top, int right, int bottom)
|
||||
{
|
||||
Left = left;
|
||||
Top = top;
|
||||
Right = right;
|
||||
Bottom = bottom;
|
||||
}
|
||||
|
||||
public Rectangle ToRectangle() { return Rectangle.FromLTRB(Left, Top, Right, Bottom); }
|
||||
public Size Size => new Size(Right - Left, Bottom - Top);
|
||||
public int Width => Right - Left;
|
||||
public int Height => Bottom - Top;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10,7 +10,7 @@ public class MediaInfo : IDisposable
|
||||
{
|
||||
if (!Loaded)
|
||||
{
|
||||
if (LoadLibrary("MediaInfo.dll") == IntPtr.Zero)
|
||||
if (Native.LoadLibrary("MediaInfo.dll") == IntPtr.Zero)
|
||||
throw new Exception("Failed to load MediaInfo.dll.");
|
||||
|
||||
Loaded = true;
|
||||
@@ -56,21 +56,24 @@ public class MediaInfo : IDisposable
|
||||
|
||||
~MediaInfo() { Dispose(); }
|
||||
|
||||
[DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
|
||||
static extern IntPtr LoadLibrary(string path);
|
||||
|
||||
[DllImport("MediaInfo.dll")]
|
||||
static extern IntPtr MediaInfo_New();
|
||||
|
||||
[DllImport("MediaInfo.dll")]
|
||||
static extern void MediaInfo_Delete(IntPtr handle);
|
||||
[DllImport("MediaInfo.dll", CharSet = CharSet.Unicode)]
|
||||
static extern int MediaInfo_Open(IntPtr handle, string path);
|
||||
|
||||
[DllImport("MediaInfo.dll", CharSet = CharSet.Unicode)]
|
||||
static extern int MediaInfo_Open(IntPtr handle, string fileName);
|
||||
static extern IntPtr MediaInfo_Option(IntPtr handle, string optionString, string value);
|
||||
|
||||
[DllImport("MediaInfo.dll")]
|
||||
static extern IntPtr MediaInfo_Inform(IntPtr handle, int reserved);
|
||||
|
||||
[DllImport("MediaInfo.dll")]
|
||||
static extern int MediaInfo_Close(IntPtr handle);
|
||||
|
||||
[DllImport("MediaInfo.dll")]
|
||||
static extern void MediaInfo_Delete(IntPtr handle);
|
||||
|
||||
[DllImport("MediaInfo.dll", CharSet = CharSet.Unicode)]
|
||||
static extern IntPtr MediaInfo_Get(IntPtr handle,
|
||||
MediaInfoStreamKind streamKind,
|
||||
95
mpv.net/Native/Native.cs
Normal file
@@ -0,0 +1,95 @@
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
public class Native
|
||||
{
|
||||
[DllImport("kernel32.dll")]
|
||||
public static extern bool AttachConsole(int dwProcessId);
|
||||
|
||||
[DllImport("kernel32.dll")]
|
||||
public static extern bool FreeConsole();
|
||||
|
||||
[DllImport("kernel32.dll")]
|
||||
public static extern IntPtr LoadLibrary(string path);
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
|
||||
public static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter, string lclassName, string windowTitle);
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
|
||||
public static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam);
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
|
||||
public static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wParam, ref COPYDATASTRUCT lParam);
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
|
||||
public static extern IntPtr PostMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam);
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
|
||||
public static extern int RegisterWindowMessage(string id);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
public static extern bool AllowSetForegroundWindow(int dwProcessId);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
public static extern void ReleaseCapture();
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
public static extern bool AdjustWindowRect(ref RECT lpRect, uint dwStyle, bool bMenu);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, int uFlags);
|
||||
|
||||
[DllImport("user32.dll", EntryPoint = "GetWindowLong")]
|
||||
private static extern IntPtr GetWindowLong32(IntPtr hWnd, int nIndex);
|
||||
|
||||
[DllImport("user32.dll", EntryPoint = "GetWindowLongPtr")]
|
||||
private static extern IntPtr GetWindowLong64(IntPtr hWnd, int nIndex);
|
||||
|
||||
public static IntPtr GetWindowLong(IntPtr hWnd, int nIndex)
|
||||
{
|
||||
if (IntPtr.Size == 8)
|
||||
return GetWindowLong64(hWnd, nIndex);
|
||||
else
|
||||
return GetWindowLong32(hWnd, nIndex);
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct RECT
|
||||
{
|
||||
public int Left;
|
||||
public int Top;
|
||||
public int Right;
|
||||
public int Bottom;
|
||||
|
||||
public RECT(Rectangle r)
|
||||
{
|
||||
Left = r.Left;
|
||||
Top = r.Top;
|
||||
Right = r.Right;
|
||||
Bottom = r.Bottom;
|
||||
}
|
||||
|
||||
public RECT(int left, int top, int right, int bottom)
|
||||
{
|
||||
Left = left;
|
||||
Top = top;
|
||||
Right = right;
|
||||
Bottom = bottom;
|
||||
}
|
||||
|
||||
public Rectangle ToRectangle() => Rectangle.FromLTRB(Left, Top, Right, Bottom);
|
||||
public Size Size => new Size(Right - Left, Bottom - Top);
|
||||
public int Width => Right - Left;
|
||||
public int Height => Bottom - Top;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct COPYDATASTRUCT
|
||||
{
|
||||
public IntPtr dwData;
|
||||
public int cbData;
|
||||
[MarshalAs(UnmanagedType.LPTStr)]
|
||||
public string lpData;
|
||||
}
|
||||
}
|
||||
@@ -32,7 +32,7 @@ namespace mpvnet
|
||||
|
||||
public static void AddWindowBorders(IntPtr hwnd, ref Native.RECT rc)
|
||||
{
|
||||
Native.AdjustWindowRect(ref rc, (uint)Native.GetWindowLongPtr(hwnd, -16 /* GWL_STYLE */), false);
|
||||
Native.AdjustWindowRect(ref rc, (uint)Native.GetWindowLong(hwnd, -16 /* GWL_STYLE */), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Collections.Generic;
|
||||
@@ -50,23 +51,23 @@ public class Msg
|
||||
td.Show();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
catch (Exception e)
|
||||
{
|
||||
MessageBox.Show(ex.GetType().Name + "\n\n" + ex.Message + "\n\n" + ex.ToString(),
|
||||
MessageBox.Show(e.GetType().Name + "\n\n" + e.Message + "\n\n" + e,
|
||||
Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
}
|
||||
}
|
||||
|
||||
public static void ShowException(Exception e)
|
||||
public static void ShowException(Exception exception)
|
||||
{
|
||||
try
|
||||
{
|
||||
using (TaskDialog<string> td = new TaskDialog<string>())
|
||||
{
|
||||
td.MainInstruction = e.GetType().Name;
|
||||
td.Content = e.Message;
|
||||
td.MainInstruction = exception.GetType().Name;
|
||||
td.Content = exception.Message;
|
||||
td.MainIcon = MsgIcon.Error;
|
||||
td.ExpandedInformation = e.ToString();
|
||||
td.ExpandedInformation = exception.ToString();
|
||||
td.Footer = "[Copy Message](copymsg)";
|
||||
|
||||
if (!string.IsNullOrEmpty(Msg.SupportURL))
|
||||
@@ -75,9 +76,9 @@ public class Msg
|
||||
td.Show();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
catch (Exception e)
|
||||
{
|
||||
MessageBox.Show(ex.GetType().Name + "\n\n" + ex.Message + "\n\n" + ex.ToString(),
|
||||
MessageBox.Show(e.GetType().Name + "\n\n" + e.Message + "\n\n" + e,
|
||||
Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
}
|
||||
}
|
||||
@@ -144,9 +145,9 @@ public class Msg
|
||||
return td.Show();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
catch (Exception e)
|
||||
{
|
||||
return (MsgResult)MessageBox.Show(ex.GetType().Name + "\n\n" + ex.Message + "\n\n" + ex.ToString(),
|
||||
return (MsgResult)MessageBox.Show(e.GetType().Name + "\n\n" + e.Message + "\n\n" + e,
|
||||
Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
}
|
||||
}
|
||||
@@ -235,6 +236,7 @@ public class TaskDialog<T> : TaskDialogNative, IDisposable
|
||||
|
||||
if (Path.GetFileName(lpszFileName.ToString().Replace(".vshost", "")) ==
|
||||
Path.GetFileName(Assembly.GetEntryAssembly().Location))
|
||||
|
||||
return foregroundWindow;
|
||||
|
||||
return IntPtr.Zero;
|
||||
@@ -359,7 +361,7 @@ public class TaskDialog<T> : TaskDialogNative, IDisposable
|
||||
public void AddCommandLink(string text, T value)
|
||||
{
|
||||
int n = 1000 + IdValueDic.Count + 1;
|
||||
IdValueDic[n] = value == null ? (T)(object)text : value;
|
||||
IdValueDic[n] = value;
|
||||
IdTextDic[n] = text;
|
||||
Buttons.Add(new TaskDialogNative.TASKDIALOG_BUTTON(n, text));
|
||||
Config.dwFlags |= TaskDialogNative.TASKDIALOG_FLAGS.TDF_USE_COMMAND_LINKS;
|
||||
53
mpv.net/Native/Taskbar.cs
Normal file
@@ -0,0 +1,53 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
public class Taskbar
|
||||
{
|
||||
private ITaskbarList3 Instance = (ITaskbarList3)new TaskBarCommunication();
|
||||
|
||||
public IntPtr Handle { get; set; }
|
||||
|
||||
public Taskbar(IntPtr handle) => Handle = handle;
|
||||
|
||||
[ComImportAttribute]
|
||||
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
|
||||
[GuidAttribute("ea1afb91-9e28-4b86-90e9-9e9f8a5eefaf")]
|
||||
private interface ITaskbarList3
|
||||
{
|
||||
// ITaskbarList
|
||||
[PreserveSig] void HrInit();
|
||||
[PreserveSig] void AddTab(IntPtr hwnd);
|
||||
[PreserveSig] void DeleteTab(IntPtr hwnd);
|
||||
[PreserveSig] void ActivateTab(IntPtr hwnd);
|
||||
[PreserveSig] void SetActiveAlt(IntPtr hwnd);
|
||||
// ITaskbarList2
|
||||
[PreserveSig] void MarkFullscreenWindow(IntPtr hwnd, [MarshalAs(UnmanagedType.Bool)] bool fFullscreen);
|
||||
// ITaskbarList3
|
||||
[PreserveSig] void SetProgressValue(IntPtr hwnd, UInt64 ullCompleted, UInt64 ullTotal);
|
||||
[PreserveSig] void SetProgressState(IntPtr hwnd, TaskbarStates state);
|
||||
}
|
||||
|
||||
[ComImportAttribute]
|
||||
[ClassInterfaceAttribute(ClassInterfaceType.None)]
|
||||
[GuidAttribute("56FDF344-FD6D-11d0-958A-006097C9A090")]
|
||||
private class TaskBarCommunication { }
|
||||
|
||||
public void SetState(TaskbarStates taskbarState)
|
||||
{
|
||||
Instance.SetProgressState(Handle, taskbarState);
|
||||
}
|
||||
|
||||
public void SetValue(double progressValue, double progressMax)
|
||||
{
|
||||
Instance.SetProgressValue(Handle, (UInt64)progressValue, (UInt64)progressMax);
|
||||
}
|
||||
}
|
||||
|
||||
public enum TaskbarStates
|
||||
{
|
||||
NoProgress = 0,
|
||||
Indeterminate = 0x1,
|
||||
Normal = 0x2,
|
||||
Error = 0x4,
|
||||
Paused = 0x8
|
||||
}
|
||||
@@ -1,127 +0,0 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using System.Management.Automation.Runspaces;
|
||||
using System.Reflection;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace mpvnet
|
||||
{
|
||||
public class PowerShellScript
|
||||
{
|
||||
public static object Execute(string code, string[] parameters)
|
||||
{
|
||||
using (Runspace runspace = RunspaceFactory.CreateRunspace())
|
||||
{
|
||||
runspace.ApartmentState = ApartmentState.STA;
|
||||
runspace.ThreadOptions = PSThreadOptions.UseCurrentThread;
|
||||
runspace.Open();
|
||||
|
||||
using (Pipeline pipeline = runspace.CreatePipeline())
|
||||
{
|
||||
pipeline.Commands.AddScript(
|
||||
@"Using namespace mpvnet;
|
||||
Using namespace System;
|
||||
[System.Reflection.Assembly]::LoadWithPartialName(""mpvnet"")");
|
||||
|
||||
pipeline.Commands.AddScript(code);
|
||||
|
||||
try
|
||||
{
|
||||
var ret = pipeline.Invoke(parameters);
|
||||
|
||||
if (ret.Count > 0)
|
||||
return ret[0];
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
try
|
||||
{
|
||||
using (Pipeline pipeline2 = runspace.CreatePipeline())
|
||||
{
|
||||
pipeline2.Commands.AddScript("$PSVersionTable.PSVersion.Major * 10 +" +
|
||||
"$PSVersionTable.PSVersion.Minor");
|
||||
|
||||
if (Convert.ToInt32(pipeline2.Invoke()[0].ToString()) < 51)
|
||||
throw new Exception();
|
||||
}
|
||||
}
|
||||
catch (Exception ex2)
|
||||
{
|
||||
Msg.ShowError("PowerShell Setup Problem\n\nEnsure you have at least PowerShell 5.1 installed.", ex2.ToString());
|
||||
return null;
|
||||
}
|
||||
Msg.ShowException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void Init(string filePath)
|
||||
{
|
||||
foreach (var eventInfo in typeof(mp).GetEvents())
|
||||
{
|
||||
if (eventInfo.Name.ToLower() ==
|
||||
Path.GetFileNameWithoutExtension(filePath).ToLower().Replace("-", ""))
|
||||
{
|
||||
PowerShellEventObject eventObject = new PowerShellEventObject();
|
||||
MethodInfo mi;
|
||||
eventObject.FilePath = filePath;
|
||||
|
||||
if (eventInfo.EventHandlerType == typeof(Action))
|
||||
{
|
||||
mi = eventObject.GetType().GetMethod(nameof(PowerShellEventObject.Invoke));
|
||||
}
|
||||
else if (eventInfo.EventHandlerType == typeof(Action<EndFileEventMode>))
|
||||
{
|
||||
mi = eventObject.GetType().GetMethod(nameof(PowerShellEventObject.InvokeEndFileEventMode));
|
||||
}
|
||||
else if (eventInfo.EventHandlerType == typeof(Action<string[]>))
|
||||
{
|
||||
mi = eventObject.GetType().GetMethod(nameof(PowerShellEventObject.InvokeStrings));
|
||||
}
|
||||
else
|
||||
throw new Exception();
|
||||
|
||||
eventObject.EventInfo = eventInfo;
|
||||
Delegate handler = Delegate.CreateDelegate(eventInfo.EventHandlerType, eventObject, mi);
|
||||
eventObject.Delegate = handler;
|
||||
eventInfo.AddEventHandler(eventObject, handler);
|
||||
return;
|
||||
}
|
||||
}
|
||||
Task.Run(() =>
|
||||
{
|
||||
PowerShellScript.Execute(File.ReadAllText(filePath), new string[] {});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public class PowerShellEventObject
|
||||
{
|
||||
public EventInfo EventInfo { get; set; }
|
||||
public Delegate Delegate { get; set; }
|
||||
public string FilePath { get; set; }
|
||||
|
||||
public void Invoke()
|
||||
{
|
||||
Task.Run(() => { PowerShellScript.Execute(File.ReadAllText(FilePath), new string[] { }); });
|
||||
}
|
||||
|
||||
public void InvokeEndFileEventMode(EndFileEventMode arg)
|
||||
{
|
||||
Task.Run(() =>
|
||||
{
|
||||
PowerShellScript.Execute(File.ReadAllText(FilePath), new string[] { arg.ToString() });
|
||||
});
|
||||
}
|
||||
|
||||
public void InvokeStrings(string[] args)
|
||||
{
|
||||
Task.Run(() => {
|
||||
PowerShellScript.Execute(File.ReadAllText(FilePath), args);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
using System;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace mpvnet
|
||||
{
|
||||
static class Program
|
||||
{
|
||||
[STAThread]
|
||||
static void Main()
|
||||
{
|
||||
try
|
||||
{
|
||||
string[] args = Environment.GetCommandLineArgs();
|
||||
|
||||
if (args.Length == 3 && args[1] == "--reg-file-assoc")
|
||||
{
|
||||
if (args[2] == "audio") FileAssociation.Register(App.AudioTypes);
|
||||
if (args[2] == "video") FileAssociation.Register(App.VideoTypes);
|
||||
if (args[2] == "unreg") FileAssociation.Unregister();
|
||||
return;
|
||||
}
|
||||
|
||||
Application.EnableVisualStyles();
|
||||
Application.SetCompatibleTextRenderingDefault(false);
|
||||
Application.Run(new MainForm());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Msg.ShowException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,11 +6,11 @@ using System.Runtime.InteropServices;
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("mpv.net")]
|
||||
[assembly: AssemblyDescription("A lightweight media player")]
|
||||
[assembly: AssemblyDescription("mpv based media player")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyCompany("Frank Skare (stax76)")]
|
||||
[assembly: AssemblyProduct("mpv.net")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2017-2019 stax76")]
|
||||
[assembly: AssemblyCopyright("Copyright (c) 2017-2019 Frank Skare (stax76)")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
@@ -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("3.6.1.0")]
|
||||
[assembly: AssemblyFileVersion("3.6.1.0")]
|
||||
[assembly: AssemblyVersion("5.4.4.0")]
|
||||
[assembly: AssemblyFileVersion("5.4.4.0")]
|
||||
|
||||
96
mpv.net/Properties/Resources.Designer.cs
generated
@@ -60,33 +60,109 @@ namespace mpvnet.Properties {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to [[settings]]
|
||||
///name = "hwdec"
|
||||
///file = "mpv"
|
||||
///default = "no"
|
||||
///filter = "Video"
|
||||
///url = "https://mpv.io/manual/master/#options-hwdec"
|
||||
///help = "Specify the hardware video decoding API that should be used if possible. Whether hardware decoding is actually done depends on the video codec. If hardware decoding is not possible, mpv will fall back on software decoding.\n\nFor more information visit:"
|
||||
///options = [{ name = "no", help = "always use software decoding" },
|
||||
/// { name = "auto", hel [rest of string was truncated]";.
|
||||
/// </summary>
|
||||
internal static string confToml {
|
||||
get {
|
||||
return ResourceManager.GetString("confToml", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to
|
||||
/// # This file defines the key and mouse bindings and the context menu
|
||||
/// # of mpv.net. A input and config editor can be found in mpv.net's
|
||||
/// # context menu under 'Settings'. The defaults of this file can be found at:
|
||||
///
|
||||
/// # https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/inputConf.txt
|
||||
///
|
||||
/// # The defaults of mpv can be found at:
|
||||
///
|
||||
/// # https://github.com/mpv-player/mpv/blob/master/etc/input.conf
|
||||
///
|
||||
/// # mpv.net's defaults of mpv.conf contain: 'input-default-bindings = no'
|
||||
/// # which disables mpv's [rest of string was truncated]";.
|
||||
/// </summary>
|
||||
internal static string inputConf {
|
||||
get {
|
||||
return ResourceManager.GetString("inputConf", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
internal static string inputConfHeader {
|
||||
get {
|
||||
return ResourceManager.GetString("inputConfHeader", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to input-default-bindings = no
|
||||
///input-ar-delay = 500
|
||||
///input-ar-rate = 20
|
||||
///keep-open = yes
|
||||
///keep-open-pause = no
|
||||
///osd-playing-msg = '${filename}'
|
||||
///script-opts = osc-scalewindowed=1.5
|
||||
///screenshot-directory = '~~desktop/'
|
||||
///cscale = spline36
|
||||
///dscale = spline36
|
||||
///scale = spline36
|
||||
///hwdec = yes
|
||||
///
|
||||
///[protocol.https]
|
||||
///osd-playing-msg = '${media-title}'.
|
||||
/// </summary>
|
||||
internal static string mpvConf {
|
||||
get {
|
||||
return ResourceManager.GetString("mpvConf", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
internal static string mpvConfToml {
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Drawing.Bitmap.
|
||||
/// </summary>
|
||||
internal static System.Drawing.Bitmap mpvnet {
|
||||
get {
|
||||
return ResourceManager.GetString("mpvConfToml", resourceCulture);
|
||||
object obj = ResourceManager.GetObject("mpvnet", resourceCulture);
|
||||
return ((System.Drawing.Bitmap)(obj));
|
||||
}
|
||||
}
|
||||
|
||||
internal static string mpvNetConfToml {
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to
|
||||
///[dark]
|
||||
///
|
||||
///heading = #1E90FF
|
||||
///foreground = #FFFFFF
|
||||
///foreground2 = #C0C0C0
|
||||
///background = #323232
|
||||
///
|
||||
///menu-foreground = #FFFFFF
|
||||
///menu-background = #323232
|
||||
///menu-highlight = #505050
|
||||
///menu-border = #FFFFFF
|
||||
///menu-checked = #5A5A5A
|
||||
///
|
||||
///[light]
|
||||
///
|
||||
///heading = #0068B2
|
||||
///foreground = #000000
|
||||
///foreground2 = #4C4C4C
|
||||
///background = #F7F7F7
|
||||
///
|
||||
///menu-foreground = #000000
|
||||
///menu-background = #DFDFDF
|
||||
///menu-highlight = #BFBFBF
|
||||
///menu-border = #6A6A6A
|
||||
///menu-checked = #AAAAAA
|
||||
///.
|
||||
/// </summary>
|
||||
internal static string theme {
|
||||
get {
|
||||
return ResourceManager.GetString("mpvNetConfToml", resourceCulture);
|
||||
return ResourceManager.GetString("theme", resourceCulture);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -118,19 +118,19 @@
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="confToml" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\ConfToml.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
|
||||
</data>
|
||||
<data name="inputConf" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\inputConf.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252</value>
|
||||
</data>
|
||||
<data name="inputConfHeader" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\inputConfHeader.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
|
||||
</data>
|
||||
<data name="mpvConf" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\mpvConf.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
|
||||
</data>
|
||||
<data name="mpvConfToml" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\mpvConfToml.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
|
||||
<data name="mpvnet" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\mpvnet.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="mpvNetConfToml" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\mpvNetConfToml.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
|
||||
<data name="theme" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\theme.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
|
||||
</data>
|
||||
</root>
|
||||
2
mpv.net/Properties/Settings.Designer.cs
generated
@@ -12,7 +12,7 @@ namespace mpvnet.Properties {
|
||||
|
||||
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.0.0.0")]
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.3.0.0")]
|
||||
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
|
||||
|
||||
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
|
||||
|
||||
561
mpv.net/Resources/ConfToml.txt
Normal file
@@ -0,0 +1,561 @@
|
||||
|
||||
[[settings]]
|
||||
name = "hwdec"
|
||||
file = "mpv"
|
||||
default = "no"
|
||||
filter = "Video"
|
||||
url = "https://mpv.io/manual/master/#options-hwdec"
|
||||
help = "Specify the hardware video decoding API that should be used if possible. Whether hardware decoding is actually done depends on the video codec. If hardware decoding is not possible, mpv will fall back on software decoding.\n\nFor more information visit:"
|
||||
options = [{ name = "no", help = "always use software decoding" },
|
||||
{ name = "auto", help = "enable best hw decoder (see below)" },
|
||||
{ name = "yes", help = "exactly the same as auto" },
|
||||
{ name = "auto-copy", help = "enable best hw decoder with copy-back (see below)" },
|
||||
{ name = "dxva2", help = "requires vo=gpu with gpu-context=d3d11, gpu-context=angle or gpu-context=dxinterop (Windows only)" },
|
||||
{ name = "dxva2-copy", help = "copies video back to system RAM (Windows only)" },
|
||||
{ name = "d3d11va", help = "requires vo=gpu with gpu-context=d3d11 or gpu-context=angle (Windows 8+ only)" },
|
||||
{ name = "d3d11va-copy", help = "copies video back to system RAM (Windows 8+ only)" },
|
||||
{ name = "cuda", help = "requires vo=gpu (Any platform CUDA is available)" },
|
||||
{ name = "cuda-copy", help = "copies video back to system RAM (Any platform CUDA is available)" },
|
||||
{ name = "nvdec", help = "requires vo=gpu (Any platform CUDA is available)" },
|
||||
{ name = "nvdec-copy", help = "copies video back to system RAM (Any platform CUDA is available)" },
|
||||
{ name = "crystalhd", help = "copies video back to system RAM (Any platform supported by hardware)" },
|
||||
{ name = "rkmpp", help = "requires vo=gpu (some RockChip devices only)" }]
|
||||
|
||||
[[settings]]
|
||||
name = "gpu-api"
|
||||
file = "mpv"
|
||||
default = "auto"
|
||||
filter = "Video"
|
||||
help = "Controls which type of graphics APIs will be accepted. Auto uses d3d11, it should only be changed in case of problems, Vulkan is not recommended."
|
||||
options = [{ name = "auto", help = "Use any available API" },
|
||||
{ name = "opengl", help = "Allow only OpenGL (requires OpenGL 2.1+ or GLES 2.0+)" },
|
||||
{ name = "vulkan", help = "Allow only Vulkan (not recommended). " },
|
||||
{ name = "d3d11", help = "Allow only gpu-context=d3d11" }]
|
||||
|
||||
[[settings]]
|
||||
name = "gpu-context"
|
||||
file = "mpv"
|
||||
default = "auto"
|
||||
filter = "Video"
|
||||
options = [{ name = "auto", help = "auto-select" },
|
||||
{ name = "win", help = "Win32/WGL" },
|
||||
{ name = "winvk", help = "VK_KHR_win32_surface" },
|
||||
{ name = "angle", help = "Direct3D11 through the OpenGL ES translation layer ANGLE. This supports almost everything the win backend does (if the ANGLE build is new enough)." },
|
||||
{ name = "dxinterop", help = "(experimental) Win32, using WGL for rendering and Direct3D 9Ex for presentation. Works on Nvidia and AMD. Newer Intel chips with the latest drivers may also work." },
|
||||
{ name = "d3d11", help = "Win32, with native Direct3D 11 rendering." }]
|
||||
|
||||
[[settings]]
|
||||
name = "vo"
|
||||
file = "mpv"
|
||||
default = "gpu"
|
||||
filter = "Video"
|
||||
help = "Video output drivers to be used.\n\nFor more information visit:"
|
||||
url = "https://mpv.io/manual/master/#video-output-drivers-vo"
|
||||
options = [{ name = "gpu", help = "General purpose, customizable, GPU-accelerated video output driver. It supports extended scaling methods, dithering, color management, custom shaders, HDR, and more." },
|
||||
{ name = "direct3d", help = "Video output driver that uses the Direct3D interface" }]
|
||||
|
||||
[[settings]]
|
||||
name = "video-sync"
|
||||
file = "mpv"
|
||||
default = "audio"
|
||||
filter = "Video"
|
||||
help = "How the player synchronizes audio and video.\n\nFor more information visit:"
|
||||
url = "https://mpv.io/manual/master/#options-video-sync"
|
||||
options = [{ name = "audio" },
|
||||
{ name = "display-resample" },
|
||||
{ name = "display-resample-vdrop" },
|
||||
{ name = "display-resample-desync" },
|
||||
{ name = "display-vdrop" },
|
||||
{ name = "display-adrop" },
|
||||
{ name = "display-desync" },
|
||||
{ name = "desync" }]
|
||||
|
||||
[[settings]]
|
||||
name = "scale"
|
||||
file = "mpv"
|
||||
default = "bilinear"
|
||||
filter = "Video"
|
||||
help = "The GPU renderer filter function to use when upscaling video. There are some more filters, but most are not as useful. For a complete list, pass help as value, e.g.: mpv --scale=help"
|
||||
options = [{ name = "bilinear", help = "Bilinear hardware texture filtering (fastest, very low quality)." },
|
||||
{ name = "spline36", help = "Mid quality and speed. This is the default when using gpu-hq." },
|
||||
{ name = "lanczos", help = "Lanczos scaling. Provides mid quality and speed. Generally worse than spline36, but it results in a slightly sharper image which is good for some content types. The number of taps can be controlled with scale-radius, but is best left unchanged. (This filter is an alias for sinc-windowed sinc)" },
|
||||
{ name = "ewa_lanczos", help = "Elliptic weighted average Lanczos scaling. Also known as Jinc. Relatively slow, but very good quality. The radius can be controlled with scale-radius. Increasing the radius makes the filter sharper but adds more ringing. (This filter is an alias for jinc-windowed jinc)" },
|
||||
{ name = "ewa_lanczossharp", help = "A slightly sharpened version of ewa_lanczos, preconfigured to use an ideal radius and parameter. If your hardware can run it, this is probably what you should use by default." },
|
||||
{ name = "mitchell", help = "Mitchell-Netravali. The B and C parameters can be set with scale-param1 and scale-param2. This filter is very good at downscaling (see dscale)." },
|
||||
{ name = "oversample", help = "A version of nearest neighbour that (naively) oversamples pixels, so that pixels overlapping edges get linearly interpolated instead of rounded. This essentially removes the small imperfections and judder artifacts caused by nearest-neighbour interpolation, in exchange for adding some blur. This filter is good at temporal interpolation, and also known as \"smoothmotion\" (see tscale)." },
|
||||
{ name = "linear", help = "A tscale filter." }]
|
||||
|
||||
[[settings]]
|
||||
name = "cscale"
|
||||
file = "mpv"
|
||||
default = "bilinear"
|
||||
filter = "Video"
|
||||
help = "As scale, but for interpolating chroma information. If the image is not subsampled, this option is ignored entirely."
|
||||
options = [{ name = "bilinear", help = "Bilinear hardware texture filtering (fastest, very low quality)." },
|
||||
{ name = "spline36", help = "Mid quality and speed. This is the default when using gpu-hq." },
|
||||
{ name = "lanczos", help = "Lanczos scaling. Provides mid quality and speed. Generally worse than spline36, but it results in a slightly sharper image which is good for some content types. The number of taps can be controlled with scale-radius, but is best left unchanged. (This filter is an alias for sinc-windowed sinc)" },
|
||||
{ name = "ewa_lanczos", help = "Elliptic weighted average Lanczos scaling. Also known as Jinc. Relatively slow, but very good quality. The radius can be controlled with scale-radius. Increasing the radius makes the filter sharper but adds more ringing. (This filter is an alias for jinc-windowed jinc)" },
|
||||
{ name = "ewa_lanczossharp", help = "A slightly sharpened version of ewa_lanczos, preconfigured to use an ideal radius and parameter. If your hardware can run it, this is probably what you should use by default." },
|
||||
{ name = "mitchell", help = "Mitchell-Netravali. The B and C parameters can be set with scale-param1 and scale-param2. This filter is very good at downscaling (see dscale)." },
|
||||
{ name = "oversample", help = "A version of nearest neighbour that (naively) oversamples pixels, so that pixels overlapping edges get linearly interpolated instead of rounded. This essentially removes the small imperfections and judder artifacts caused by nearest-neighbour interpolation, in exchange for adding some blur. This filter is good at temporal interpolation, and also known as \"smoothmotion\" (see tscale)." },
|
||||
{ name = "linear", help = "A tscale filter." }]
|
||||
|
||||
[[settings]]
|
||||
name = "dscale"
|
||||
file = "mpv"
|
||||
default = "bilinear"
|
||||
filter = "Video"
|
||||
help = "Like scale, but apply these filters on downscaling instead. If this option is unset, the filter implied by scale will be applied."
|
||||
options = [{ name = "bilinear", help = "Bilinear hardware texture filtering (fastest, very low quality)." },
|
||||
{ name = "spline36", help = "Mid quality and speed. This is the default when using gpu-hq." },
|
||||
{ name = "lanczos", help = "Lanczos scaling. Provides mid quality and speed. Generally worse than spline36, but it results in a slightly sharper image which is good for some content types. The number of taps can be controlled with scale-radius, but is best left unchanged. (This filter is an alias for sinc-windowed sinc)" },
|
||||
{ name = "ewa_lanczos", help = "Elliptic weighted average Lanczos scaling. Also known as Jinc. Relatively slow, but very good quality. The radius can be controlled with scale-radius. Increasing the radius makes the filter sharper but adds more ringing. (This filter is an alias for jinc-windowed jinc)" },
|
||||
{ name = "ewa_lanczossharp", help = "A slightly sharpened version of ewa_lanczos, preconfigured to use an ideal radius and parameter. If your hardware can run it, this is probably what you should use by default." },
|
||||
{ name = "mitchell", help = "Mitchell-Netravali. The B and C parameters can be set with scale-param1 and scale-param2. This filter is very good at downscaling (see dscale)." },
|
||||
{ name = "oversample", help = "A version of nearest neighbour that (naively) oversamples pixels, so that pixels overlapping edges get linearly interpolated instead of rounded. This essentially removes the small imperfections and judder artifacts caused by nearest-neighbour interpolation, in exchange for adding some blur. This filter is good at temporal interpolation, and also known as \"smoothmotion\" (see tscale)." },
|
||||
{ name = "linear", help = "A tscale filter." }]
|
||||
|
||||
[[settings]]
|
||||
name = "dither-depth"
|
||||
file = "mpv"
|
||||
default = "no"
|
||||
filter = "Video"
|
||||
help = "Set dither target depth to N. Note that the depth of the connected video display device cannot be detected. Often, LCD panels will do dithering on their own, which conflicts with this option and leads to ugly output."
|
||||
options = [{ name = "no", help = "Disable any dithering done by mpv." },
|
||||
{ name = "auto", help = "Automatic selection. If output bit depth cannot be detected, 8 bits per component are assumed." },
|
||||
{ name = "8", help = "Dither to 8 bit output." }]
|
||||
|
||||
[[settings]]
|
||||
name = "correct-downscaling"
|
||||
file = "mpv"
|
||||
default = "no"
|
||||
filter = "Video"
|
||||
help = "When using convolution based filters, extend the filter size when downscaling. Increases quality, but reduces performance while downscaling.\n\nThis will perform slightly sub-optimally for anamorphic video (but still better than without it) since it will extend the size to match only the milder of the scale factors between the axes."
|
||||
options = [{ name = "yes" },
|
||||
{ name = "no" }]
|
||||
|
||||
[[settings]]
|
||||
name = "sigmoid-upscaling"
|
||||
file = "mpv"
|
||||
default = "no"
|
||||
filter = "Video"
|
||||
help = "When upscaling, use a sigmoidal color transform to avoid emphasizing ringing artifacts. This also implies linear-scaling."
|
||||
options = [{ name = "yes" },
|
||||
{ name = "no" }]
|
||||
|
||||
[[settings]]
|
||||
name = "deband"
|
||||
file = "mpv"
|
||||
default = "no"
|
||||
filter = "Video"
|
||||
help = "Enable the debanding algorithm. This greatly reduces the amount of visible banding, blocking and other quantization artifacts, at the expense of very slightly blurring some of the finest details. In practice, it's virtually always an improvement - the only reason to disable it would be for performance."
|
||||
options = [{ name = "yes" },
|
||||
{ name = "no" }]
|
||||
|
||||
[[settings]]
|
||||
name = "volume"
|
||||
file = "mpv"
|
||||
filter = "Audio"
|
||||
help = "Set the startup volume. 0 means silence, 100 means no volume reduction or amplification. Negative values can be passed for compatibility, but are treated as 0. Since mpv 0.18.1, this always controls the internal mixer (aka \"softvol\"). Default: 100"
|
||||
|
||||
[[settings]]
|
||||
name = "remember-volume"
|
||||
file = "mpvnet"
|
||||
default = "yes"
|
||||
filter = "Audio"
|
||||
help = "Save volume and mute on exit and restore it on start. (mpv.net specific setting)"
|
||||
options = [{ name = "yes" },
|
||||
{ name = "no" }]
|
||||
|
||||
[[settings]]
|
||||
name = "alang"
|
||||
file = "mpv"
|
||||
filter = "Audio"
|
||||
type = "string"
|
||||
help = "Specify a priority list of audio languages to use. Different container formats employ different language codes. DVDs use ISO 639-1 two-letter language codes, Matroska, MPEG-TS and NUT use ISO 639-2 three-letter language codes, while OGM uses a free-form identifier. See also aid.\n\nExamples\n\nmpv dvd://1 alang=hu,en chooses the Hungarian language track on a DVD and falls back on English if Hungarian is not available.\n\nmpv alang=jpn example.mkv plays a Matroska file with Japanese audio."
|
||||
|
||||
[[settings]]
|
||||
name = "audio-file-auto"
|
||||
file = "mpv"
|
||||
default = "no"
|
||||
filter = "Audio"
|
||||
help = "Load additional audio files matching the video filename. The parameter specifies how external audio files are matched."
|
||||
options = [{ name = "no", help = "Don't automatically load external audio files." },
|
||||
{ name = "exact", help = "Load the media filename with audio file extension." },
|
||||
{ name = "fuzzy", help = "Load all audio files containing media filename." },
|
||||
{ name = "all", help = "Load all audio files in the current and audio-file-paths directories." }]
|
||||
|
||||
[[settings]]
|
||||
name = "slang"
|
||||
file = "mpv"
|
||||
filter = "Subtitle"
|
||||
type = "string"
|
||||
help = "Specify a priority list of subtitle languages to use. Different container formats employ different language codes. DVDs use ISO 639-1 two letter language codes, Matroska uses ISO 639-2 three letter language codes while OGM uses a free-form identifier. See also sid."
|
||||
|
||||
[[settings]]
|
||||
name = "sub-auto"
|
||||
file = "mpv"
|
||||
default = "exact"
|
||||
filter = "Subtitle"
|
||||
help = "Load additional subtitle files matching the video filename. The parameter specifies how external subtitle files are matched. exact is enabled by default."
|
||||
options = [{ name = "no", help = "Don't automatically load external subtitle files." },
|
||||
{ name = "exact", help = "Load the media filename with subtitle file extension." },
|
||||
{ name = "fuzzy", help = "Load all subs containing media filename." },
|
||||
{ name = "all", help = "Load all subs in the current and sub-file-paths directories." }]
|
||||
|
||||
[[settings]]
|
||||
name = "sub-font"
|
||||
file = "mpv"
|
||||
filter = "Subtitle"
|
||||
type = "string"
|
||||
help = "Specify font to use for subtitles that do not themselves specify a particular font. The default is sans-serif."
|
||||
|
||||
[[settings]]
|
||||
name = "sub-font-size"
|
||||
file = "mpv"
|
||||
filter = "Subtitle"
|
||||
help = "Specify the sub font size. The unit is the size in scaled pixels at a window height of 720. The actual pixel size is scaled with the window height: if the window height is larger or smaller than 720, the actual size of the text increases or decreases as well. Default: 55"
|
||||
|
||||
[[settings]]
|
||||
name = "sub-color"
|
||||
file = "mpv"
|
||||
type = "color"
|
||||
filter = "Subtitle"
|
||||
help = "Specify the color used for unstyled text subtitles.\n\nThe color is specified in the form r/g/b, where each color component is specified as number in the range 0.0 to 1.0. It's also possible to specify the transparency by using r/g/b/a, where the alpha value 0 means fully transparent, and 1.0 means opaque. If the alpha component is not given, the color is 100% opaque.\n\nPassing a single number to the option sets the sub to gray, and the form gray/a lets you specify alpha additionally.\n\nExamples\n\n1.0/0.0/0.0 set sub to opaque red\n1.0/0.0/0.0/0.75 set sub to opaque red with 75% alpha\n0.5/0.75 set sub to 50% gray with 75% alpha\n\nAlternatively, the color can be specified as a RGB hex triplet in the form #RRGGBB, where each 2-digit group expresses a color value in the range 0 (00) to 255 (FF). For example, #FF0000 is red. This is similar to web colors. Alpha is given with #AARRGGBB.\n\nExamples\n\n#FF0000 set sub to opaque red\n#C0808080 set sub to 50% gray with 75% alpha"
|
||||
|
||||
[[settings]]
|
||||
name = "sub-border-color"
|
||||
file = "mpv"
|
||||
type = "color"
|
||||
filter = "Subtitle"
|
||||
help = "See sub-color. Color used for the sub font border. Ignored when sub-back-color is specified (or more exactly: when that option is not set to completely transparent)."
|
||||
|
||||
[[settings]]
|
||||
name = "sub-back-color"
|
||||
file = "mpv"
|
||||
type = "color"
|
||||
filter = "Subtitle"
|
||||
help = "See sub-color. Color used for sub text background. You can use sub-shadow-offset to change its size relative to the text."
|
||||
|
||||
[[settings]]
|
||||
name = "fullscreen"
|
||||
file = "mpv"
|
||||
default = "no"
|
||||
filter = "Screen"
|
||||
help = "Start the player in fullscreen mode."
|
||||
options = [{ name = "yes" },
|
||||
{ name = "no" }]
|
||||
|
||||
[[settings]]
|
||||
name = "border"
|
||||
file = "mpv"
|
||||
default = "yes"
|
||||
filter = "Screen"
|
||||
help = "Show window with decoration (titlebar, border)."
|
||||
options = [{ name = "yes" },
|
||||
{ name = "no" }]
|
||||
|
||||
[[settings]]
|
||||
name = "screen"
|
||||
file = "mpv"
|
||||
filter = "Screen"
|
||||
help = "<0-32> In multi-monitor configurations (i.e. a single desktop that spans across multiple displays), this option tells mpv which screen to display the video on."
|
||||
|
||||
[[settings]]
|
||||
name = "osd-playing-msg"
|
||||
file = "mpv"
|
||||
width = 300
|
||||
filter = "Screen"
|
||||
type = "string"
|
||||
help = "Show a message on OSD when playback starts. The string is expanded for properties, e.g. osd-playing-msg='file: ${filename}' will show the message file: followed by a space and the currently played filename. For more information visit:"
|
||||
url = "https://mpv.io/manual/master/#property-expansion"
|
||||
|
||||
[[settings]]
|
||||
name = "osd-font-size"
|
||||
file = "mpv"
|
||||
filter = "Screen"
|
||||
help = "Specify the OSD font size. See sub-font-size for details. Default: 55"
|
||||
|
||||
[[settings]]
|
||||
name = "osd-scale-by-window"
|
||||
file = "mpv"
|
||||
default = "yes"
|
||||
filter = "Screen"
|
||||
help = "Whether to scale the OSD with the window size. If this is disabled, osd-font-size and other OSD options that use scaled pixels are always in actual pixels. The effect is that changing the window size won't change the OSD font size."
|
||||
options = [{ name = "yes" },
|
||||
{ name = "no" }]
|
||||
|
||||
[[settings]]
|
||||
name = "autofit"
|
||||
file = "mpv"
|
||||
filter = "Screen"
|
||||
help = "<int> Initial window height in percent. Default: 50"
|
||||
|
||||
[[settings]]
|
||||
name = "autofit-smaller"
|
||||
file = "mpv"
|
||||
filter = "Screen"
|
||||
help = "<int> Minimum window height in percent. Default: 40"
|
||||
|
||||
[[settings]]
|
||||
name = "autofit-larger"
|
||||
file = "mpv"
|
||||
filter = "Screen"
|
||||
help = "<int> Maximum window height in percent. Default: 75"
|
||||
|
||||
[[settings]]
|
||||
name = "start-size"
|
||||
file = "mpvnet"
|
||||
default = "previous"
|
||||
filter = "Screen"
|
||||
help = "Setting to remember the window height in the current session, otherwise the video's native resolution is used. (mpv.net specific setting)"
|
||||
options = [{ name = "video", help = "Window size is set to native video resolution" },
|
||||
{ name = "previous", help = "Window size is remembered but only from the current session" }]
|
||||
|
||||
[[settings]]
|
||||
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 setting)"
|
||||
|
||||
[[settings]]
|
||||
name = "minimum-aspect-ratio"
|
||||
file = "mpvnet"
|
||||
filter = "Screen"
|
||||
help = "<float> Minimum aspect ratio for the window. Default: 1.3 (mpv.net specific setting)"
|
||||
|
||||
[[settings]]
|
||||
name = "remember-position"
|
||||
file = "mpvnet"
|
||||
default = "no"
|
||||
filter = "Screen"
|
||||
help = "Save the window position on exit. (mpv.net specific setting)"
|
||||
options = [{ name = "yes" },
|
||||
{ name = "no" }]
|
||||
|
||||
[[settings]]
|
||||
name = "maximized"
|
||||
file = "mpvnet"
|
||||
default = "no"
|
||||
filter = "Screen"
|
||||
help = "Start with a maximized window. (mpv.net specific setting)"
|
||||
options = [{ name = "yes" },
|
||||
{ name = "no" }]
|
||||
|
||||
[[settings]]
|
||||
name = "screenshot-directory"
|
||||
file = "mpv"
|
||||
width = 500
|
||||
type = "folder"
|
||||
filter = "Screen"
|
||||
help = "Store screenshots in this directory. This path is joined with the filename generated by screenshot-template. If the template filename is already absolute, the directory is ignored.\n\nIf the directory does not exist, it is created on the first screenshot. If it is not a directory, an error is generated when trying to write a screenshot."
|
||||
|
||||
[[settings]]
|
||||
name = "screenshot-format"
|
||||
file = "mpv"
|
||||
default = "jpg"
|
||||
filter = "Screen"
|
||||
help = "Set the image file type used for saving screenshots."
|
||||
options = [{ name = "jpg" },
|
||||
{ name = "png" }]
|
||||
|
||||
[[settings]]
|
||||
name = "screenshot-tag-colorspace"
|
||||
file = "mpv"
|
||||
default = "no"
|
||||
filter = "Screen"
|
||||
help = "Tag screenshots with the appropriate colorspace. Note that not all formats are supported."
|
||||
options = [{ name = "yes" },
|
||||
{ name = "no" }]
|
||||
|
||||
[[settings]]
|
||||
name = "screenshot-high-bit-depth"
|
||||
file = "mpv"
|
||||
default = "yes"
|
||||
filter = "Screen"
|
||||
help = "If possible, write screenshots with a bit depth similar to the source video. This is interesting in particular for PNG, as this sometimes triggers writing 16 bit PNGs with huge file sizes. This will also include an unused alpha channel in the resulting files if 16 bit is used."
|
||||
options = [{ name = "yes" },
|
||||
{ name = "no" }]
|
||||
|
||||
[[settings]]
|
||||
name = "screenshot-jpeg-source-chroma"
|
||||
file = "mpv"
|
||||
default = "yes"
|
||||
filter = "Screen"
|
||||
help = "Write JPEG files with the same chroma subsampling as the video. If disabled, the libjpeg default is used."
|
||||
options = [{ name = "yes" },
|
||||
{ name = "no" }]
|
||||
|
||||
[[settings]]
|
||||
name = "screenshot-template"
|
||||
file = "mpv"
|
||||
filter = "Screen"
|
||||
type = "string"
|
||||
help = "Specify the filename template used to save screenshots. The template specifies the filename without file extension, and can contain format specifiers, which will be substituted when taking a screenshot. By default, the template is mpv-shot%n, which results in filenames like mpv-shot0012.png for example.\n\nFind the full documentation here:"
|
||||
url = "https://mpv.io/manual/master/#options-screenshot-template"
|
||||
|
||||
[[settings]]
|
||||
name = "screenshot-jpeg-quality"
|
||||
file = "mpv"
|
||||
filter = "Screen"
|
||||
help = "<0-100> Set the JPEG quality level. Higher means better quality. The default is 90."
|
||||
|
||||
[[settings]]
|
||||
name = "screenshot-png-compression"
|
||||
file = "mpv"
|
||||
filter = "Screen"
|
||||
help = "<0-9> Set the PNG compression level. Higher means better compression. This will affect the file size of the written screenshot file and the time it takes to write a screenshot. Too high compression might occupy enough CPU time to interrupt playback. The default is 7."
|
||||
|
||||
[[settings]]
|
||||
name = "screenshot-png-filter"
|
||||
file = "mpv"
|
||||
filter = "Screen"
|
||||
help = "<0-5> Set the filter applied prior to PNG compression. 0 is none, 1 is 'sub', 2 is 'up', 3 is 'average', 4 is 'Paeth', and 5 is 'mixed'. This affects the level of compression that can be achieved. For most images, 'mixed' achieves the best compression ratio, hence it is the default."
|
||||
|
||||
[[settings]]
|
||||
name = "taskbar-progress"
|
||||
file = "mpv"
|
||||
default = "yes"
|
||||
filter = "Playback"
|
||||
help = "Show progress in taskbar."
|
||||
options = [{ name = "yes" },
|
||||
{ name = "no" }]
|
||||
|
||||
[[settings]]
|
||||
name = "keep-open-pause"
|
||||
file = "mpv"
|
||||
default = "yes"
|
||||
filter = "Playback"
|
||||
help = "If set to no, instead of pausing when keep-open is active, just stop at end of file and continue playing forward when you seek backwards until end where it stops again."
|
||||
options = [{ name = "yes" },
|
||||
{ name = "no" }]
|
||||
|
||||
[[settings]]
|
||||
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."
|
||||
options = [{ name = "yes", help = "If the current file ends, go to the next file, keep the last file open."},
|
||||
{ name = "no", help = "If the current file ends, go to the next file." },
|
||||
{ name = "always", help = "Playback will never automatically advance to the next file."}]
|
||||
|
||||
[[settings]]
|
||||
name = "loop-file"
|
||||
file = "mpv"
|
||||
filter = "Playback"
|
||||
help = "<N|inf|no> Loop a single file N times. inf means forever, no means normal playback.\n\nThe difference to loop-playlist is that this doesn't loop the playlist, just the file itself. If the playlist contains only a single file, the difference between the two option is that this option performs a seek on loop, instead of reloading the file. loop is an alias for this option."
|
||||
|
||||
[[settings]]
|
||||
name = "save-position-on-quit"
|
||||
file = "mpv"
|
||||
default = "no"
|
||||
filter = "Playback"
|
||||
help = "Always save the current playback position on quit. When this file is played again later, the player will seek to the old playback position on start. This does not happen if playback of a file is stopped in any other way than quitting. For example, going to the next file in the playlist will not save the position, and start playback at beginning the next time the file is played.\n\nThis behavior is disabled by default, but is always available when quitting the player with Shift+Q."
|
||||
options = [{ name = "yes" },
|
||||
{ name = "no" }]
|
||||
|
||||
[[settings]]
|
||||
name = "hr-seek"
|
||||
file = "mpv"
|
||||
default = "absolute"
|
||||
filter = "Playback"
|
||||
help = "Select when to use precise seeks that are not limited to keyframes. Such seeks require decoding video from the previous keyframe up to the target position and so can take some time depending on decoding performance. For some video formats, precise seeks are disabled. This option selects the default choice to use for seeks; it is possible to explicitly override that default in the definition of key bindings and in input commands."
|
||||
options = [{ name = "yes", help = "Use precise seeks whenever possible." },
|
||||
{ name = "no", help = "Never use precise seeks." },
|
||||
{ name = "absolute", help = "Use precise seeks if the seek is to an absolute position in the file, such as a chapter seek, but not for relative seeks like the default behavior of arrow keys." },
|
||||
{ name = "always", help = "Same as yes (for compatibility)." }]
|
||||
|
||||
[[settings]]
|
||||
name = "track-auto-selection"
|
||||
file = "mpv"
|
||||
default = "yes"
|
||||
filter = "Playback"
|
||||
help = "Enable the default track auto-selection. Enabling this will make the player select streams according to aid, alang, and others. If it is disabled, no tracks are selected. In addition, the player will not exit if no tracks are selected, and wait instead (this wait mode is similar to pausing, but the pause option is not set).\n\nThis is useful with lavfi-complex: you can start playback in this mode, and then set select tracks at runtime by setting the filter graph. Note that if lavfi-complex is set before playback is started, the referenced tracks are always selected."
|
||||
options = [{ name = "yes" },
|
||||
{ name = "no" }]
|
||||
|
||||
[[settings]]
|
||||
name = "loop-playlist"
|
||||
file = "mpv"
|
||||
filter = "Playback"
|
||||
help = "<N|inf|force|no> Loops playback N times. A value of 1 plays it one time (default), 2 two times, etc. inf means forever. no is the same as 1 and disables looping. If several files are specified on command line, the entire playlist is looped. The force mode is like inf, but does not skip playlist entries which have been marked as failing. This means the player might waste CPU time trying to loop a file that doesn't exist. But it might be useful for playing webradios under very bad network conditions."
|
||||
|
||||
[[settings]]
|
||||
name = "auto-load-folder"
|
||||
file = "mpvnet"
|
||||
default = "yes"
|
||||
filter = "Playback"
|
||||
help = "For single files automatically load the entire directory into the playlist. Can be suppressed via shift key. (mpv.net specific setting)"
|
||||
options = [{ name = "yes" },
|
||||
{ name = "no" }]
|
||||
|
||||
[[settings]]
|
||||
name = "input-ar-delay"
|
||||
file = "mpv"
|
||||
filter = "Input"
|
||||
help = "Delay in milliseconds before we start to autorepeat a key (0 to disable)."
|
||||
|
||||
[[settings]]
|
||||
name = "input-ar-rate"
|
||||
file = "mpv"
|
||||
filter = "Input"
|
||||
help = "Number of key presses to generate per second on autorepeat."
|
||||
|
||||
[[settings]]
|
||||
name = "update-check"
|
||||
file = "mpvnet"
|
||||
default = "no"
|
||||
filter = "General"
|
||||
help = "Daily check for new version. (requires PowerShell 5 and curl. mpv.net specific setting)"
|
||||
options = [{ name = "yes" },
|
||||
{ name = "no" }]
|
||||
|
||||
[[settings]]
|
||||
name = "process-instance"
|
||||
file = "mpvnet"
|
||||
default = "single"
|
||||
filter = "General"
|
||||
help = "Defines if more then one mpv.net process is allowed. (mpv.net specific setting)\n\nTip: Whenever the control key is pressed when files or URLs are opened, the playlist is not cleared but the files or URLs are appended to the playlist. This not only works on process startup but in all mpv.net features that open files and URLs."
|
||||
options = [{ name = "multi", help = "Create a new process everytime the shell starts mpv.net" },
|
||||
{ name = "single", help = "Force a single process everytime the shell starts mpv.net" },
|
||||
{ name = "queue", help = "Force a single process and add files to playlist" }]
|
||||
|
||||
[[settings]]
|
||||
name = "recent-count"
|
||||
file = "mpvnet"
|
||||
filter = "General"
|
||||
help = "<int> Amount of recent files to be remembered. Default: 15 (mpv.net specific setting)"
|
||||
|
||||
[[settings]]
|
||||
name = "debug-mode"
|
||||
file = "mpvnet"
|
||||
default = "no"
|
||||
filter = "General"
|
||||
help = "Enable this only when a developer asks for it. (mpv.net specific setting)"
|
||||
options = [{ name = "yes" },
|
||||
{ name = "no" }]
|
||||
|
||||
[[settings]]
|
||||
name = "dark-mode"
|
||||
file = "mpvnet"
|
||||
default = "always"
|
||||
filter = "UI"
|
||||
help = "Enables a dark theme. (mpv.net specific setting)"
|
||||
options = [{ name = "always" },
|
||||
{ name = "system" , help = "Available on Windows 10 or higher" },
|
||||
{ name = "never" }]
|
||||
|
||||
[[settings]]
|
||||
name = "dark-theme"
|
||||
file = "mpvnet"
|
||||
filter = "UI"
|
||||
url = "https://github.com/stax76/mpv.net/blob/master/Manual.md#color-theme"
|
||||
help = "Color theme used in dark mode. Default: dark"
|
||||
|
||||
[[settings]]
|
||||
name = "light-theme"
|
||||
file = "mpvnet"
|
||||
filter = "UI"
|
||||
url = "https://github.com/stax76/mpv.net/blob/master/Manual.md#color-theme"
|
||||
help = "Color theme used in light mode. Default: light"
|
||||
@@ -1,17 +1,11 @@
|
||||
|
||||
# This file defines the input (keys and mouse) bindings of mpv and mpv.net
|
||||
# and it also defines the context menu of mpv.net. mpv.net has an input
|
||||
# editor and an config editor as alternative to editing conf text files.
|
||||
# The input and config editor can be found in mpv.net's context menu at:
|
||||
|
||||
# Settings > Show Config Editor
|
||||
# Settings > Show Input Editor
|
||||
|
||||
# The defaults of this file can be found at:
|
||||
# This file defines the key and mouse bindings and the context menu
|
||||
# of mpv.net. A input and config editor can be found in mpv.net's
|
||||
# context menu under 'Settings'. The defaults of this file can be found at:
|
||||
|
||||
# https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/inputConf.txt
|
||||
|
||||
# the defaults of mpv can be found at:
|
||||
# The defaults of mpv can be found at:
|
||||
|
||||
# https://github.com/mpv-player/mpv/blob/master/etc/input.conf
|
||||
|
||||
@@ -20,18 +14,23 @@
|
||||
# space character to make it easier to do a text search, so if you want to know
|
||||
# if 'o' has already a binding you can make a text search on ' o '.
|
||||
|
||||
# mpv input commands: https://github.com/stax76/mpv.net/wiki/mpv-input-commands
|
||||
# mpv input commands: https://mpv.io/manual/master/#list-of-input-commands
|
||||
|
||||
# mpv input keys: https://github.com/stax76/mpv.net/wiki/mpv-input-keys
|
||||
|
||||
o script-message mpv.net open-files #menu: Open > Open Files...
|
||||
u script-message mpv.net open-url #menu: Open > Open URL...
|
||||
Ctrl+S script-message mpv.net show-media-search #menu: Open > Show media search...
|
||||
_ ignore #menu: Open > -
|
||||
Alt+a script-message mpv.net load-audio #menu: Open > Load external audio files...
|
||||
Alt+s script-message mpv.net load-sub #menu: Open > Load external subtitle files...
|
||||
_ ignore #menu: Open > -
|
||||
_ ignore #menu: Open > Recent
|
||||
# run mpv.net in input test mode with: mpvnet --input-test
|
||||
|
||||
o script-message mpv.net open-files #menu: Open > Open Files...
|
||||
u script-message mpv.net open-url #menu: Open > Open URL or file path from clipboard
|
||||
_ 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...
|
||||
Alt+s script-message mpv.net load-sub #menu: Open > Load external subtitle files...
|
||||
_ ignore #menu: Open > -
|
||||
_ script-message mpv.net open-files append #menu: Open > Add files to playlist...
|
||||
F3 script-message mpv.net show-media-search #menu: Open > Show media search...
|
||||
_ ignore #menu: Open > -
|
||||
_ ignore #menu: Open > Recent
|
||||
|
||||
_ ignore #menu: -
|
||||
Space cycle pause #menu: Play/Pause
|
||||
@@ -42,6 +41,9 @@
|
||||
F11 playlist-prev #menu: Navigate > Previous File
|
||||
F12 playlist-next #menu: Navigate > Next File
|
||||
_ ignore #menu: Navigate > -
|
||||
Home set playlist-pos 0 #menu: Navigate > First File
|
||||
End script-message mpv.net playlist-last #menu: Navigate > Last File
|
||||
_ ignore #menu: Navigate > -
|
||||
PGUP add chapter 1 #menu: Navigate > Next Chapter
|
||||
PGDWN add chapter -1 #menu: Navigate > Previous Chapter
|
||||
_ ignore #menu: Navigate > -
|
||||
@@ -74,7 +76,7 @@
|
||||
Ctrl+BS set video-zoom 0; set video-pan-x 0; set video-pan-y 0 #menu: Pan & Scan > Reset
|
||||
|
||||
Ctrl+1 add contrast -1 #menu: Video > Decrease Contrast
|
||||
Ctrl+2 add contrast #menu: Video > Increase Contrast
|
||||
Ctrl+2 add contrast 1 #menu: Video > Increase Contrast
|
||||
_ ignore #menu: Video > -
|
||||
Ctrl+3 add brightness -1 #menu: Video > Decrease Brightness
|
||||
Ctrl+4 add brightness 1 #menu: Video > Increase Brightness
|
||||
@@ -127,54 +129,67 @@
|
||||
KP3 script-message rate-file 3 #menu: Extensions > Rating > 3stars
|
||||
KP4 script-message rate-file 4 #menu: Extensions > Rating > 4stars
|
||||
KP5 script-message rate-file 5 #menu: Extensions > Rating > 5stars
|
||||
_ ignore #menu: Extensions > Rating > -
|
||||
_ script-message rate-file about #menu: Extensions > Rating > About
|
||||
|
||||
Ctrl+t set ontop yes #menu: View > On Top > Enable
|
||||
Ctrl+T set ontop no #menu: View > On Top > Disable
|
||||
i script-message mpv.net show-info #menu: View > File Info
|
||||
Alt++ no-osd set window-scale 1.2 #menu: View > Window Size > Enlarge
|
||||
Alt+- no-osd set window-scale 0.8 #menu: View > Window Size > Shrink
|
||||
b cycle border #menu: View > Toggle Border
|
||||
i script-message mpv.net show-info #menu: View > File/Stream Info
|
||||
t script-binding stats/display-stats #menu: View > Show Statistics
|
||||
T script-binding stats/display-stats-toggle #menu: View > Toggle Statistics
|
||||
Del script-binding osc/visibility #menu: View > Toggle OSC Visibility
|
||||
F8 show-text ${playlist} 5000 #menu: View > Show Playlist
|
||||
F8 script-binding show-playlist #menu: View > Show Playlist
|
||||
F9 show-text ${track-list} 5000 #menu: View > Show Audio/Video/Subtitle List
|
||||
|
||||
Ctrl+c script-message mpv.net show-conf-editor #menu: Settings > Show Config Editor
|
||||
c script-message mpv.net show-conf-editor #menu: Settings > Show Config Editor
|
||||
Ctrl+i script-message mpv.net show-input-editor #menu: Settings > Show Input Editor
|
||||
Ctrl+f script-message mpv.net open-conf-folder #menu: Settings > Open Config Folder
|
||||
|
||||
Ctrl+P script-message mpv.net show-command-palette #menu: Tools > Command Palette
|
||||
F1 script-message mpv.net show-command-palette #menu: Tools > Show All Commands
|
||||
h script-message mpv.net show-history #menu: Tools > Show History
|
||||
Ctrl+r script-message-to repl type "" #menu: Tools > Show REPL
|
||||
l ab-loop #menu: Tools > Set/clear A-B loop points
|
||||
L cycle-values loop-file "inf" "no" #menu: Tools > Toggle infinite file looping
|
||||
Ctrl+h cycle-values hwdec "auto" "no" #menu: Tools > Cycle Hardware Decoding
|
||||
_ script-message mpv.net execute-mpv-command #menu: Tools > Execute mpv command...
|
||||
_ script-message mpv.net manage-file-associations #menu: Tools > Manage File Associations...
|
||||
_ cycle shuffle #menu: Tools > Toggle Shuffle
|
||||
Ctrl+h cycle-values hwdec "auto" "no" #menu: Tools > Toggle Hardware Decoding
|
||||
_ script-message mpv.net show-setup-dialog #menu: Tools > OS Setup...
|
||||
|
||||
_ script-message mpv.net shell-execute https://mpv.io/manual/stable/ #menu: Help > Show mpv manual
|
||||
_ script-message mpv.net shell-execute https://github.com/mpv-player/mpv/blob/master/etc/input.conf #menu: Help > Show mpv default keys
|
||||
_ script-message mpv.net shell-execute https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/inputConf.txt #menu: Help > Show mpv.net default keys
|
||||
_ script-message mpv.net shell-execute https://mpv-net.github.io/mpv.net-web-site/ #menu: Help > Show mpv.net web site
|
||||
_ ignore #menu: Help > -
|
||||
_ script-message mpv.net show-about #menu: Help > About mpv.net
|
||||
_ script-message mpv.net shell-execute https://mpv.io #menu: Help > Website mpv
|
||||
_ script-message mpv.net shell-execute https://github.com/stax76/mpv.net #menu: Help > Website mpv.net
|
||||
_ ignore #menu: Help > -
|
||||
_ script-message mpv.net shell-execute https://mpv.io/manual/stable/ #menu: Help > Manual mpv
|
||||
_ script-message mpv.net shell-execute https://github.com/stax76/mpv.net/blob/master/Manual.md #menu: Help > Manual mpv.net
|
||||
_ ignore #menu: Help > -
|
||||
_ script-message mpv.net update-check #menu: Help > Check for Updates
|
||||
_ script-message mpv.net show-about #menu: Help > About mpv.net
|
||||
|
||||
_ ignore #menu: -
|
||||
Esc quit #menu: Exit
|
||||
Q quit-watch-later #menu: Exit Watch Later
|
||||
|
||||
> playlist-next
|
||||
< playlist-prev
|
||||
Power quit
|
||||
Play cycle pause
|
||||
Pause cycle pause
|
||||
PlayPause cycle pause
|
||||
Stop stop
|
||||
Forward seek 60
|
||||
Rewind seek -60
|
||||
Mute cycle mute
|
||||
Volume_Up add volume 10
|
||||
Volume_Down add volume -10
|
||||
Wheel_Up add volume 10
|
||||
Wheel_Down add volume -10
|
||||
Prev playlist-prev
|
||||
Next playlist-next
|
||||
|
||||
MBTN_LEFT_DBL cycle fullscreen
|
||||
Power quit
|
||||
Play cycle pause
|
||||
Pause cycle pause
|
||||
PlayPause cycle pause
|
||||
MBTN_Mid cycle pause
|
||||
Stop stop
|
||||
Forward seek 60
|
||||
Rewind seek -60
|
||||
Mute cycle mute
|
||||
Volume_Up add volume 10
|
||||
Volume_Down add volume -10
|
||||
Wheel_Up add volume 10
|
||||
Wheel_Down add volume -10
|
||||
Prev playlist-prev
|
||||
Next playlist-next
|
||||
MBTN_Forward playlist-next
|
||||
MBTN_Back playlist-prev
|
||||
> playlist-next
|
||||
< playlist-prev
|
||||
Ctrl+Wheel_Up no-osd seek 7
|
||||
Ctrl+Wheel_Down no-osd seek -7
|
||||
MBTN_Left_DBL cycle fullscreen
|
||||
KP_Enter cycle fullscreen
|
||||
@@ -1,25 +0,0 @@
|
||||
|
||||
# This file defines the input (keys and mouse) bindings of mpv and mpv.net
|
||||
# and it also defines the context menu of mpv.net. mpv.net has an input
|
||||
# editor and an config editor as alternatives to editing conf text files.
|
||||
# The input and config editor can be found in mpv.net's context menu at:
|
||||
|
||||
# Settings > Show Config Editor
|
||||
# Settings > Show Input Editor
|
||||
|
||||
# The defaults of this file can be found at:
|
||||
|
||||
# https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/inputConf.txt
|
||||
|
||||
# the defaults of mpv can be found at:
|
||||
|
||||
# https://github.com/mpv-player/mpv/blob/master/etc/inputConf
|
||||
|
||||
# mpv.net's defaults of mpv.conf contain: 'input-default-bindings = no'
|
||||
# which disables mpv's input defaults. Every line in this file begins with a
|
||||
# space character to make it easier to do a text search, so if you want to know
|
||||
# if 'o' has already a binding you can make a text search on ' o '.
|
||||
|
||||
# mpv input commands: https://github.com/stax76/mpv.net/wiki/mpv-input-commands
|
||||
|
||||
# mpv input keys: https://github.com/stax76/mpv.net/wiki/mpv-input-keys
|
||||
@@ -1,14 +1,15 @@
|
||||
|
||||
# mpv manual: https://mpv.io/manual/master/
|
||||
|
||||
# mpv.net mpv.conf defaults: https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/mpvConf.txt
|
||||
|
||||
input-default-bindings = no
|
||||
input-ar-delay = 500
|
||||
input-ar-rate = 20
|
||||
volume = 50
|
||||
hwdec = yes
|
||||
keep-open = yes
|
||||
keep-open-pause = no
|
||||
osd-playing-msg = ${filename}
|
||||
screenshot-directory = ~~desktop/
|
||||
input-default-bindings = no
|
||||
osd-playing-msg = '${filename}'
|
||||
script-opts = osc-scalewindowed=1.5
|
||||
screenshot-directory = '~~desktop/'
|
||||
cscale = spline36
|
||||
dscale = spline36
|
||||
scale = spline36
|
||||
hwdec = yes
|
||||
|
||||
[protocol.https]
|
||||
osd-playing-msg = '${media-title}'
|
||||
@@ -1,282 +0,0 @@
|
||||
[[settings]]
|
||||
name = "hwdec"
|
||||
default = "no"
|
||||
filter = "Video"
|
||||
helpurl = "https://mpv.io/manual/master/#options-hwdec"
|
||||
help = "--hwdec=<mode> Specify the hardware video decoding API that should be used if possible. Whether hardware decoding is actually done depends on the video codec. If hardware decoding is not possible, mpv will fall back on software decoding.\n\nFor more information visit:"
|
||||
options = [{ name = "no", help = "always use software decoding (Default)" },
|
||||
{ name = "auto", help = "enable best hw decoder (see below)" },
|
||||
{ name = "yes", help = "exactly the same as auto" },
|
||||
{ name = "auto-copy", help = "enable best hw decoder with copy-back (see below)" },
|
||||
{ name = "dxva2", help = "requires --vo=gpu with --gpu-context=d3d11, --gpu-context=angle or --gpu-context=dxinterop (Windows only)" },
|
||||
{ name = "dxva2-copy", help = "copies video back to system RAM (Windows only)" },
|
||||
{ name = "d3d11va", help = "requires --vo=gpu with --gpu-context=d3d11 or --gpu-context=angle (Windows 8+ only)" },
|
||||
{ name = "d3d11va-copy", help = "copies video back to system RAM (Windows 8+ only)" },
|
||||
{ name = "cuda", help = "requires --vo=gpu (Any platform CUDA is available)" },
|
||||
{ name = "cuda-copy", help = "copies video back to system RAM (Any platform CUDA is available)" },
|
||||
{ name = "nvdec", help = "requires --vo=gpu (Any platform CUDA is available)" },
|
||||
{ name = "nvdec-copy", help = "copies video back to system RAM (Any platform CUDA is available)" },
|
||||
{ name = "crystalhd", help = "copies video back to system RAM (Any platform supported by hardware)" },
|
||||
{ name = "rkmpp", help = "requires --vo=gpu (some RockChip devices only)" }]
|
||||
|
||||
[[settings]]
|
||||
name = "gpu-api"
|
||||
default = "auto"
|
||||
filter = "Video"
|
||||
help = "--gpu-api=<type> Controls which type of graphics APIs will be accepted."
|
||||
options = [{ name = "auto", help = "Use any available API (Default)" },
|
||||
{ name = "opengl", help = "Allow only OpenGL (requires OpenGL 2.1+ or GLES 2.0+)" },
|
||||
{ name = "vulkan", help = "Allow only Vulkan (requires a valid/working --spirv-compiler)" },
|
||||
{ name = "d3d11", help = "Allow only --gpu-context=d3d11" }]
|
||||
|
||||
[[settings]]
|
||||
name = "gpu-context"
|
||||
default = "auto"
|
||||
filter = "Video"
|
||||
help = "--gpu-context=<sys> The value auto (the default) selects the GPU context. You can also pass help to get a complete list of compiled in backends (sorted by autoprobe order)."
|
||||
options = [{ name = "auto", help = "auto-select (Default)" },
|
||||
{ name = "win", help = "Win32/WGL" },
|
||||
{ name = "winvk", help = "VK_KHR_win32_surface" },
|
||||
{ name = "angle", help = "Direct3D11 through the OpenGL ES translation layer ANGLE. This supports almost everything the win backend does (if the ANGLE build is new enough)." },
|
||||
{ name = "dxinterop", help = "(experimental) Win32, using WGL for rendering and Direct3D 9Ex for presentation. Works on Nvidia and AMD. Newer Intel chips with the latest drivers may also work." },
|
||||
{ name = "d3d11", help = "Win32, with native Direct3D 11 rendering." }]
|
||||
|
||||
[[settings]]
|
||||
name = "vo"
|
||||
default = "gpu"
|
||||
filter = "Video"
|
||||
helpurl = "https://mpv.io/manual/master/#video-output-drivers-vo"
|
||||
help = "--gpu=<mode> Video output drivers to be used. Default = gpu.\n\nFor more information visit:"
|
||||
options = [{ name = "gpu", help = "General purpose, customizable, GPU-accelerated video output driver. It supports extended scaling methods, dithering, color management, custom shaders, HDR, and more. (Default)" },
|
||||
{ name = "direct3d", help = "Video output driver that uses the Direct3D interface" }]
|
||||
|
||||
[[settings]]
|
||||
name = "video-sync"
|
||||
default = "audio"
|
||||
filter = "Video"
|
||||
help = "--video-sync=<audio|...> How the player synchronizes audio and video.\n\nFor more information visit:"
|
||||
helpurl = "https://mpv.io/manual/master/#options-video-sync"
|
||||
options = [{ name = "audio" },
|
||||
{ name = "display-resample" },
|
||||
{ name = "display-resample-vdrop" },
|
||||
{ name = "display-resample-desync" },
|
||||
{ name = "display-vdrop" },
|
||||
{ name = "display-adrop" },
|
||||
{ name = "display-desync" },
|
||||
{ name = "desync" }]
|
||||
|
||||
[[settings]]
|
||||
name = "scale"
|
||||
default = "bilinear"
|
||||
filter = "Video"
|
||||
help = "--scale=<filter> The GPU renderer filter function to use when upscaling video. There are some more filters, but most are not as useful. For a complete list, pass help as value, e.g.: mpv --scale=help"
|
||||
options = [{ name = "bilinear", help = "Bilinear hardware texture filtering (fastest, very low quality). This is the default for compatibility reasons." },
|
||||
{ name = "spline36", help = "Mid quality and speed. This is the default when using gpu-hq." },
|
||||
{ name = "lanczos", help = "Lanczos scaling. Provides mid quality and speed. Generally worse than spline36, but it results in a slightly sharper image which is good for some content types. The number of taps can be controlled with scale-radius, but is best left unchanged. (This filter is an alias for sinc-windowed sinc)" },
|
||||
{ name = "ewa_lanczos", help = "Elliptic weighted average Lanczos scaling. Also known as Jinc. Relatively slow, but very good quality. The radius can be controlled with scale-radius. Increasing the radius makes the filter sharper but adds more ringing. (This filter is an alias for jinc-windowed jinc)" },
|
||||
{ name = "ewa_lanczossharp", help = "A slightly sharpened version of ewa_lanczos, preconfigured to use an ideal radius and parameter. If your hardware can run it, this is probably what you should use by default." },
|
||||
{ name = "mitchell", help = "Mitchell-Netravali. The B and C parameters can be set with --scale-param1 and --scale-param2. This filter is very good at downscaling (see --dscale)." },
|
||||
{ name = "oversample", help = "A version of nearest neighbour that (naively) oversamples pixels, so that pixels overlapping edges get linearly interpolated instead of rounded. This essentially removes the small imperfections and judder artifacts caused by nearest-neighbour interpolation, in exchange for adding some blur. This filter is good at temporal interpolation, and also known as \"smoothmotion\" (see --tscale)." },
|
||||
{ name = "linear", help = "A --tscale filter." }]
|
||||
|
||||
[[settings]]
|
||||
name = "cscale"
|
||||
default = "bilinear"
|
||||
filter = "Video"
|
||||
help = "--cscale=<filter> As --scale, but for interpolating chroma information. If the image is not subsampled, this option is ignored entirely."
|
||||
options = [{ name = "bilinear", help = "Bilinear hardware texture filtering (fastest, very low quality). This is the default for compatibility reasons." },
|
||||
{ name = "spline36", help = "Mid quality and speed. This is the default when using gpu-hq." },
|
||||
{ name = "lanczos", help = "Lanczos scaling. Provides mid quality and speed. Generally worse than spline36, but it results in a slightly sharper image which is good for some content types. The number of taps can be controlled with scale-radius, but is best left unchanged. (This filter is an alias for sinc-windowed sinc)" },
|
||||
{ name = "ewa_lanczos", help = "Elliptic weighted average Lanczos scaling. Also known as Jinc. Relatively slow, but very good quality. The radius can be controlled with scale-radius. Increasing the radius makes the filter sharper but adds more ringing. (This filter is an alias for jinc-windowed jinc)" },
|
||||
{ name = "ewa_lanczossharp", help = "A slightly sharpened version of ewa_lanczos, preconfigured to use an ideal radius and parameter. If your hardware can run it, this is probably what you should use by default." },
|
||||
{ name = "mitchell", help = "Mitchell-Netravali. The B and C parameters can be set with --scale-param1 and --scale-param2. This filter is very good at downscaling (see --dscale)." },
|
||||
{ name = "oversample", help = "A version of nearest neighbour that (naively) oversamples pixels, so that pixels overlapping edges get linearly interpolated instead of rounded. This essentially removes the small imperfections and judder artifacts caused by nearest-neighbour interpolation, in exchange for adding some blur. This filter is good at temporal interpolation, and also known as \"smoothmotion\" (see --tscale)." },
|
||||
{ name = "linear", help = "A --tscale filter." }]
|
||||
|
||||
[[settings]]
|
||||
name = "dscale"
|
||||
default = "bilinear"
|
||||
filter = "Video"
|
||||
help = "--dscale=<filter> Like --scale, but apply these filters on downscaling instead. If this option is unset, the filter implied by --scale will be applied."
|
||||
options = [{ name = "bilinear", help = "Bilinear hardware texture filtering (fastest, very low quality). This is the default for compatibility reasons." },
|
||||
{ name = "spline36", help = "Mid quality and speed. This is the default when using gpu-hq." },
|
||||
{ name = "lanczos", help = "Lanczos scaling. Provides mid quality and speed. Generally worse than spline36, but it results in a slightly sharper image which is good for some content types. The number of taps can be controlled with scale-radius, but is best left unchanged. (This filter is an alias for sinc-windowed sinc)" },
|
||||
{ name = "ewa_lanczos", help = "Elliptic weighted average Lanczos scaling. Also known as Jinc. Relatively slow, but very good quality. The radius can be controlled with scale-radius. Increasing the radius makes the filter sharper but adds more ringing. (This filter is an alias for jinc-windowed jinc)" },
|
||||
{ name = "ewa_lanczossharp", help = "A slightly sharpened version of ewa_lanczos, preconfigured to use an ideal radius and parameter. If your hardware can run it, this is probably what you should use by default." },
|
||||
{ name = "mitchell", help = "Mitchell-Netravali. The B and C parameters can be set with --scale-param1 and --scale-param2. This filter is very good at downscaling (see --dscale)." },
|
||||
{ name = "oversample", help = "A version of nearest neighbour that (naively) oversamples pixels, so that pixels overlapping edges get linearly interpolated instead of rounded. This essentially removes the small imperfections and judder artifacts caused by nearest-neighbour interpolation, in exchange for adding some blur. This filter is good at temporal interpolation, and also known as \"smoothmotion\" (see --tscale)." },
|
||||
{ name = "linear", help = "A --tscale filter." }]
|
||||
|
||||
[[settings]]
|
||||
name = "dither-depth"
|
||||
default = "no"
|
||||
filter = "Video"
|
||||
help = "--dither-depth=<N|no|auto> Set dither target depth to N. Default: no. Note that the depth of the connected video display device cannot be detected. Often, LCD panels will do dithering on their own, which conflicts with this option and leads to ugly output."
|
||||
options = [{ name = "no", help = "Disable any dithering done by mpv." },
|
||||
{ name = "auto", help = "Automatic selection. If output bit depth cannot be detected, 8 bits per component are assumed." },
|
||||
{ name = "8", help = "Dither to 8 bit output." }]
|
||||
|
||||
[[settings]]
|
||||
name = "correct-downscaling"
|
||||
default = "no"
|
||||
filter = "Video"
|
||||
help = "--correct-downscaling When using convolution based filters, extend the filter size when downscaling. Increases quality, but reduces performance while downscaling.\n\nThis will perform slightly sub-optimally for anamorphic video (but still better than without it) since it will extend the size to match only the milder of the scale factors between the axes."
|
||||
options = [{ name = "yes" },
|
||||
{ name = "no" }]
|
||||
|
||||
[[settings]]
|
||||
name = "sigmoid-upscaling"
|
||||
default = "no"
|
||||
filter = "Video"
|
||||
help = "--sigmoid-upscaling When upscaling, use a sigmoidal color transform to avoid emphasizing ringing artifacts. This also implies --linear-scaling."
|
||||
options = [{ name = "yes" },
|
||||
{ name = "no" }]
|
||||
|
||||
[[settings]]
|
||||
name = "deband"
|
||||
default = "no"
|
||||
filter = "Video"
|
||||
help = "--deband Enable the debanding algorithm. This greatly reduces the amount of visible banding, blocking and other quantization artifacts, at the expense of very slightly blurring some of the finest details. In practice, it's virtually always an improvement - the only reason to disable it would be for performance."
|
||||
options = [{ name = "yes" },
|
||||
{ name = "no" }]
|
||||
|
||||
[[settings]]
|
||||
name = "volume"
|
||||
default = "100"
|
||||
filter = "Audio"
|
||||
help = "--volume=<integer> Set the startup volume. 0 means silence, 100 means no volume reduction or amplification. Negative values can be passed for compatibility, but are treated as 0. Since mpv 0.18.1, this always controls the internal mixer (aka \"softvol\"). Default: 100"
|
||||
|
||||
[[settings]]
|
||||
name = "alang"
|
||||
default = ""
|
||||
filter = "Audio"
|
||||
help = "--alang=<languagecode[,languagecode,...]> Specify a priority list of audio languages to use. Different container formats employ different language codes. DVDs use ISO 639-1 two-letter language codes, Matroska, MPEG-TS and NUT use ISO 639-2 three-letter language codes, while OGM uses a free-form identifier. See also --aid.\n\nExamples\n\nmpv dvd://1 --alang=hu,en chooses the Hungarian language track on a DVD and falls back on English if Hungarian is not available.\n\nmpv --alang=jpn example.mkv plays a Matroska file with Japanese audio."
|
||||
|
||||
[[settings]]
|
||||
name = "audio-file-auto"
|
||||
default = "no"
|
||||
filter = "Audio"
|
||||
help = "--audio-file-auto=<no|exact|fuzzy|all>, --no-audio-file-auto Load additional audio files matching the video filename. The parameter specifies how external audio files are matched."
|
||||
options = [{ name = "no", help = "Don't automatically load external audio files (default)." },
|
||||
{ name = "exact", help = "Load the media filename with audio file extension." },
|
||||
{ name = "fuzzy", help = "Load all audio files containing media filename." },
|
||||
{ name = "all", help = "Load all audio files in the current and --audio-file-paths directories." }]
|
||||
|
||||
[[settings]]
|
||||
name = "slang"
|
||||
default = ""
|
||||
filter = "Subtitle"
|
||||
help = "--slang=<languagecode[,languagecode,...]> Specify a priority list of subtitle languages to use. Different container formats employ different language codes. DVDs use ISO 639-1 two letter language codes, Matroska uses ISO 639-2 three letter language codes while OGM uses a free-form identifier. See also --sid."
|
||||
|
||||
[[settings]]
|
||||
name = "sub-auto"
|
||||
default = "exact"
|
||||
filter = "Subtitle"
|
||||
help = "--sub-auto=<no|exact|fuzzy|all>, --no-sub-auto Load additional subtitle files matching the video filename. The parameter specifies how external subtitle files are matched. exact is enabled by default."
|
||||
options = [{ name = "no", help = "Don't automatically load external subtitle files." },
|
||||
{ name = "exact", help = "Load the media filename with subtitle file extension (Default)." },
|
||||
{ name = "fuzzy", help = "Load all subs containing media filename." },
|
||||
{ name = "all", help = "Load all subs in the current and --sub-file-paths directories." }]
|
||||
|
||||
[[settings]]
|
||||
name = "screen"
|
||||
default = ""
|
||||
filter = "Screen"
|
||||
help = "--screen=<default|0-32> In multi-monitor configurations (i.e. a single desktop that spans across multiple displays), this option tells mpv which screen to display the video on. Default: default."
|
||||
|
||||
[[settings]]
|
||||
name = "osd-playing-msg"
|
||||
default = ""
|
||||
width = 300
|
||||
filter = "Screen"
|
||||
help = "--osd-playing-msg=<value> Show a message on OSD when playback starts. The string is expanded for properties, e.g. --osd-playing-msg='file: ${filename}' will show the message file: followed by a space and the currently played filename. For more information visit:"
|
||||
helpurl = "https://mpv.io/manual/master/#property-expansion"
|
||||
|
||||
[[settings]]
|
||||
name = "fullscreen"
|
||||
default = "no"
|
||||
filter = "Screen"
|
||||
help = "--fullscreen=<yes|no>, fs=<yes|no> Start the player in fullscreen mode. Default: no."
|
||||
options = [{ name = "yes" },
|
||||
{ name = "no" }]
|
||||
|
||||
[[settings]]
|
||||
name = "screenshot-directory"
|
||||
default = ""
|
||||
width = 500
|
||||
folder = true
|
||||
filter = "Screen"
|
||||
help = "--screenshot-directory=<value> Store screenshots in this directory. This path is joined with the filename generated by --screenshot-template. If the template filename is already absolute, the directory is ignored.\n\nIf the directory does not exist, it is created on the first screenshot. If it is not a directory, an error is generated when trying to write a screenshot.\n\nThis option is not set by default, and thus will write screenshots to the directory from which mpv was started. In pseudo-gui mode (see PSEUDO GUI MODE), this is set to the desktop."
|
||||
|
||||
[[settings]]
|
||||
name = "autofit"
|
||||
default = "50%"
|
||||
filter = "Screen"
|
||||
help = "--autofit=<percent value> Set the initial window size in percent. Please note that this setting is only partly implemented in mpv.net, accepted are only integer values with percent sign added. Default: 50%."
|
||||
|
||||
[[settings]]
|
||||
name = "keep-open-pause"
|
||||
default = "yes"
|
||||
filter = "Playback"
|
||||
help = "--keep-open-pause=<yes|no> If set to no, instead of pausing when --keep-open is active, just stop at end of file and continue playing forward when you seek backwards until end where it stops again. Default: yes."
|
||||
options = [{ name = "yes" },
|
||||
{ name = "no" }]
|
||||
|
||||
[[settings]]
|
||||
name = "keep-open"
|
||||
default = "no"
|
||||
filter = "Playback"
|
||||
help = "--keep-open=<yes|no|always> Do not terminate when playing or seeking beyond the end of the file, and there is not next file to be played (and --loop is not used). Instead, pause the player. When trying to seek beyond end of the file, the player will attempt to seek to the last frame.\n\nNormally, this will act like set pause yes on EOF, unless the --keep-open-pause=no option is set."
|
||||
options = [{ name = "yes", help = "Don't terminate if the current file is the last playlist entry. Equivalent to --keep-open without arguments."},
|
||||
{ name = "no", help = "If the current file ends, go to the next file or terminate. (Default.)" },
|
||||
{ name = "always", help = "Like yes, but also applies to files before the last playlist entry. This means playback will never automatically advance to the next file."}]
|
||||
|
||||
[[settings]]
|
||||
name = "loop-file"
|
||||
default = ""
|
||||
filter = "Playback"
|
||||
help = "--loop-file=<N|inf|no>, loop=<N|inf|no> Loop a single file N times. inf means forever, no means normal playback. For compatibility, --loop-file and --loop-file=yes are also accepted, and are the same as --loop-file=inf.\n\nThe difference to --loop-playlist is that this doesn't loop the playlist, just the file itself. If the playlist contains only a single file, the difference between the two option is that this option performs a seek on loop, instead of reloading the file.\n\n--loop is an alias for this option."
|
||||
|
||||
[[settings]]
|
||||
name = "save-position-on-quit"
|
||||
default = "no"
|
||||
filter = "Playback"
|
||||
help = "--save-position-on-quit=<yes|no> Always save the current playback position on quit. When this file is played again later, the player will seek to the old playback position on start. This does not happen if playback of a file is stopped in any other way than quitting. For example, going to the next file in the playlist will not save the position, and start playback at beginning the next time the file is played.\n\nThis behavior is disabled by default, but is always available when quitting the player with Shift+Q."
|
||||
options = [{ name = "yes" },
|
||||
{ name = "no" }]
|
||||
|
||||
[[settings]]
|
||||
name = "input-ar-delay"
|
||||
default = ""
|
||||
filter = "Input"
|
||||
help = "--input-ar-delay=<integer> Delay in milliseconds before we start to autorepeat a key (0 to disable)."
|
||||
|
||||
[[settings]]
|
||||
name = "input-ar-rate"
|
||||
default = ""
|
||||
filter = "Input"
|
||||
help = "--input-ar-rate=<integer> Number of key presses to generate per second on autorepeat."
|
||||
|
||||
[[settings]]
|
||||
name = "hr-seek"
|
||||
default = "absolute"
|
||||
filter = "Playback"
|
||||
help = "--hr-seek=<no|absolute|yes> Select when to use precise seeks that are not limited to keyframes. Such seeks require decoding video from the previous keyframe up to the target position and so can take some time depending on decoding performance. For some video formats, precise seeks are disabled. This option selects the default choice to use for seeks; it is possible to explicitly override that default in the definition of key bindings and in input commands."
|
||||
options = [{ name = "yes", help = "Use precise seeks whenever possible." },
|
||||
{ name = "no", help = "Never use precise seeks." },
|
||||
{ name = "absolute", help = "Use precise seeks if the seek is to an absolute position in the file, such as a chapter seek, but not for relative seeks like the default behavior of arrow keys (default)." },
|
||||
{ name = "always", help = "Same as yes (for compatibility)." }]
|
||||
|
||||
[[settings]]
|
||||
name = "track-auto-selection"
|
||||
default = "yes"
|
||||
filter = "Playback"
|
||||
help = "--track-auto-selection=<yes|no> Enable the default track auto-selection (default: yes). Enabling this will make the player select streams according to --aid, --alang, and others. If it is disabled, no tracks are selected. In addition, the player will not exit if no tracks are selected, and wait instead (this wait mode is similar to pausing, but the pause option is not set).\n\nThis is useful with --lavfi-complex: you can start playback in this mode, and then set select tracks at runtime by setting the filter graph. Note that if --lavfi-complex is set before playback is started, the referenced tracks are always selected."
|
||||
options = [{ name = "yes" },
|
||||
{ name = "no" }]
|
||||
|
||||
[[settings]]
|
||||
name = "loop-playlist"
|
||||
default = ""
|
||||
filter = "Playback"
|
||||
help = "--loop-playlist=<N|inf|force|no>, --loop-playlist Loops playback N times. A value of 1 plays it one time (default), 2 two times, etc. inf means forever. no is the same as 1 and disables looping. If several files are specified on command line, the entire playlist is looped. --loop-playlist is the same as --loop-playlist=inf.\n\nThe force mode is like inf, but does not skip playlist entries which have been marked as failing. This means the player might waste CPU time trying to loop a file that doesn't exist. But it might be useful for playing webradios under very bad network conditions."
|
||||
@@ -1,8 +0,0 @@
|
||||
[[settings]]
|
||||
name = "dark-mode"
|
||||
default = "always"
|
||||
filter = "mpv.net"
|
||||
help = "Enables a dark theme."
|
||||
options = [{ name = "always" },
|
||||
{ name = "system" , help = "Available on Windows 10 or higher" },
|
||||
{ name = "never" }]
|
||||
BIN
mpv.net/Resources/mpvnet.ico
Normal file
|
After Width: | Height: | Size: 25 KiB |
BIN
mpv.net/Resources/mpvnet.png
Normal file
|
After Width: | Height: | Size: 8.2 KiB |
27
mpv.net/Resources/theme.txt
Normal file
@@ -0,0 +1,27 @@
|
||||
|
||||
[dark]
|
||||
|
||||
heading = #1E90FF
|
||||
foreground = #DDDDDD
|
||||
foreground2 = #AAAAAA
|
||||
background = #323232
|
||||
|
||||
menu-foreground = #DDDDDD
|
||||
menu-background = #323232
|
||||
menu-highlight = #505050
|
||||
menu-border = #FFFFFF
|
||||
menu-checked = #5A5A5A
|
||||
|
||||
|
||||
[light]
|
||||
|
||||
heading = #0068B2
|
||||
foreground = #000000
|
||||
foreground2 = #4C4C4C
|
||||
background = #F7F7F7
|
||||
|
||||
menu-foreground = #000000
|
||||
menu-background = #DFDFDF
|
||||
menu-highlight = #BFBFBF
|
||||
menu-border = #6A6A6A
|
||||
menu-checked = #AAAAAA
|
||||
129
mpv.net/Scripting/PowerShellScript.cs
Normal file
@@ -0,0 +1,129 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using System.Management.Automation.Runspaces;
|
||||
using System.Reflection;
|
||||
using System.Management.Automation;
|
||||
|
||||
namespace mpvnet
|
||||
{
|
||||
public class PowerShellScript
|
||||
{
|
||||
public static void Execute(string filepath, params string[] parameters)
|
||||
{
|
||||
using (Runspace runspace = RunspaceFactory.CreateRunspace())
|
||||
{
|
||||
runspace.ApartmentState = ApartmentState.STA;
|
||||
runspace.Open();
|
||||
|
||||
using (Pipeline pipeline = runspace.CreatePipeline())
|
||||
{
|
||||
pipeline.Commands.AddScript(
|
||||
"Using namespace mpvnet\n" +
|
||||
"Using namespace System\n" +
|
||||
"[System.Reflection.Assembly]::LoadWithPartialName(\"mpvnet\")\n");
|
||||
|
||||
pipeline.Commands.AddScript(File.ReadAllText(filepath));
|
||||
|
||||
if (parameters != null)
|
||||
foreach (string i in parameters)
|
||||
pipeline.Commands[1].Parameters.Add(null, i);
|
||||
|
||||
PowerShellOutput output = new PowerShellOutput();
|
||||
output.ModuleName = Path.GetFileName(filepath);
|
||||
|
||||
pipeline.Output.DataReady += output.Output_DataReady;
|
||||
pipeline.Error.DataReady += output.Error_DataReady;
|
||||
|
||||
runspace.SessionStateProxy.SetVariable("Output", output);
|
||||
|
||||
try {
|
||||
pipeline.Invoke();
|
||||
}
|
||||
catch (RuntimeException e) {
|
||||
Msg.ShowError("PowerShell Exception", e.Message + "\n\n" +
|
||||
e.ErrorRecord.ScriptStackTrace.Replace(" <ScriptBlock>, <No file>", "") +
|
||||
"\n\n" + Path.GetFileName(filepath));
|
||||
}
|
||||
catch (Exception e) {
|
||||
Msg.ShowException(e);
|
||||
}
|
||||
|
||||
pipeline.Output.DataReady -= output.Output_DataReady;
|
||||
pipeline.Error.DataReady -= output.Error_DataReady;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void Init(string filepath)
|
||||
{
|
||||
foreach (var eventInfo in typeof(mp).GetEvents())
|
||||
{
|
||||
if (eventInfo.Name.ToLower() ==
|
||||
Path.GetFileNameWithoutExtension(filepath).ToLower().Replace("-", ""))
|
||||
{
|
||||
PowerShellEventObject eventObject = new PowerShellEventObject();
|
||||
MethodInfo mi;
|
||||
eventObject.Filepath = filepath;
|
||||
|
||||
if (eventInfo.EventHandlerType == typeof(Action))
|
||||
mi = eventObject.GetType().GetMethod(nameof(PowerShellEventObject.Invoke));
|
||||
else if (eventInfo.EventHandlerType == typeof(Action<EndFileEventMode>))
|
||||
mi = eventObject.GetType().GetMethod(nameof(PowerShellEventObject.InvokeEndFile));
|
||||
else if (eventInfo.EventHandlerType == typeof(Action<string[]>))
|
||||
mi = eventObject.GetType().GetMethod(nameof(PowerShellEventObject.InvokeStrings));
|
||||
else
|
||||
throw new Exception();
|
||||
|
||||
eventObject.EventInfo = eventInfo;
|
||||
Delegate handler = Delegate.CreateDelegate(eventInfo.EventHandlerType, eventObject, mi);
|
||||
eventObject.Delegate = handler;
|
||||
eventInfo.AddEventHandler(eventObject, handler);
|
||||
return;
|
||||
}
|
||||
}
|
||||
Execute(filepath);
|
||||
}
|
||||
|
||||
class PowerShellOutput
|
||||
{
|
||||
public string ModuleName { get; set; }
|
||||
|
||||
public bool WriteStandard { get; set; } = true;
|
||||
public bool WriteError { get; set; } = true;
|
||||
|
||||
public void Output_DataReady(object sender, EventArgs e)
|
||||
{
|
||||
if (!WriteStandard)
|
||||
return;
|
||||
|
||||
var output = sender as PipelineReader<PSObject>;
|
||||
|
||||
while (output.Count > 0)
|
||||
Console.WriteLine("[" + ModuleName + "] " + output.Read().ToString());
|
||||
}
|
||||
|
||||
public void Error_DataReady(object sender, EventArgs e)
|
||||
{
|
||||
if (!WriteError)
|
||||
return;
|
||||
|
||||
var output = sender as PipelineReader<Object>;
|
||||
|
||||
while (output.Count > 0)
|
||||
ConsoleHelp.WriteError("[" + ModuleName + "] " + output.Read().ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class PowerShellEventObject
|
||||
{
|
||||
public EventInfo EventInfo { get; set; }
|
||||
public Delegate Delegate { get; set; }
|
||||
public string Filepath { get; set; }
|
||||
|
||||
public void Invoke() => PowerShellScript.Execute(Filepath);
|
||||
public void InvokeEndFile(EndFileEventMode arg) => PowerShellScript.Execute(Filepath, arg.ToString());
|
||||
public void InvokeStrings(string[] args) => PowerShellScript.Execute(Filepath, args);
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
|
||||
using Microsoft.Scripting;
|
||||
@@ -15,7 +16,7 @@ namespace mpvnet
|
||||
ScriptEngine engine;
|
||||
ScriptScope scope;
|
||||
|
||||
public PythonScript(string code)
|
||||
public PythonScript(string scriptPath)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -26,14 +27,14 @@ namespace mpvnet
|
||||
engine.Execute("clr.AddReference(\"mpvnet\")", scope);
|
||||
engine.Execute("import mpvnet", scope);
|
||||
engine.Execute("from mpvnet import *", scope);
|
||||
engine.Execute(code, scope);
|
||||
engine.Execute(File.ReadAllText(scriptPath), scope);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (ex is SyntaxErrorException e)
|
||||
Msg.ShowError($"{e.Line}, {e.Column}: " + ex.Message);
|
||||
Msg.ShowError(e.GetType().Name,$"{e.Line}, {e.Column}: " + e.Message + "\n\n" + Path.GetFileName(scriptPath));
|
||||
else
|
||||
Msg.ShowException(ex);
|
||||
Msg.ShowError(ex.GetType().Name, ex.Message + "\n\n" + Path.GetFileName(scriptPath));
|
||||
}
|
||||
}
|
||||
}
|
||||
23
mpv.net/Update.ps1
Normal file
@@ -0,0 +1,23 @@
|
||||
|
||||
$ErrorActionPreference = 'Stop'
|
||||
$targetDir = (Split-Path $args[1]) + "\new version"
|
||||
$targetFile = $targetDir + '.7z'
|
||||
|
||||
Write-Host 'Download new version' -ForegroundColor Green
|
||||
curl.exe $args[0] --location --output $targetFile
|
||||
if ($LastExitCode) { throw $LastExitCode }
|
||||
|
||||
Write-Host 'Unpack new version' -ForegroundColor Green
|
||||
& ($args[1] + '\7z\7za.exe') x -y $targetFile -o"$targetDir"
|
||||
if ($LastExitCode) { throw $LastExitCode }
|
||||
|
||||
Write-Host 'Delete downloaded file' -ForegroundColor Green
|
||||
Remove-Item $targetFile -Force -Recurse
|
||||
|
||||
Write-Host 'Delete current version' -ForegroundColor Green
|
||||
Remove-Item $args[1] -Force -Recurse
|
||||
|
||||
Write-Host 'Rename directory' -ForegroundColor Green
|
||||
Rename-Item $targetDir (Split-Path $args[1] -Leaf)
|
||||
|
||||
Write-Host 'Update is complete' -ForegroundColor Green
|
||||
@@ -3,14 +3,25 @@
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:UI="clr-namespace:UI"
|
||||
mc:Ignorable="d"
|
||||
Title="About mpv.net" Height="230" Width="420" FontSize="16" ShowInTaskbar="False"
|
||||
WindowStartupLocation="CenterOwner" ResizeMode="NoResize">
|
||||
|
||||
Title="About mpv.net"
|
||||
Height="230"
|
||||
Width="400"
|
||||
FontSize="16"
|
||||
ShowInTaskbar="False"
|
||||
WindowStartupLocation="CenterOwner"
|
||||
ResizeMode="NoResize"
|
||||
Foreground="{x:Static UI:Theme.Foreground}"
|
||||
Background="{x:Static UI:Theme.Background}">
|
||||
|
||||
<Grid>
|
||||
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
|
||||
<TextBlock FontSize="48" HorizontalAlignment="Center" Margin="0,0,0,10">mpv.net</TextBlock>
|
||||
<TextBlock HorizontalAlignment="Center">Copyright (c) 2017-2019 Frank Skare (stax76)</TextBlock>
|
||||
<TextBlock Name="Version" HorizontalAlignment="Center" />
|
||||
<TextBlock Name="mpvVersion" HorizontalAlignment="Center" />
|
||||
<TextBlock HorizontalAlignment="Center" Margin="0,0,0,20">MIT License</TextBlock>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
19
mpv.net/WPF/AboutWindow.xaml.cs
Normal file
@@ -0,0 +1,19 @@
|
||||
using System.IO;
|
||||
using System.Windows;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace mpvnet
|
||||
{
|
||||
public partial class AboutWindow : Window
|
||||
{
|
||||
public AboutWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
Version.Text = $"mpv.net Version {System.Windows.Forms.Application.ProductVersion} ({File.GetLastWriteTime(System.Windows.Forms.Application.ExecutablePath).ToShortDateString()})";
|
||||
mpvVersion.Text = $"{mp.get_property_string("mpv-version")} ({File.GetLastWriteTime(Folder.Startup + "mpv-1.dll").ToShortDateString()})";
|
||||
}
|
||||
|
||||
protected override void OnPreviewKeyDown(KeyEventArgs e) => Close();
|
||||
protected override void OnMouseDown(MouseButtonEventArgs e) => Close();
|
||||
}
|
||||
}
|
||||
@@ -3,21 +3,41 @@
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:UI="clr-namespace:UI"
|
||||
mc:Ignorable="d"
|
||||
Title="Command Palette" Height="295" Width="400" ResizeMode="NoResize"
|
||||
WindowStartupLocation="CenterOwner" Loaded="Window_Loaded" FontSize="13">
|
||||
|
||||
Title="Command Palette"
|
||||
Height="295"
|
||||
Width="400"
|
||||
FontSize="13"
|
||||
ResizeMode="NoResize"
|
||||
WindowStartupLocation="CenterOwner"
|
||||
Loaded="Window_Loaded">
|
||||
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition></RowDefinition>
|
||||
</Grid.RowDefinitions>
|
||||
<TextBox Name="FilterTextBox" PreviewKeyDown="FilterTextBox_PreviewKeyDown" TextChanged="FilterTextBox_TextChanged"></TextBox>
|
||||
<ListView Name="ListView" Grid.Row="1" MouseUp="ListView_MouseUp">
|
||||
|
||||
<TextBox Name="FilterTextBox"
|
||||
Foreground="{x:Static UI:Theme.Foreground}"
|
||||
Background="{x:Static UI:Theme.Background}"
|
||||
PreviewKeyDown="FilterTextBox_PreviewKeyDown"
|
||||
TextChanged="FilterTextBox_TextChanged"/>
|
||||
|
||||
<ListView Name="ListView"
|
||||
Grid.Row="1"
|
||||
Foreground="{x:Static UI:Theme.Foreground}"
|
||||
Background="{x:Static UI:Theme.Background}"
|
||||
MouseUp="ListView_MouseUp">
|
||||
|
||||
<ListView.ItemContainerStyle>
|
||||
<Style TargetType="ListBoxItem">
|
||||
<Setter Property="HorizontalContentAlignment" Value="Stretch"></Setter>
|
||||
</Style>
|
||||
</ListView.ItemContainerStyle>
|
||||
|
||||
<ListView.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<Grid>
|
||||
@@ -25,8 +45,12 @@
|
||||
<ColumnDefinition />
|
||||
<ColumnDefinition />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<TextBlock Text="{Binding Path}"></TextBlock>
|
||||
<TextBlock Grid.Column="1" Text="{Binding Input}" HorizontalAlignment="Right"></TextBlock>
|
||||
|
||||
<TextBlock Grid.Column="1"
|
||||
Text="{Binding Input}"
|
||||
HorizontalAlignment="Right"></TextBlock>
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
</ListView.ItemTemplate>
|
||||
@@ -23,14 +23,6 @@ namespace mpvnet
|
||||
var yourCostumFilter = new Predicate<object>(item => Filter((CommandItem)item));
|
||||
CollectionView.Filter = yourCostumFilter;
|
||||
ListView.ItemsSource = CollectionView;
|
||||
|
||||
if (App.IsDarkMode)
|
||||
{
|
||||
ListView.Foreground = Brushes.White;
|
||||
ListView.Background = Brushes.Black;
|
||||
FilterTextBox.Foreground = Brushes.White;
|
||||
FilterTextBox.Background = Brushes.Black;
|
||||
}
|
||||
}
|
||||
|
||||
bool Filter(CommandItem item)
|
||||
@@ -104,7 +96,7 @@ namespace mpvnet
|
||||
{
|
||||
CommandItem item = ListView.SelectedItem as CommandItem;
|
||||
Close();
|
||||
mp.command_string(item.Command);
|
||||
mp.command(item.Command);
|
||||
}
|
||||
}
|
||||
|
||||
65
mpv.net/WPF/ConfWindow.xaml
Normal file
@@ -0,0 +1,65 @@
|
||||
<Window xmlns:Controls="clr-namespace:Controls" x:Name="ConfWindow1" x:Class="mpvnet.ConfWindow"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:UI="clr-namespace:UI"
|
||||
mc:Ignorable="d"
|
||||
|
||||
Title="Config Editor"
|
||||
Height="530"
|
||||
Width="700"
|
||||
Foreground="{x:Static UI:Theme.Foreground}"
|
||||
Background="{x:Static UI:Theme.Background}"
|
||||
ShowInTaskbar="False"
|
||||
WindowStartupLocation="CenterScreen"
|
||||
Loaded="ConfWindow1_Loaded">
|
||||
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="100" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<Controls:SearchTextBoxUserControl HintText="Find a setting"
|
||||
x:Name="SearchControl"
|
||||
Width="250"
|
||||
Margin="0,20,0,0"
|
||||
Grid.ColumnSpan="2"/>
|
||||
|
||||
<ScrollViewer x:Name="MainScrollViewer"
|
||||
VerticalScrollBarVisibility="Auto"
|
||||
Grid.Row="1"
|
||||
Grid.Column="2"
|
||||
Margin="0,0,0,10">
|
||||
|
||||
<StackPanel x:Name="MainStackPanel"></StackPanel>
|
||||
</ScrollViewer>
|
||||
|
||||
<StackPanel Margin="20,0,0,0" Grid.Row="1">
|
||||
<ListBox x:Name="FilterListBox"
|
||||
ItemsSource="{Binding FilterStrings}"
|
||||
BorderThickness="0"
|
||||
SelectionChanged="FilterListBox_SelectionChanged"
|
||||
Foreground="{x:Static UI:Theme.Heading}"
|
||||
Background="{x:Static UI:Theme.Background}">
|
||||
|
||||
<ListBox.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock Text="{Binding}" FontSize="16" />
|
||||
</DataTemplate>
|
||||
</ListBox.ItemTemplate>
|
||||
</ListBox>
|
||||
|
||||
<TextBlock x:Name="OpenSettingsTextBlock" Margin="0,30,0,0" Cursor="Hand" TextWrapping="WrapWithOverflow" Foreground="{x:Static UI:Theme.Heading}" MouseUp="OpenSettingsTextBlock_MouseUp">Open config folder</TextBlock>
|
||||
<TextBlock x:Name="PreviewTextBlock" Margin="0,15,0,0" Cursor="Hand" TextWrapping="WrapWithOverflow" Foreground="{x:Static UI:Theme.Heading}" MouseUp="PreviewTextBlock_MouseUp">Preview mpv.conf</TextBlock>
|
||||
<TextBlock x:Name="ShowManualTextBlock" Margin="0,15,0,0" Cursor="Hand" TextWrapping="WrapWithOverflow" Foreground="{x:Static UI:Theme.Heading}" MouseUp="ShowManualTextBlock_MouseUp">Show mpv manual</TextBlock>
|
||||
<TextBlock x:Name="SupportTextBlock" Margin="0,15,0,0" Cursor="Hand" TextWrapping="WrapWithOverflow" Foreground="{x:Static UI:Theme.Heading}" MouseUp="SupportTextBlock_MouseUp">Show support forum</TextBlock>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Window>
|
||||
320
mpv.net/WPF/ConfWindow.xaml.cs
Normal file
@@ -0,0 +1,320 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
|
||||
using DynamicGUI;
|
||||
|
||||
namespace mpvnet
|
||||
{
|
||||
public partial class ConfWindow : Window
|
||||
{
|
||||
List<SettingBase> SettingsDefinitions = Settings.LoadSettings(Properties.Resources.confToml);
|
||||
List<ConfItem> ConfItems = new List<ConfItem>();
|
||||
public ObservableCollection<string> FilterStrings { get; } = new ObservableCollection<string>();
|
||||
string InitialContent;
|
||||
|
||||
public ConfWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
DataContext = this;
|
||||
SearchControl.SearchTextBox.TextChanged += SearchTextBox_TextChanged;
|
||||
LoadConf(mp.ConfPath);
|
||||
LoadConf(App.ConfPath);
|
||||
LoadSettings();
|
||||
InitialContent = GetCompareString();
|
||||
SearchControl.Text = RegistryHelp.GetString(App.RegPath, "ConfigEditorSearch");
|
||||
}
|
||||
|
||||
private void LoadSettings()
|
||||
{
|
||||
foreach (SettingBase setting in SettingsDefinitions)
|
||||
{
|
||||
if (!FilterStrings.Contains(setting.Filter))
|
||||
FilterStrings.Add(setting.Filter);
|
||||
|
||||
foreach (ConfItem confItem in ConfItems)
|
||||
{
|
||||
if (setting.Name == confItem.Name && confItem.Section == "" && !confItem.IsSectionItem)
|
||||
{
|
||||
setting.Value = confItem.Value.Trim('\'', '"');
|
||||
setting.ConfItem = confItem;
|
||||
confItem.SettingBase = setting;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
switch (setting)
|
||||
{
|
||||
case StringSetting s:
|
||||
var sc = new StringSettingControl(s);
|
||||
MainStackPanel.Children.Add(sc);
|
||||
break;
|
||||
case OptionSetting s:
|
||||
var oc = new OptionSettingControl(s);
|
||||
MainStackPanel.Children.Add(oc);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnClosed(EventArgs e)
|
||||
{
|
||||
base.OnClosed(e);
|
||||
RegistryHelp.SetValue(App.RegPath, "ConfigEditorSearch", SearchControl.Text);
|
||||
|
||||
if (InitialContent == GetCompareString())
|
||||
return;
|
||||
|
||||
File.WriteAllText(mp.ConfPath, GetContent("mpv"));
|
||||
File.WriteAllText(App.ConfPath, GetContent("mpvnet"));
|
||||
Msg.Show("Changes will be available on next mpv.net startup.");
|
||||
}
|
||||
|
||||
string GetCompareString()
|
||||
{
|
||||
return string.Join("", SettingsDefinitions.Select(item => item.Name + item.Value).ToArray());
|
||||
}
|
||||
|
||||
void LoadConf(string file)
|
||||
{
|
||||
if (!File.Exists(file))
|
||||
return;
|
||||
|
||||
string comment = "";
|
||||
string section = "";
|
||||
bool isSectionItem = false;
|
||||
|
||||
foreach (string currentLine in File.ReadAllLines(file))
|
||||
{
|
||||
string line = currentLine.Trim();
|
||||
|
||||
if (line == "")
|
||||
{
|
||||
comment += "\r\n";
|
||||
}
|
||||
else if (line.StartsWith("#"))
|
||||
{
|
||||
comment += line.Trim() + "\r\n";
|
||||
}
|
||||
else if (line.StartsWith("[") && line.Contains("]"))
|
||||
{
|
||||
if (!isSectionItem && comment != "" && comment != "\r\n")
|
||||
ConfItems.Add(new ConfItem() {
|
||||
Comment = comment, File = Path.GetFileNameWithoutExtension(file)});
|
||||
|
||||
section = line.Substring(0, line.IndexOf("]") + 1);
|
||||
comment = "";
|
||||
isSectionItem = true;
|
||||
}
|
||||
else if (line.Contains("="))
|
||||
{
|
||||
ConfItem item = new ConfItem();
|
||||
item.File = Path.GetFileNameWithoutExtension(file);
|
||||
item.IsSectionItem = isSectionItem;
|
||||
item.Comment = comment;
|
||||
comment = "";
|
||||
item.Section = section;
|
||||
section = "";
|
||||
|
||||
if (line.Contains("#") && !line.Contains("'") && !line.Contains("\""))
|
||||
{
|
||||
item.LineComment = line.Substring(line.IndexOf("#")).Trim();
|
||||
line = line.Substring(0, line.IndexOf("#")).Trim();
|
||||
}
|
||||
|
||||
int pos = line.IndexOf("=");
|
||||
string left = line.Substring(0, pos).Trim().ToLower();
|
||||
string right = line.Substring(pos + 1).Trim();
|
||||
|
||||
if (left == "fs")
|
||||
left = "fullscreen";
|
||||
|
||||
if (left == "loop")
|
||||
left = "loop-file";
|
||||
|
||||
item.Name = left;
|
||||
item.Value = right;
|
||||
ConfItems.Add(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
string GetContent(string filename)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
List<string> namesWritten = new List<string>();
|
||||
|
||||
foreach (ConfItem item in ConfItems)
|
||||
{
|
||||
if (filename != item.File || item.Section != "" || item.IsSectionItem)
|
||||
continue;
|
||||
|
||||
if (item.Comment != "")
|
||||
sb.Append(item.Comment);
|
||||
|
||||
if (item.SettingBase == null)
|
||||
{
|
||||
if (item.Name != "")
|
||||
{
|
||||
sb.Append(item.Name + " = " + item.Value);
|
||||
|
||||
if (item.LineComment != "")
|
||||
sb.Append(" " + item.LineComment);
|
||||
|
||||
sb.AppendLine();
|
||||
namesWritten.Add(item.Name);
|
||||
}
|
||||
}
|
||||
else if ((item.SettingBase.Value ?? "") != item.SettingBase.Default)
|
||||
{
|
||||
string value = "";
|
||||
|
||||
if (item.SettingBase.Type == "string" ||
|
||||
item.SettingBase.Type == "folder" ||
|
||||
item.SettingBase.Type == "color")
|
||||
|
||||
value = "'" + item.SettingBase.Value + "'";
|
||||
else
|
||||
value = item.SettingBase.Value;
|
||||
|
||||
sb.Append(item.Name + " = " + value);
|
||||
|
||||
if (item.LineComment != "")
|
||||
sb.Append(" " + item.LineComment);
|
||||
|
||||
sb.AppendLine();
|
||||
namesWritten.Add(item.Name);
|
||||
}
|
||||
}
|
||||
|
||||
if (!sb.ToString().Contains("# Editor"))
|
||||
sb.AppendLine("# Editor");
|
||||
|
||||
foreach (SettingBase setting in SettingsDefinitions)
|
||||
{
|
||||
if (filename != setting.File || namesWritten.Contains(setting.Name))
|
||||
continue;
|
||||
|
||||
if ((setting.Value ?? "") != setting.Default)
|
||||
{
|
||||
string value = "";
|
||||
|
||||
if (setting.Type == "string" ||
|
||||
setting.Type == "folder" ||
|
||||
setting.Type == "color")
|
||||
|
||||
value = "'" + setting.Value + "'";
|
||||
else
|
||||
value = setting.Value;
|
||||
|
||||
sb.AppendLine(setting.Name + " = " + value);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (ConfItem item in ConfItems)
|
||||
{
|
||||
if (filename != item.File || (item.Section == "" && !item.IsSectionItem))
|
||||
continue;
|
||||
|
||||
if (item.Section != "")
|
||||
{
|
||||
if (!sb.ToString().EndsWith("\r\n\r\n"))
|
||||
sb.AppendLine();
|
||||
|
||||
sb.AppendLine(item.Section);
|
||||
}
|
||||
|
||||
if (item.Comment != "")
|
||||
sb.Append(item.Comment);
|
||||
|
||||
sb.Append(item.Name + " = " + item.Value);
|
||||
|
||||
if (item.LineComment != "")
|
||||
sb.Append(" " + item.LineComment);
|
||||
|
||||
sb.AppendLine();
|
||||
namesWritten.Add(item.Name);
|
||||
}
|
||||
|
||||
return "\r\n" + sb.ToString().Trim() + "\r\n";
|
||||
}
|
||||
|
||||
private void SearchTextBox_TextChanged(object sender, TextChangedEventArgs e)
|
||||
{
|
||||
string activeFilter = "";
|
||||
|
||||
foreach (var i in FilterStrings)
|
||||
if (SearchControl.Text == i + ":")
|
||||
activeFilter = i;
|
||||
|
||||
if (activeFilter == "")
|
||||
{
|
||||
foreach (UIElement i in MainStackPanel.Children)
|
||||
if ((i as ISettingControl).Contains(SearchControl.Text))
|
||||
i.Visibility = Visibility.Visible;
|
||||
else
|
||||
i.Visibility = Visibility.Collapsed;
|
||||
|
||||
FilterListBox.SelectedItem = null;
|
||||
}
|
||||
else
|
||||
foreach (UIElement i in MainStackPanel.Children)
|
||||
if ((i as ISettingControl).SettingBase.Filter == activeFilter)
|
||||
i.Visibility = Visibility.Visible;
|
||||
else
|
||||
i.Visibility = Visibility.Collapsed;
|
||||
|
||||
MainScrollViewer.ScrollToTop();
|
||||
}
|
||||
|
||||
private void ConfWindow1_Loaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
SearchControl.SearchTextBox.SelectAll();
|
||||
Keyboard.Focus(SearchControl.SearchTextBox);
|
||||
|
||||
foreach (var i in MainStackPanel.Children.OfType<StringSettingControl>())
|
||||
i.Update();
|
||||
}
|
||||
|
||||
private void FilterListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||
{
|
||||
if (e.AddedItems.Count > 0) SearchControl.Text = e.AddedItems[0] + ":";
|
||||
}
|
||||
|
||||
private void OpenSettingsTextBlock_MouseUp(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
Process.Start(Path.GetDirectoryName(mp.ConfPath));
|
||||
}
|
||||
|
||||
private void PreviewTextBlock_MouseUp(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
Msg.Show("mpv.conf Preview", GetContent("mpv"));
|
||||
}
|
||||
|
||||
private void ShowManualTextBlock_MouseUp(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
Process.Start("https://mpv.io/manual/master/");
|
||||
}
|
||||
|
||||
private void SupportTextBlock_MouseUp(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
Process.Start("https://github.com/stax76/mpv.net#Support");
|
||||
}
|
||||
|
||||
protected override void OnKeyDown(KeyEventArgs e)
|
||||
{
|
||||
base.OnKeyDown(e);
|
||||
|
||||
if (e.Key == Key.Escape)
|
||||
Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
44
mpv.net/WPF/EverythingWindow.xaml
Normal file
@@ -0,0 +1,44 @@
|
||||
<Window x:Class="mpvnet.EverythingWindow"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:UI="clr-namespace:UI"
|
||||
mc:Ignorable="d"
|
||||
|
||||
Title="Media File Search"
|
||||
FontSize="13"
|
||||
Height="300"
|
||||
Width="600"
|
||||
ResizeMode="NoResize"
|
||||
WindowStartupLocation="CenterOwner"
|
||||
Loaded="Window_Loaded">
|
||||
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition></RowDefinition>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<TextBox Name="FilterTextBox"
|
||||
Foreground="{x:Static UI:Theme.Foreground}"
|
||||
Background="{x:Static UI:Theme.Background}"
|
||||
PreviewKeyDown="FilterTextBox_PreviewKeyDown"
|
||||
TextChanged="FilterTextBox_TextChanged"/>
|
||||
|
||||
<ListView Name="ListView"
|
||||
Foreground="{x:Static UI:Theme.Foreground}"
|
||||
Background="{x:Static UI:Theme.Background}"
|
||||
Grid.Row="1"
|
||||
MouseUp="ListView_MouseUp"
|
||||
PreviewKeyDown="ListView_PreviewKeyDown">
|
||||
|
||||
<ListView.ItemContainerStyle>
|
||||
<Style TargetType="ListBoxItem">
|
||||
<Setter Property="HorizontalContentAlignment" Value="Stretch"></Setter>
|
||||
</Style>
|
||||
</ListView.ItemContainerStyle>
|
||||
|
||||
</ListView>
|
||||
</Grid>
|
||||
</Window>
|
||||
@@ -1,6 +1,6 @@
|
||||
using System;
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
@@ -9,7 +9,6 @@ using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Interop;
|
||||
using System.Windows.Media;
|
||||
|
||||
namespace mpvnet
|
||||
{
|
||||
@@ -18,19 +17,10 @@ namespace mpvnet
|
||||
public EverythingWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
if (App.IsDarkMode)
|
||||
{
|
||||
ListView.Foreground = Brushes.White;
|
||||
ListView.Background = Brushes.Black;
|
||||
FilterTextBox.Foreground = Brushes.White;
|
||||
FilterTextBox.Background = Brushes.Black;
|
||||
}
|
||||
}
|
||||
|
||||
const int EVERYTHING_REQUEST_FILE_NAME = 0x00000001;
|
||||
const int EVERYTHING_REQUEST_PATH = 0x00000002;
|
||||
const int EVERYTHING_SORT_SIZE_DESCENDING = 6;
|
||||
|
||||
[DllImport("Everything.dll", CharSet = CharSet.Unicode)]
|
||||
public static extern int Everything_SetSearch(string lpSearchString);
|
||||
@@ -70,6 +60,7 @@ namespace mpvnet
|
||||
{
|
||||
if (msg == 0x200 /*WM_MOUSEMOVE*/ && Mouse.LeftButton != MouseButtonState.Pressed)
|
||||
handled = true;
|
||||
|
||||
return IntPtr.Zero;
|
||||
}
|
||||
|
||||
@@ -95,32 +86,29 @@ namespace mpvnet
|
||||
ListView.ScrollIntoView(ListView.SelectedItem);
|
||||
}
|
||||
break;
|
||||
case Key.Escape:
|
||||
Close();
|
||||
break;
|
||||
case Key.Enter:
|
||||
Execute();
|
||||
break;
|
||||
case Key.Escape: Close(); break;
|
||||
case Key.Enter: Execute(); break;
|
||||
}
|
||||
}
|
||||
|
||||
private void ListView_PreviewKeyDown(object sender, KeyEventArgs e)
|
||||
{
|
||||
if (e.Key == Key.Escape) Close();
|
||||
if (e.Key == Key.Enter) Execute();
|
||||
if (e.Key == Key.Escape)
|
||||
Close();
|
||||
|
||||
if (e.Key == Key.Enter)
|
||||
Execute();
|
||||
}
|
||||
|
||||
void Execute()
|
||||
{
|
||||
if (ListView.SelectedItem != null)
|
||||
mp.LoadFiles(ListView.SelectedItem as string);
|
||||
mp.Load(new[] { ListView.SelectedItem as string }, true, Keyboard.Modifiers == ModifierKeys.Control);
|
||||
|
||||
Keyboard.Focus(FilterTextBox);
|
||||
}
|
||||
|
||||
private void ListView_MouseUp(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
Execute();
|
||||
}
|
||||
private void ListView_MouseUp(object sender, MouseButtonEventArgs e) => Execute();
|
||||
|
||||
private void FilterTextBox_TextChanged(object sender, TextChangedEventArgs e)
|
||||
{
|
||||
@@ -142,16 +130,21 @@ namespace mpvnet
|
||||
StringBuilder buf = new StringBuilder(bufsize);
|
||||
Everything_SetSearch(searchtext);
|
||||
Everything_SetRequestFlags(EVERYTHING_REQUEST_FILE_NAME | EVERYTHING_REQUEST_PATH);
|
||||
Everything_SetSort(EVERYTHING_SORT_SIZE_DESCENDING);
|
||||
Everything_Query(true);
|
||||
|
||||
for (i = 0; i < Everything_GetNumResults(); i++)
|
||||
{
|
||||
Everything_GetResultFullPathName(i, buf, bufsize);
|
||||
string ext = Path.GetExtension(buf.ToString()).TrimStart('.').ToLower();
|
||||
if (App.AudioTypes.Contains(ext) || App.VideoTypes.Contains(ext))
|
||||
string ext = buf.ToString().ShortExt();
|
||||
|
||||
if (App.AudioTypes.Contains(ext) || App.VideoTypes.Contains(ext) ||
|
||||
App.ImageTypes.Contains(ext))
|
||||
|
||||
items.Add(buf.ToString());
|
||||
|
||||
if (items.Count > 100) break;
|
||||
}
|
||||
|
||||
Application.Current.Dispatcher.Invoke(() => {
|
||||
ListView.ItemsSource = items;
|
||||
SelectFirst();
|
||||
@@ -3,9 +3,19 @@
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:UI="clr-namespace:UI"
|
||||
mc:Ignorable="d"
|
||||
Title="Input Editor" Height="500" Width="750" FontSize="13"
|
||||
Loaded="Window_Loaded" Closed="Window_Closed" ShowInTaskbar="False">
|
||||
|
||||
Title="Input Editor"
|
||||
Height="500"
|
||||
Width="750"
|
||||
FontSize="13"
|
||||
ShowInTaskbar="False"
|
||||
Foreground="{x:Static UI:Theme.Foreground}"
|
||||
Background="{x:Static UI:Theme.Background}"
|
||||
Loaded="Window_Loaded"
|
||||
Closed="Window_Closed">
|
||||
|
||||
<Window.Resources>
|
||||
<Style x:Key="DataGrid_Font_Centering" TargetType="{x:Type DataGridCell}">
|
||||
<Setter Property="Template">
|
||||
@@ -19,15 +29,29 @@
|
||||
</Setter>
|
||||
</Style>
|
||||
</Window.Resources>
|
||||
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
<Controls:SearchTextBoxUserControl HintText="Type ? to get help." x:Name="SearchControl" Width="300" Margin="0,20,0,20" Grid.ColumnSpan="2" />
|
||||
<DataGrid Grid.Row="1" x:Name="DataGrid" CommandManager.PreviewCanExecute="DataGrid_PreviewCanExecute" AutoGenerateColumns="False" CellStyle="{StaticResource DataGrid_Font_Centering}">
|
||||
|
||||
<Controls:SearchTextBoxUserControl
|
||||
HintText="Type ? to get help."
|
||||
x:Name="SearchControl"
|
||||
Width="300"
|
||||
Margin="0,20,0,20"
|
||||
Grid.ColumnSpan="2" />
|
||||
|
||||
<DataGrid x:Name="DataGrid"
|
||||
Grid.Row="1"
|
||||
CommandManager.PreviewCanExecute="DataGrid_PreviewCanExecute"
|
||||
AutoGenerateColumns="False"
|
||||
CellStyle="{StaticResource DataGrid_Font_Centering}" >
|
||||
|
||||
<DataGrid.Columns>
|
||||
<DataGridTextColumn Header="Menu" Binding="{Binding Path}"/>
|
||||
|
||||
<DataGridTemplateColumn Header="Input">
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
@@ -37,7 +61,9 @@
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
</DataGridTemplateColumn>
|
||||
|
||||
<DataGridTextColumn Header="Command" Binding="{Binding Command}" MaxWidth="330" />
|
||||
|
||||
</DataGrid.Columns>
|
||||
</DataGrid>
|
||||
</Grid>
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.IO;
|
||||
@@ -6,7 +7,6 @@ using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
|
||||
namespace mpvnet
|
||||
{
|
||||
@@ -26,38 +26,28 @@ namespace mpvnet
|
||||
var yourCostumFilter = new Predicate<object>(item => Filter((CommandItem)item));
|
||||
CollectionView.Filter = yourCostumFilter;
|
||||
DataGrid.ItemsSource = CollectionView;
|
||||
|
||||
if (App.IsDarkMode)
|
||||
{
|
||||
Foreground = Brushes.White;
|
||||
Foreground2 = Brushes.Silver;
|
||||
Background = Brushes.Black;
|
||||
}
|
||||
}
|
||||
|
||||
public Brush Foreground2 {
|
||||
get { return (Brush)GetValue(Foreground2Property); }
|
||||
set { SetValue(Foreground2Property, value); }
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty Foreground2Property =
|
||||
DependencyProperty.Register("Foreground2", typeof(Brush), typeof(InputWindow), new PropertyMetadata(Brushes.DarkSlateGray));
|
||||
|
||||
private void SearchTextBox_TextChanged(object sender, TextChangedEventArgs e)
|
||||
{
|
||||
CollectionView.Refresh();
|
||||
|
||||
if (SearchControl.SearchTextBox.Text == "?")
|
||||
Msg.Show("Filtering works by searching in the Input, Menu and Command but it's possible to reduce the filter scope to either of Input, Menu or Command by prefixing as follows:\n\ni <input search>\ni: <input search>\n\nm <menu search>\nm: <menu search>\n\nc <command search>\nc: <command search>\n\nIf only one character is entered the search will be performed only in the input.", "Filtering");
|
||||
{
|
||||
SearchControl.SearchTextBox.Text = "";
|
||||
Msg.Show("Filtering", "Reduce the filter scope with:\n\ni input\n\nm menu\n\nc command\n\nIf only one character is entered input search is performed.");
|
||||
}
|
||||
}
|
||||
|
||||
bool Filter(CommandItem item)
|
||||
{
|
||||
if (item.Command == "") return false;
|
||||
string searchText = SearchControl.SearchTextBox.Text.ToLower();
|
||||
if (searchText == "") return true;
|
||||
if (searchText == "" || searchText == "?") return true;
|
||||
|
||||
if (searchText.StartsWith("i ") || searchText.StartsWith("i:") || searchText.Length == 1)
|
||||
if (searchText.Length == 1)
|
||||
return item.Input.ToLower().Replace("ctrl+", "").Replace("shift+", "").Replace("alt+", "") == searchText.ToLower();
|
||||
else if (searchText.StartsWith("i ") || searchText.StartsWith("i:") || searchText.Length == 1)
|
||||
{
|
||||
if (searchText.Length > 1)
|
||||
searchText = searchText.Substring(2).Trim();
|
||||
@@ -102,7 +92,15 @@ namespace mpvnet
|
||||
|
||||
string GetInputConfContent()
|
||||
{
|
||||
string text = Properties.Resources.inputConfHeader + "\r\n";
|
||||
string text = null;
|
||||
|
||||
foreach (string line in Properties.Resources.inputConf.Split(new[] { "\r\n" }, StringSplitOptions.None))
|
||||
{
|
||||
string test = line.Trim();
|
||||
if (test == "" || test.StartsWith("#")) text += test + "\r\n";
|
||||
}
|
||||
|
||||
text = "\r\n" + text.Trim() + "\r\n\r\n";
|
||||
|
||||
foreach (CommandItem item in CommandItem.Items)
|
||||
{
|
||||
50
mpv.net/WPF/LearnWindow.xaml
Normal file
@@ -0,0 +1,50 @@
|
||||
<Window x:Class="mpvnet.LearnWindow"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:UI="clr-namespace:UI"
|
||||
mc:Ignorable="d"
|
||||
|
||||
Title="Learn Input"
|
||||
Height="200"
|
||||
Width="400"
|
||||
WindowStartupLocation="CenterOwner"
|
||||
ResizeMode="NoResize"
|
||||
Loaded="Window_Loaded"
|
||||
Foreground="{x:Static UI:Theme.Foreground}"
|
||||
Background="{x:Static UI:Theme.Background}"
|
||||
MouseWheel="Window_MouseWheel"
|
||||
MouseUp="Window_MouseUp"
|
||||
MouseDoubleClick="Window_MouseDoubleClick"
|
||||
TextInput="Window_TextInput">
|
||||
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="40" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<TextBlock x:Name="MenuTextBlock"
|
||||
Grid.ColumnSpan="2"
|
||||
VerticalAlignment="Center"
|
||||
HorizontalAlignment="Center"
|
||||
FontSize="16"></TextBlock>
|
||||
|
||||
<TextBlock x:Name="KeyTextBlock"
|
||||
Grid.Row="1"
|
||||
Grid.ColumnSpan="2"
|
||||
VerticalAlignment="Top"
|
||||
HorizontalAlignment="Center"
|
||||
FontSize="16" />
|
||||
|
||||
<Button x:Name="ConfirmButton" Grid.Row="2" Click="ConfirmButton_Click">Confirm</Button>
|
||||
<Button x:Name="ClearButton" Grid.Row="2" Click="ClearButton_Click" Grid.Column="1">Clear</Button>
|
||||
</Grid>
|
||||
</Window>
|
||||
385
mpv.net/WPF/LearnWindow.xaml.cs
Normal file
@@ -0,0 +1,385 @@
|
||||
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Windows;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Interop;
|
||||
|
||||
using WinForms = System.Windows.Forms;
|
||||
|
||||
namespace mpvnet
|
||||
{
|
||||
public partial class LearnWindow : Window
|
||||
{
|
||||
public CommandItem InputItem { get; set; }
|
||||
string NewKey = "";
|
||||
string KeyChar = "";
|
||||
|
||||
public LearnWindow() => InitializeComponent();
|
||||
|
||||
private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
|
||||
{
|
||||
WinForms.Message m = new WinForms.Message();
|
||||
m.HWnd = hwnd;
|
||||
m.Msg = msg;
|
||||
m.WParam = wParam;
|
||||
m.LParam = lParam;
|
||||
ProcessKeyEventArgs(ref m);
|
||||
return m.Result;
|
||||
}
|
||||
|
||||
void OnKeyUp(WinForms.KeyEventArgs e)
|
||||
{
|
||||
if (e.KeyCode == WinForms.Keys.ControlKey || e.KeyCode == WinForms.Keys.ShiftKey ||
|
||||
e.KeyCode == WinForms.Keys.Menu || e.KeyCode == WinForms.Keys.None)
|
||||
|
||||
return;
|
||||
|
||||
string text = "";
|
||||
uint charValue = MapVirtualKey((uint)e.KeyCode, 2);
|
||||
|
||||
if (charValue == 0 || (charValue & 1 << 31) == 1 << 31)
|
||||
text = e.KeyCode.ToString().Trim();
|
||||
else
|
||||
try {
|
||||
text = Convert.ToChar(charValue).ToString().ToLower().Trim();
|
||||
} catch {}
|
||||
|
||||
for (int i = 0; i < 13; i++)
|
||||
if ("D" + i == text)
|
||||
text = text.Substring(1);
|
||||
|
||||
switch (e.KeyCode)
|
||||
{
|
||||
case WinForms.Keys.NumPad0:
|
||||
case WinForms.Keys.NumPad1:
|
||||
case WinForms.Keys.NumPad2:
|
||||
case WinForms.Keys.NumPad3:
|
||||
case WinForms.Keys.NumPad4:
|
||||
case WinForms.Keys.NumPad5:
|
||||
case WinForms.Keys.NumPad6:
|
||||
case WinForms.Keys.NumPad7:
|
||||
case WinForms.Keys.NumPad8:
|
||||
case WinForms.Keys.NumPad9:
|
||||
text = "KP" + e.KeyCode.ToString()[6]; break;
|
||||
case WinForms.Keys.Space:
|
||||
text = "Space"; break;
|
||||
case WinForms.Keys.Enter:
|
||||
text = "Enter"; break;
|
||||
case WinForms.Keys.Tab:
|
||||
text = "TAB"; break;
|
||||
case WinForms.Keys.Back:
|
||||
text = "BS"; break;
|
||||
case WinForms.Keys.Delete:
|
||||
text = "DEL"; break;
|
||||
case WinForms.Keys.Insert:
|
||||
text = "INS"; break;
|
||||
case WinForms.Keys.Home:
|
||||
text = "Home"; break;
|
||||
case WinForms.Keys.End:
|
||||
text = "END"; break;
|
||||
case WinForms.Keys.PageUp:
|
||||
text = "PGUP"; break;
|
||||
case WinForms.Keys.PageDown:
|
||||
text = "PGDWN"; break;
|
||||
case WinForms.Keys.Escape:
|
||||
text = "ESC"; break;
|
||||
case WinForms.Keys.PrintScreen:
|
||||
text = "Print"; break;
|
||||
case WinForms.Keys.Play:
|
||||
text = "Play"; break;
|
||||
case WinForms.Keys.Pause:
|
||||
text = "Pause"; break;
|
||||
case WinForms.Keys.MediaPlayPause:
|
||||
text = "PlayPause"; break;
|
||||
case WinForms.Keys.MediaStop:
|
||||
text = "Stop"; break;
|
||||
case WinForms.Keys.MediaNextTrack:
|
||||
text = "Next"; break;
|
||||
case WinForms.Keys.MediaPreviousTrack:
|
||||
text = "Prev"; break;
|
||||
case WinForms.Keys.VolumeUp:
|
||||
text = "Volume_Up"; break;
|
||||
case WinForms.Keys.VolumeDown:
|
||||
text = "Volume_Down"; break;
|
||||
case WinForms.Keys.VolumeMute:
|
||||
text = "Mute"; break;
|
||||
case WinForms.Keys.BrowserHome:
|
||||
text = "Homepage"; break;
|
||||
case WinForms.Keys.LaunchMail:
|
||||
text = "Mail"; break;
|
||||
case WinForms.Keys.BrowserFavorites:
|
||||
text = "Favorites"; break;
|
||||
case WinForms.Keys.BrowserSearch:
|
||||
text = "Search"; break;
|
||||
case WinForms.Keys.Sleep:
|
||||
text = "Sleep"; break;
|
||||
case WinForms.Keys.Cancel:
|
||||
text = "Cancel"; break;
|
||||
}
|
||||
|
||||
bool wasModified = false;
|
||||
|
||||
bool isAlt = GetKeyState(18) < (short)0;
|
||||
bool isShift = GetKeyState(16) < (short)0;
|
||||
bool isCtrl = GetKeyState(17) < (short)0;
|
||||
|
||||
if (text.Length == 1 && KeyChar != text)
|
||||
{
|
||||
text = KeyChar;
|
||||
wasModified = true;
|
||||
}
|
||||
|
||||
if (text == "#") text = "SHARP";
|
||||
|
||||
if (isAlt && !wasModified)
|
||||
text = "ALT+" + text;
|
||||
|
||||
if (isShift && !wasModified)
|
||||
text = "SHIFT+" + text;
|
||||
|
||||
if (isCtrl && !wasModified)
|
||||
text = "CTRL+" + text;
|
||||
|
||||
if (!string.IsNullOrEmpty(text))
|
||||
SetKey(text);
|
||||
}
|
||||
|
||||
DateTime LastKeyUp;
|
||||
|
||||
void SetKey(string key)
|
||||
{
|
||||
NewKey = key;
|
||||
MenuTextBlock.Text = InputItem.Path;
|
||||
KeyTextBlock.Text = key;
|
||||
LastKeyUp = DateTime.Now;
|
||||
}
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
static extern uint MapVirtualKey(uint uCode, uint uMapType);
|
||||
|
||||
public static WinForms.Keys ModifierKeys {
|
||||
get {
|
||||
WinForms.Keys keys = WinForms.Keys.None;
|
||||
|
||||
if (GetKeyState(17) < (short)0)
|
||||
keys |= WinForms.Keys.Control;
|
||||
|
||||
if (GetKeyState(16) < (short)0)
|
||||
keys |= WinForms.Keys.Shift;
|
||||
|
||||
if (GetKeyState(18) < (short)0)
|
||||
keys |= WinForms.Keys.Alt;
|
||||
|
||||
return keys;
|
||||
}
|
||||
}
|
||||
|
||||
void ProcessKeyEventArgs(ref WinForms.Message m)
|
||||
{
|
||||
int WM_KEYUP = 0x0101, WM_SYSKEYUP = 0x0105, WM_APPCOMMAND = 0x0319;
|
||||
|
||||
if (m.Msg == WM_KEYUP || m.Msg == WM_SYSKEYUP)
|
||||
OnKeyUp(new WinForms.KeyEventArgs((WinForms.Keys)(unchecked((int)(long)m.WParam)) | ModifierKeys));
|
||||
else if (m.Msg == WM_APPCOMMAND)
|
||||
{
|
||||
var value = (AppCommand)(m.LParam.ToInt64() >> 16 & ~0xf000);
|
||||
|
||||
switch (value)
|
||||
{
|
||||
case AppCommand.APPCOMMAND_MEDIA_CHANNEL_DOWN:
|
||||
SetKey("CHANNEL_DOWN");
|
||||
break;
|
||||
case AppCommand.APPCOMMAND_MEDIA_CHANNEL_UP:
|
||||
SetKey("CHANNEL_UP");
|
||||
break;
|
||||
case AppCommand.APPCOMMAND_MEDIA_FAST_FORWARD:
|
||||
SetKey("FORWARD");
|
||||
break;
|
||||
case AppCommand.APPCOMMAND_MEDIA_REWIND:
|
||||
SetKey("REWIND");
|
||||
break;
|
||||
case AppCommand.APPCOMMAND_MEDIA_PAUSE:
|
||||
SetKey("PAUSE");
|
||||
break;
|
||||
case AppCommand.APPCOMMAND_MEDIA_PLAY:
|
||||
SetKey("PLAY");
|
||||
break;
|
||||
case AppCommand.APPCOMMAND_MEDIA_PLAY_PAUSE:
|
||||
SetKey("PLAYPAUSE");
|
||||
break;
|
||||
case AppCommand.APPCOMMAND_MEDIA_NEXTTRACK:
|
||||
SetKey("NEXT");
|
||||
break;
|
||||
case AppCommand.APPCOMMAND_MEDIA_PREVIOUSTRACK:
|
||||
SetKey("PREV");
|
||||
break;
|
||||
case AppCommand.APPCOMMAND_MEDIA_RECORD:
|
||||
SetKey("RECORD");
|
||||
break;
|
||||
case AppCommand.APPCOMMAND_MEDIA_STOP:
|
||||
SetKey("STOP");
|
||||
break;
|
||||
case AppCommand.APPCOMMAND_VOLUME_UP:
|
||||
SetKey("VOLUME_UP");
|
||||
break;
|
||||
case AppCommand.APPCOMMAND_VOLUME_DOWN:
|
||||
SetKey("VOLUME_DOWN");
|
||||
break;
|
||||
case AppCommand.APPCOMMAND_VOLUME_MUTE:
|
||||
SetKey("MUTE");
|
||||
break;
|
||||
case AppCommand.APPCOMMAND_BROWSER_HOME:
|
||||
SetKey("HOMEPAGE");
|
||||
break;
|
||||
case AppCommand.APPCOMMAND_LAUNCH_MAIL:
|
||||
SetKey("MAIL");
|
||||
break;
|
||||
case AppCommand.APPCOMMAND_BROWSER_FAVORITES:
|
||||
SetKey("FAVORITES");
|
||||
break;
|
||||
case AppCommand.APPCOMMAND_BROWSER_SEARCH:
|
||||
SetKey("SEARCH");
|
||||
break;
|
||||
case AppCommand.APPCOMMAND_PRINT:
|
||||
SetKey("PRINT");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal enum AppCommand
|
||||
{
|
||||
APPCOMMAND_BASS_BOOST = 20,
|
||||
APPCOMMAND_BASS_DOWN = 19,
|
||||
APPCOMMAND_BASS_UP = 21,
|
||||
APPCOMMAND_BROWSER_BACKWARD = 1,
|
||||
APPCOMMAND_BROWSER_FAVORITES = 6,
|
||||
APPCOMMAND_BROWSER_FORWARD = 2,
|
||||
APPCOMMAND_BROWSER_HOME = 7,
|
||||
APPCOMMAND_BROWSER_REFRESH = 3,
|
||||
APPCOMMAND_BROWSER_SEARCH = 5,
|
||||
APPCOMMAND_BROWSER_STOP = 4,
|
||||
APPCOMMAND_CLOSE = 31,
|
||||
APPCOMMAND_COPY = 36,
|
||||
APPCOMMAND_CORRECTION_LIST = 45,
|
||||
APPCOMMAND_CUT = 37,
|
||||
APPCOMMAND_DICTATE_OR_COMMAND_CONTROL_TOGGLE = 43,
|
||||
APPCOMMAND_FIND = 28,
|
||||
APPCOMMAND_FORWARD_MAIL = 40,
|
||||
APPCOMMAND_HELP = 27,
|
||||
APPCOMMAND_LAUNCH_APP1 = 17,
|
||||
APPCOMMAND_LAUNCH_APP2 = 18,
|
||||
APPCOMMAND_LAUNCH_MAIL = 15,
|
||||
APPCOMMAND_LAUNCH_MEDIA_SELECT = 16,
|
||||
APPCOMMAND_MEDIA_CHANNEL_DOWN = 52,
|
||||
APPCOMMAND_MEDIA_CHANNEL_UP = 51,
|
||||
APPCOMMAND_MEDIA_FAST_FORWARD = 49,
|
||||
APPCOMMAND_MEDIA_NEXTTRACK = 11,
|
||||
APPCOMMAND_MEDIA_PAUSE = 47,
|
||||
APPCOMMAND_MEDIA_PLAY = 46,
|
||||
APPCOMMAND_MEDIA_PLAY_PAUSE = 14,
|
||||
APPCOMMAND_MEDIA_PREVIOUSTRACK = 12,
|
||||
APPCOMMAND_MEDIA_RECORD = 48,
|
||||
APPCOMMAND_MEDIA_REWIND = 50,
|
||||
APPCOMMAND_MEDIA_STOP = 13,
|
||||
APPCOMMAND_MIC_ON_OFF_TOGGLE = 44,
|
||||
APPCOMMAND_MICROPHONE_VOLUME_DOWN = 25,
|
||||
APPCOMMAND_MICROPHONE_VOLUME_MUTE = 24,
|
||||
APPCOMMAND_MICROPHONE_VOLUME_UP = 26,
|
||||
APPCOMMAND_NEW = 29,
|
||||
APPCOMMAND_OPEN = 30,
|
||||
APPCOMMAND_PASTE = 38,
|
||||
APPCOMMAND_PRINT = 33,
|
||||
APPCOMMAND_REDO = 35,
|
||||
APPCOMMAND_REPLY_TO_MAIL = 39,
|
||||
APPCOMMAND_SAVE = 32,
|
||||
APPCOMMAND_SEND_MAIL = 41,
|
||||
APPCOMMAND_SPELL_CHECK = 42,
|
||||
APPCOMMAND_TREBLE_DOWN = 22,
|
||||
APPCOMMAND_TREBLE_UP = 23,
|
||||
APPCOMMAND_UNDO = 34,
|
||||
APPCOMMAND_VOLUME_DOWN = 9,
|
||||
APPCOMMAND_VOLUME_MUTE = 8,
|
||||
APPCOMMAND_VOLUME_UP = 10
|
||||
}
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Auto)]
|
||||
public static extern short GetKeyState(int keyCode);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
static extern short VkKeyScan(char c);
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
static extern int ToAscii(uint uVirtKey,
|
||||
uint uScanCode,
|
||||
byte[] lpKeyState,
|
||||
out uint lpChar,
|
||||
uint flags);
|
||||
|
||||
private void Window_Loaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
HwndSource source = HwndSource.FromHwnd(new WindowInteropHelper(this).Handle);
|
||||
source.AddHook(new HwndSourceHook(WndProc));
|
||||
SetKey(InputItem.Input);
|
||||
}
|
||||
|
||||
private void ConfirmButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
InputItem.Input = NewKey;
|
||||
Close();
|
||||
}
|
||||
|
||||
private void ClearButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
InputItem.Input = "_";
|
||||
Close();
|
||||
}
|
||||
|
||||
private void Window_MouseWheel(object sender, MouseWheelEventArgs e)
|
||||
{
|
||||
if (e.Delta > 0)
|
||||
SetKey("WHEEL_UP");
|
||||
else
|
||||
SetKey("WHEEL_DOWN");
|
||||
}
|
||||
|
||||
private void Window_MouseUp(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
switch (e.ChangedButton)
|
||||
{
|
||||
case MouseButton.Left:
|
||||
if (BlockMBTN_LEFT)
|
||||
BlockMBTN_LEFT = false;
|
||||
else
|
||||
SetKey("MBTN_LEFT");
|
||||
break;
|
||||
case MouseButton.Middle:
|
||||
SetKey("MBTN_MID");
|
||||
break;
|
||||
case MouseButton.XButton1:
|
||||
SetKey("MBTN_BACK");
|
||||
break;
|
||||
case MouseButton.XButton2:
|
||||
SetKey("MBTN_FORWARD");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool BlockMBTN_LEFT;
|
||||
|
||||
private void Window_MouseDoubleClick(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
if (e.ChangedButton == MouseButton.Left)
|
||||
{
|
||||
SetKey("MBTN_LEFT_DBL");
|
||||
BlockMBTN_LEFT = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void Window_TextInput(object sender, TextCompositionEventArgs e)
|
||||
{
|
||||
KeyChar = e.Text;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,27 +1,120 @@
|
||||
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:WPF="clr-namespace:WPF">
|
||||
xmlns:UI="clr-namespace:UI">
|
||||
|
||||
<Style TargetType="TextBox">
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="{x:Type TextBox}">
|
||||
<Border x:Name="border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
|
||||
<ScrollViewer x:Name="PART_ContentHost" Focusable="false" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden"/>
|
||||
</Border>
|
||||
<ControlTemplate.Triggers>
|
||||
<Trigger Property="IsEnabled" Value="false">
|
||||
<Setter Property="Opacity" TargetName="border" Value="0.56"/>
|
||||
</Trigger>
|
||||
<Trigger Property="IsMouseOver" Value="true">
|
||||
<Setter Property="BorderBrush" TargetName="border" Value="#FF7EB4EA"/>
|
||||
</Trigger>
|
||||
<Trigger Property="IsFocused" Value="true">
|
||||
<Setter Property="BorderBrush" TargetName="border" Value="{x:Static WPF:WPF.ThemeBrush}"/>
|
||||
</Trigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
<Style TargetType="TextBox">
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="{x:Type TextBox}">
|
||||
<Border x:Name="border"
|
||||
BorderBrush="{TemplateBinding BorderBrush}"
|
||||
BorderThickness="{TemplateBinding BorderThickness}"
|
||||
Background="{TemplateBinding Background}"
|
||||
SnapsToDevicePixels="True">
|
||||
|
||||
<ScrollViewer x:Name="PART_ContentHost"
|
||||
Focusable="false"
|
||||
HorizontalScrollBarVisibility="Hidden"
|
||||
VerticalScrollBarVisibility="Hidden"/>
|
||||
</Border>
|
||||
|
||||
<ControlTemplate.Triggers>
|
||||
<Trigger Property="IsEnabled" Value="false">
|
||||
<Setter Property="Opacity" TargetName="border" Value="0.56"/>
|
||||
</Trigger>
|
||||
<Trigger Property="IsMouseOver" Value="true">
|
||||
<Setter Property="BorderBrush" TargetName="border" Value="#FF7EB4EA"/>
|
||||
</Trigger>
|
||||
<Trigger Property="IsFocused" Value="true">
|
||||
<Setter Property="BorderBrush" TargetName="border" Value="{x:Static UI:Theme.Heading}"/>
|
||||
</Trigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
<Style TargetType="RadioButton">
|
||||
<Setter Property="Padding" Value="6 0 0 0" />
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="RadioButton">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition x:Name="LeftCol" Width="18" />
|
||||
<ColumnDefinition x:Name="RightCol" Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<Grid x:Name="PART_CHECKBOX">
|
||||
<Ellipse
|
||||
x:Name="normal"
|
||||
Width="18"
|
||||
Height="18"
|
||||
Fill="{x:Static UI:Theme.Background}"
|
||||
Stroke="{x:Static UI:Theme.Heading}"
|
||||
StrokeThickness="2" />
|
||||
<Ellipse
|
||||
x:Name="Checked1"
|
||||
Width="8"
|
||||
Height="8"
|
||||
Fill="{TemplateBinding Foreground}"
|
||||
Opacity="0" />
|
||||
<Ellipse
|
||||
x:Name="disabled"
|
||||
Width="18"
|
||||
Height="18"
|
||||
Fill="{DynamicResource SemiTransparentWhiteBrush}"
|
||||
Opacity="0"
|
||||
StrokeThickness="{TemplateBinding BorderThickness}" />
|
||||
</Grid>
|
||||
|
||||
<ContentPresenter
|
||||
x:Name="contentPresenter"
|
||||
Grid.Column="1"
|
||||
Margin="{TemplateBinding Padding}"
|
||||
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
|
||||
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
|
||||
Content="{TemplateBinding Content}"
|
||||
ContentStringFormat="{TemplateBinding ContentStringFormat}"
|
||||
ContentTemplate="{TemplateBinding ContentTemplate}"
|
||||
ContentTemplateSelector="{TemplateBinding ContentTemplateSelector}"
|
||||
RecognizesAccessKey="True" />
|
||||
|
||||
<VisualStateManager.VisualStateGroups>
|
||||
<VisualStateGroup x:Name="CommonStates">
|
||||
<VisualState x:Name="Normal" />
|
||||
<VisualState x:Name="Disabled">
|
||||
<Storyboard>
|
||||
<DoubleAnimation
|
||||
Storyboard.TargetName="contentPresenter"
|
||||
Storyboard.TargetProperty="(UIElement.Opacity)"
|
||||
To=".55"
|
||||
Duration="0" />
|
||||
<DoubleAnimation
|
||||
Storyboard.TargetName="disabled"
|
||||
Storyboard.TargetProperty="(UIElement.Opacity)"
|
||||
To="1"
|
||||
Duration="0" />
|
||||
</Storyboard>
|
||||
</VisualState>
|
||||
</VisualStateGroup>
|
||||
<VisualStateGroup x:Name="CheckStates">
|
||||
<VisualState x:Name="Checked">
|
||||
<Storyboard>
|
||||
<DoubleAnimation
|
||||
Storyboard.TargetName="Checked1"
|
||||
Storyboard.TargetProperty="(UIElement.Opacity)"
|
||||
To="1"
|
||||
Duration="0" />
|
||||
</Storyboard>
|
||||
</VisualState>
|
||||
<VisualState x:Name="Unchecked" />
|
||||
<VisualState x:Name="Indeterminate" />
|
||||
</VisualStateGroup>
|
||||
</VisualStateManager.VisualStateGroups>
|
||||
</Grid>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
<Setter Property="VerticalContentAlignment" Value="Center" />
|
||||
</Style>
|
||||
</ResourceDictionary>
|
||||
68
mpv.net/WPF/SearchTextBoxUserControl.xaml
Normal file
@@ -0,0 +1,68 @@
|
||||
<UserControl x:Class="Controls.SearchTextBoxUserControl"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:UI="clr-namespace:UI"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450"
|
||||
d:DesignWidth="800">
|
||||
|
||||
<Grid Name="SearchTextBoxUserControl1"
|
||||
Background="{x:Static UI:Theme.Background}">
|
||||
|
||||
<TextBlock Name="HintTextBlock"
|
||||
Margin="5,2"
|
||||
Text="Find a setting"
|
||||
VerticalAlignment="Center"
|
||||
Foreground="{x:Static UI:Theme.Foreground2}"
|
||||
Background="{x:Static UI:Theme.Background}" />
|
||||
|
||||
<TextBox Name="SearchTextBox"
|
||||
Height="25"
|
||||
Padding="1,2,0,0"
|
||||
BorderThickness="2"
|
||||
Background="Transparent"
|
||||
TextChanged="SearchTextBox_TextChanged"
|
||||
Foreground="{x:Static UI:Theme.Foreground}"
|
||||
CaretBrush="{x:Static UI:Theme.Foreground}" />
|
||||
|
||||
<Button Name="SearchClearButton"
|
||||
Background="Transparent"
|
||||
HorizontalAlignment="Right"
|
||||
FontFamily="Marlett"
|
||||
FontSize="10"
|
||||
Width="17"
|
||||
Height="17"
|
||||
Margin="2,0,4,0"
|
||||
Visibility="Hidden"
|
||||
Click="SearchClearButton_Click" >r
|
||||
|
||||
<Button.Style>
|
||||
<Style TargetType="Button">
|
||||
<Setter Property="Background" Value="{x:Static UI:Theme.Background}"/>
|
||||
<Setter Property="Foreground" Value="{x:Static UI:Theme.Foreground2}"/>
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="Button">
|
||||
<Border BorderThickness="1"
|
||||
BorderBrush="{TemplateBinding Foreground}"
|
||||
SnapsToDevicePixels="True">
|
||||
|
||||
<ContentPresenter HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center" />
|
||||
</Border>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
|
||||
<Style.Triggers>
|
||||
<Trigger Property="IsMouseOver" Value="True">
|
||||
<Setter Property="Foreground" Value="{x:Static UI:Theme.Heading}"/>
|
||||
</Trigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</Button.Style>
|
||||
</Button>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
33
mpv.net/WPF/SetupWindow.xaml
Normal file
@@ -0,0 +1,33 @@
|
||||
<Window x:Class="mpvnet.SetupWindow"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:UI="clr-namespace:UI"
|
||||
mc:Ignorable="d"
|
||||
|
||||
Title="mpv.net OS Setup"
|
||||
FontSize="13"
|
||||
Foreground="{x:Static UI:Theme.Foreground}"
|
||||
Background="{x:Static UI:Theme.Background}"
|
||||
SizeToContent="WidthAndHeight"
|
||||
WindowStartupLocation="CenterOwner" >
|
||||
|
||||
<Window.Resources>
|
||||
<Style TargetType="Button">
|
||||
<Setter Property="Padding" Value="10"></Setter>
|
||||
<Setter Property="Margin" Value="5"></Setter>
|
||||
</Style>
|
||||
</Window.Resources>
|
||||
|
||||
<Grid>
|
||||
<StackPanel Margin="10">
|
||||
<Button Name="RegisterVideo" Click="RegisterVideo_Click">Register video file extensions (requires admin rights)</Button>
|
||||
<Button Name="RegisterAudio" Click="RegisterAudio_Click">Register audio file extensions (requires admin rights)</Button>
|
||||
<Button Name="RegisterImage" Click="RegisterImage_Click">Register image file extensions (requires admin rights)</Button>
|
||||
<Button Name="UnregisterFileAssociations" Click="UnregisterFileAssociations_Click">Unregister file extensions (requires admin rights)</Button>
|
||||
<Button Name="AddToPathEnvVar" Click="AddToPathEnvVar_Click">Add mpv.net to Path environment variable</Button>
|
||||
<Button Name="RemoveFromPathEnvVar" Click="RemoveFromPathEnvVar_Click">Remove mpv.net from Path environment variable</Button>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Window>
|
||||
64
mpv.net/WPF/SetupWindow.xaml.cs
Normal file
@@ -0,0 +1,64 @@
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Windows;
|
||||
|
||||
using WinForms = System.Windows.Forms;
|
||||
|
||||
namespace mpvnet
|
||||
{
|
||||
public partial class SetupWindow : Window
|
||||
{
|
||||
public SetupWindow() => InitializeComponent();
|
||||
|
||||
void RegisterFileAssociations(string value)
|
||||
{
|
||||
try
|
||||
{
|
||||
using (Process proc = new Process())
|
||||
{
|
||||
proc.StartInfo.FileName = WinForms.Application.ExecutablePath;
|
||||
proc.StartInfo.Arguments = "--reg-file-assoc " + value;
|
||||
proc.StartInfo.Verb = "runas";
|
||||
proc.Start();
|
||||
}
|
||||
|
||||
Process.Start("ms-settings:defaultapps");
|
||||
} catch {}
|
||||
}
|
||||
|
||||
private void RegisterVideo_Click(object sender, RoutedEventArgs e) => RegisterFileAssociations("video");
|
||||
private void RegisterAudio_Click(object sender, RoutedEventArgs e) => RegisterFileAssociations("audio");
|
||||
private void RegisterImage_Click(object sender, RoutedEventArgs e) => RegisterFileAssociations("image");
|
||||
|
||||
private void UnregisterFileAssociations_Click(object sender, RoutedEventArgs e) => RegisterFileAssociations("unreg");
|
||||
|
||||
private void AddToPathEnvVar_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
string var = WinForms.Application.StartupPath + ";";
|
||||
string path = Environment.GetEnvironmentVariable("Path", EnvironmentVariableTarget.User);
|
||||
|
||||
if (path.Contains(var))
|
||||
Msg.ShowWarning("Path was already containing mpv.net.");
|
||||
else
|
||||
{
|
||||
Environment.SetEnvironmentVariable("Path", var + path, EnvironmentVariableTarget.User);
|
||||
Msg.Show("mpv.net was successfully added to Path.", (var + path).Replace(";","\n"));
|
||||
}
|
||||
}
|
||||
|
||||
private void RemoveFromPathEnvVar_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
string var = WinForms.Application.StartupPath + ";";
|
||||
string path = Environment.GetEnvironmentVariable("Path", EnvironmentVariableTarget.User);
|
||||
|
||||
if (path.Contains(var))
|
||||
{
|
||||
Environment.SetEnvironmentVariable("Path", path.Replace(var, ""), EnvironmentVariableTarget.User);
|
||||
Msg.Show("mpv.net was successfully removed from Path.");
|
||||
}
|
||||
else
|
||||
Msg.ShowWarning("Path was not containing mpv.net.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,34 +1,20 @@
|
||||
using System;
|
||||
using System.Windows;
|
||||
using System.Windows.Media;
|
||||
|
||||
namespace WPF
|
||||
{
|
||||
public class WPF
|
||||
{
|
||||
public static void Init()
|
||||
{
|
||||
EnsureApplicationResources();
|
||||
}
|
||||
|
||||
public static void EnsureApplicationResources()
|
||||
{
|
||||
if (Application.Current == null)
|
||||
{
|
||||
new Application();
|
||||
|
||||
Application.Current.Resources.MergedDictionaries.Add(
|
||||
Application.LoadComponent(new Uri("mpvnet;component/WPF/Resources.xaml",
|
||||
UriKind.Relative)) as ResourceDictionary);
|
||||
}
|
||||
}
|
||||
|
||||
public static Brush ThemeBrush {
|
||||
get {
|
||||
if (Environment.OSVersion.Version.Major < 10)
|
||||
return new SolidColorBrush(Colors.DarkSlateGray);
|
||||
else
|
||||
return SystemParameters.WindowGlassBrush;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||