Compare commits
85 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e1bd44cd00 | ||
|
|
27d6026213 | ||
|
|
c67d5f10f8 | ||
|
|
5f73be07e8 | ||
|
|
0cad09d2bb | ||
|
|
54b2612bb8 | ||
|
|
82b4d19282 | ||
|
|
23a587c819 | ||
|
|
d69eecd494 | ||
|
|
0d4cc59f9a | ||
|
|
a394536a8c | ||
|
|
ebcd20ceb5 | ||
|
|
964c2f4dd2 | ||
|
|
e985047a54 | ||
|
|
bafc09a948 | ||
|
|
14a172b78b | ||
|
|
2eb324bf41 | ||
|
|
afe9ad5128 | ||
|
|
cc657d4ec2 | ||
|
|
1270dd474e | ||
|
|
e9ea70838d | ||
|
|
e7fde60150 | ||
|
|
2028113d58 | ||
|
|
4d55423fc7 | ||
|
|
d82874409d | ||
|
|
930ba2b0e7 | ||
|
|
4743f365a1 | ||
|
|
194ff5d62b | ||
|
|
5a726a01e0 | ||
|
|
fee13353ec | ||
|
|
cd3543fff4 | ||
|
|
c54f240346 | ||
|
|
7f55ad908a | ||
|
|
d586a82e37 | ||
|
|
722e06a02b | ||
|
|
2f76d2b775 | ||
|
|
7519977124 | ||
|
|
2e65b9ceb8 | ||
|
|
04bffca206 | ||
|
|
ff5a164c69 | ||
|
|
26b391a8d9 | ||
|
|
32eed33c82 | ||
|
|
639893f2e7 | ||
|
|
42b0cc1a64 | ||
|
|
6f7fa6c9d6 | ||
|
|
e6fb775dcd | ||
|
|
ece15ca9bb | ||
|
|
6b3c2788df | ||
|
|
067bdd20d7 | ||
|
|
97ce08c4c7 | ||
|
|
fbb9cbdc33 | ||
|
|
815adca198 | ||
|
|
ce3d5792ad | ||
|
|
74fc0b3ed7 | ||
|
|
604a1e8499 | ||
|
|
56ade0a0d1 | ||
|
|
6294a96aea | ||
|
|
9a95953a04 | ||
|
|
8d9c0c9092 | ||
|
|
e399ca672f | ||
|
|
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 |
27
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
27
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
---
|
||||||
|
name: Bug report
|
||||||
|
about: Create a report to help us improve
|
||||||
|
title: ''
|
||||||
|
labels: bug
|
||||||
|
assignees: stax76
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Describe the bug**
|
||||||
|
A clear and concise description of what the bug is.
|
||||||
|
|
||||||
|
**To Reproduce**
|
||||||
|
Steps to reproduce the behavior:
|
||||||
|
1. Go to '...'
|
||||||
|
2. Click on '....'
|
||||||
|
3. Scroll down to '....'
|
||||||
|
4. See error
|
||||||
|
|
||||||
|
**Expected behavior**
|
||||||
|
A clear and concise description of what you expected to happen.
|
||||||
|
|
||||||
|
**Screenshots**
|
||||||
|
If applicable, add screenshots to help explain your problem.
|
||||||
|
|
||||||
|
**Additional context**
|
||||||
|
Add any other context about the problem here.
|
||||||
20
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
20
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
---
|
||||||
|
name: Feature request
|
||||||
|
about: Suggest an idea for this project
|
||||||
|
title: ''
|
||||||
|
labels: enhancement
|
||||||
|
assignees: stax76
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Is your feature request related to a problem? Please describe.**
|
||||||
|
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||||
|
|
||||||
|
**Describe the solution you'd like**
|
||||||
|
A clear and concise description of what you want to happen.
|
||||||
|
|
||||||
|
**Describe alternatives you've considered**
|
||||||
|
A clear and concise description of any alternative solutions or features you've considered.
|
||||||
|
|
||||||
|
**Additional context**
|
||||||
|
Add any other context or screenshots about the feature request here.
|
||||||
128
Changelog.md
128
Changelog.md
@@ -1,4 +1,115 @@
|
|||||||
|
|
||||||
|
5.4.4.7 Beta (not yet released)
|
||||||
|
============
|
||||||
|
|
||||||
|
-
|
||||||
|
|
||||||
|
|
||||||
|
5.4.4.6 Beta
|
||||||
|
============
|
||||||
|
|
||||||
|
- using start-size=video the window size was not remembered
|
||||||
|
after fullscreen mode was left.
|
||||||
|
- using start-size=video the window can now use the entire
|
||||||
|
working area using autofit-larger=100
|
||||||
|
|
||||||
|
|
||||||
|
5.4.4.5 Beta
|
||||||
|
============
|
||||||
|
|
||||||
|
- overhaul of the [webpage](README.md) and the [manual](Manual.md).
|
||||||
|
- change that possibly could fix a multimedia keyboard volume issue.
|
||||||
|
|
||||||
|
|
||||||
|
5.4.4.4 Beta
|
||||||
|
============
|
||||||
|
|
||||||
|
- with `border=no` the OSC top bar window buttons min, max and close are fully supported.
|
||||||
|
- anamorphic videos are shown without black bars, the window is resized according to the ascpect ratio.
|
||||||
|
- PowerShell 5.1 was made optional.
|
||||||
|
- full implementation for `window-minimized` and `window-maximized`,
|
||||||
|
scripts that depend on this like pause-when-minimize.lua are now fully supported.
|
||||||
|
- fix cycling from maximized to fullscreen and back.
|
||||||
|
|
||||||
|
|
||||||
|
5.4.4.3 Beta
|
||||||
|
============
|
||||||
|
|
||||||
|
- update MediaInfo 20.03
|
||||||
|
- update libmpv 2020-04-12, it supports vpy playback, read manual or ask in forum
|
||||||
|
- mpv property `window-maximized` support added, cycling it from input.conf
|
||||||
|
is not recommended, use native Windows shortcuts Win+Up, Win+Down
|
||||||
|
- the mpv.net `start-size` option supports `always` to always remember the window height
|
||||||
|
- if the window was maximized before fullscreen was entered, it's now set to
|
||||||
|
maximized after fullscreen was left
|
||||||
|
- with `border=no` the OSC did not auto hide after the mouse curser left the window
|
||||||
|
- the script that modified the seek OSD was removed, it still can be found in the mpv wiki
|
||||||
|
- certain videos were showed with black bars
|
||||||
|
|
||||||
|
|
||||||
|
### 5.4.4.2
|
||||||
|
|
||||||
|
- update: libmpv shinchiro 0.32.0-258-g281f5c63c1
|
||||||
|
- update: youtube-dl
|
||||||
|
|
||||||
|
- new: d3d11va-zero-copy setting added to conf editor
|
||||||
|
- new: hdr-compute-peak setting added to conf editor
|
||||||
|
- new: flag cli switches support now `--no-flag` in addition to `--flag=no`
|
||||||
|
https://mpv.io/manual/master/#usage
|
||||||
|
- new: cli switches can also start with single `-` instead of double `--`
|
||||||
|
https://mpv.io/manual/master/#legacy-option-syntax
|
||||||
|
- new: PowerShell script host was completely rewritten, events can be assigned
|
||||||
|
by using `Register-ObjectEvent`, the scripting wiki page was updated
|
||||||
|
https://github.com/stax76/mpv.net/wiki/Scripting#powershell
|
||||||
|
- new: Context Menu > View > Show Profiles
|
||||||
|
https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/input.conf.txt#L147
|
||||||
|
- new: Context Menu > View > Show Properties
|
||||||
|
https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/input.conf.txt#L148
|
||||||
|
- new: Context Menu > View > Show Commands
|
||||||
|
https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/input.conf.txt#L149
|
||||||
|
- new: config editor tab is now remembered
|
||||||
|
- new: osd-duration setting added to config editor and default mpv.conf
|
||||||
|
- new: external console replaced with internal console, in case mpv.conf is missing it's
|
||||||
|
generated with correct Hight DPI font size scale settings.
|
||||||
|
`script-opts=console-scale=<dpiscale>`
|
||||||
|
https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/input.conf.txt#L150
|
||||||
|
https://mpv.io/manual/master/#console
|
||||||
|
- new: blue color in dark theme is now less intense
|
||||||
|
https://github.com/stax76/mpv.net/blob/master/Manual.md#color-theme
|
||||||
|
- new: menu item 'View > Show Progress' (p key) to show progress bar
|
||||||
|
https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/input.conf.txt#L146
|
||||||
|
- new: `script-message mpv.net playlist-first`, unlike mpv does not
|
||||||
|
restart if the first file is already active
|
||||||
|
https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/input.conf.txt#L44
|
||||||
|
- new: if mpv.net is started from the terminal and an error happens then the error
|
||||||
|
is printed to the terminal instead of shown with a message box
|
||||||
|
- fix: update routine did only work when mpv.net was located in 'Program Files'
|
||||||
|
- fix: fatal errors were ignored and only seen in the terminal, now a message box is shown
|
||||||
|
- fix: when start-size=video was used then enlarging or shrinking the window size was broken
|
||||||
|
|
||||||
|
### 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/input.conf.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
|
### 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: the color themes can now be customized ([manual](https://github.com/stax76/mpv.net/blob/master/Manual.md#color-theme))
|
||||||
@@ -25,7 +136,7 @@
|
|||||||
context menu item in explorer with multi selection support use my
|
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
|
[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
|
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))
|
- window-size mpv property support added ([default bindings](https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/input.conf.txt#L137))
|
||||||
- the config editor keeps profiles and comments in mpv.conf intact!
|
- the config editor keeps profiles and comments in mpv.conf intact!
|
||||||
- the options in the config editor are better organized
|
- the options in the config editor are better organized
|
||||||
|
|
||||||
@@ -99,7 +210,6 @@
|
|||||||
|
|
||||||
### 5.1
|
### 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
|
- many [wiki pages](https://github.com/stax76/mpv.net/wiki) were improved
|
||||||
- the logo/icon had a very small cosmetic change
|
- the logo/icon had a very small cosmetic change
|
||||||
- the help in the context menu was improved,
|
- the help in the context menu was improved,
|
||||||
@@ -219,11 +329,11 @@
|
|||||||
- fix for middle mouse button not working
|
- 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 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
|
- fix config dialog showing a message about app restart without reason
|
||||||
- when multiple files are selected in Windows File Explorer and enter is
|
- when multiple files are selected in File Explorer and enter is
|
||||||
pressed, the files are opened as selected, the order is random though
|
pressed, the files are opened as selected, the order is random though
|
||||||
because Explorer starts multiple mpv.net processes concurrently
|
because Explorer starts multiple mpv.net processes concurrently
|
||||||
- libmpv was updated to shinchiro 2019-06-30
|
- 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
|
- the [mpv.conf defaults](https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/mpv.conf.txt) were changed to show a larger OSC
|
||||||
- in case a file is opened that has a aspect ratio smaller then 1.2 then
|
- 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
|
the window size will use a aspect ratio of 1.8
|
||||||
- new JavaScript script osc-visibility.js included in the distribution
|
- new JavaScript script osc-visibility.js included in the distribution
|
||||||
@@ -234,7 +344,7 @@
|
|||||||
|
|
||||||
- opening a URL manually no longer uses a input box but uses the clipboard directly
|
- opening a URL manually no longer uses a input box but uses the clipboard directly
|
||||||
- the manifest was missing the company attribute which caused
|
- the manifest was missing the company attribute which caused
|
||||||
mpv.net not appearing in the 'Open with' menu of the Windows File Explorer,
|
mpv.net not appearing in the 'Open with' menu of the File Explorer,
|
||||||
thanks to 44vince44 for pointing this out!!!
|
thanks to 44vince44 for pointing this out!!!
|
||||||
- new Python and C# script examples were added to the wiki and the scripting and
|
- new Python and C# script examples were added to the wiki and the scripting and
|
||||||
extension documentation was improved
|
extension documentation was improved
|
||||||
@@ -262,7 +372,7 @@
|
|||||||
- the default key binding of the Everything media search was changed to F3
|
- 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
|
- 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
|
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))
|
key binding (b) was added as well ([Default Binding](https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/input.conf.txt#L135))
|
||||||
|
|
||||||
### 4.3.1
|
### 4.3.1
|
||||||
|
|
||||||
@@ -277,7 +387,7 @@
|
|||||||
- the help and layout in the config editor was improved
|
- the help and layout in the config editor was improved
|
||||||
- clipboard monitoring for URLs can be disabled in the settings
|
- clipboard monitoring for URLs can be disabled in the settings
|
||||||
- the context menu has a new feature: Open > Add files to playlist,
|
- 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)
|
it appends files to the playlist [(Default binding)](https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/input.conf.txt#L33)
|
||||||
- a setting was added to force using a single mpv.net process instance
|
- a setting was added to force using a single mpv.net process instance
|
||||||
|
|
||||||
### 4.1
|
### 4.1
|
||||||
@@ -319,7 +429,7 @@
|
|||||||
- there was a bug that caused underscores beeing removed from input like MBTN_LEFT_DBL
|
- 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
|
- 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
|
- 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)
|
[Everything](https://www.voidtools.com) to be installed. [Default Binding](https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/input.conf.txt#L29)
|
||||||
|
|
||||||
### 3.5
|
### 3.5
|
||||||
|
|
||||||
@@ -332,6 +442,6 @@
|
|||||||
|
|
||||||
### 3.4
|
### 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 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/input.conf.txt#L149)
|
||||||
- new zip download option added
|
- new zip download option added
|
||||||
- new x86 download option added
|
- new x86 download option added
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
MIT License
|
MIT License
|
||||||
|
|
||||||
Copyright 2002-2017 Frank Skare (stax76)
|
Copyright (C) 2017-2020 Frank Skare (stax76)
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person
|
Permission is hereby granted, free of charge, to any person
|
||||||
obtaining a copy of this software and ssociated documentation
|
obtaining a copy of this software and ssociated documentation
|
||||||
|
|||||||
305
README.md
305
README.md
@@ -1,263 +1,148 @@
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
     [](https://www.paypal.me/stax76)
|
    
|
||||||
|
|
||||||
# 🎞 mpv.net
|
🎞 mpv.net
|
||||||
|
==========
|
||||||
|
|
||||||
mpv.net is a modern media player for Windows that works just like [mpv](https://mpv.io).
|
mpv.net is a modern media player for Windows based on the popular [mpv](https://mpv.io) player.
|
||||||
|
|
||||||
#### 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.
|
#### Graphical User Interface
|
||||||
|
|
||||||
|
Modern GUI with customizable color themes.
|
||||||
|
|
||||||
|
|
||||||
#### Command Line Interface
|
#### Command Line Interface
|
||||||
|
|
||||||
mpv.net has the [CLI of mpv](https://mpv.io/manual/master/#options).
|
mpv.net supports mpvs property based command line switches.
|
||||||
|
|
||||||
|
|
||||||
#### High quality video output
|
#### High quality video output
|
||||||
|
|
||||||
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.
|
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
|
#### On Screen Controller
|
||||||
|
|
||||||
The OSC of libmpv offers play controls with a modern flat design. ([Screenshot](#main-window-screenshot))
|
Play controls with a modern flat design.
|
||||||
|
|
||||||
|
|
||||||
#### GPU video decoding
|
#### GPU video decoding
|
||||||
|
|
||||||
libmpv leverages the FFmpeg hwaccel APIs to support DXVA2 video decoding acceleration.
|
Leverages the FFmpeg hwaccel APIs to support DXVA2 video decoding acceleration.
|
||||||
|
|
||||||
|
|
||||||
#### Active development
|
#### 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)!
|
mpv.net is under active development.
|
||||||
|
|
||||||
|
|
||||||
|
#### 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
|
Table of contents
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
- [Features](#features)
|
- [Features](#features)
|
||||||
- [Screenshots](#screenshots)
|
|
||||||
- [Manual](#manual)
|
|
||||||
- [Context Menu](#context-menu)
|
|
||||||
- [Settings](#settings)
|
|
||||||
- [Scripting](#scripting)
|
|
||||||
- [Extensions](#extensions)
|
|
||||||
- [Architecture](#architecture)
|
|
||||||
- [Support](#support)
|
- [Support](#support)
|
||||||
- [Links](#links)
|
|
||||||
- [Changelog](#changelog)
|
|
||||||
- [Download](#download)
|
- [Download](#download)
|
||||||
|
|
||||||
### Features
|
|
||||||
|
|
||||||
- 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
|
|
||||||
- Searchable command palette to quickly launch commands and look for keys ([Screenshot](#command-palette-screenshot))
|
|
||||||
- Modern WPF based graphical user interface with dark mode ([Screenshot](#config-editor-screenshot))
|
|
||||||
- Extension API for .NET languages
|
|
||||||
- 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)
|
|
||||||
- [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 Explorer using the shell extension [Open with++](https://github.com/stax76/OpenWithPlusPlus#add-to-mpvnet-playlist) and the --queue switch
|
|
||||||
- [Manual](#manual)
|
- [Manual](#manual)
|
||||||
|
- [Screenshots](#screenshots)
|
||||||
|
|
||||||
### Screenshots
|
|
||||||
|
|
||||||
#### Main Window Screenshot
|
Features
|
||||||
|
--------
|
||||||
|
|
||||||
|
- High degree of mpv compatibility, almost all mpv features are available
|
||||||
|
- Customizable context menu defined in the same file as the key bindings
|
||||||
|
- Config dialog
|
||||||
|
- Shorcut key editor
|
||||||
|
- Many features like the config editor and shortcut key editor are fully searchable
|
||||||
|
- Configuration files that are easy to read and edit
|
||||||
|
- Command palette to quickly find commands and keys
|
||||||
|
- Modern graphical user interface with customizable color themes
|
||||||
|
- Extension API for .NET languages (C#, VB.NET and F#)
|
||||||
|
- Scripting API for C#, Lua, JavaScript and PowerShell
|
||||||
|
- JSON IPC to control the player with a external programs
|
||||||
|
- On Screen Controler (OSC, play control buttons) with modern flat design
|
||||||
|
- Command Line Interface
|
||||||
|
- Started from a terminal status and debug output is printed on the terminal
|
||||||
|
- DXVA2 video decoding acceleration
|
||||||
|
- 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
|
||||||
|
- File search feature powered by the popular search and index tool Everything
|
||||||
|
- Browser extensions to start mpv.net from the browser
|
||||||
|
- Fast seek performance
|
||||||
|
- Fast startup performance
|
||||||
|
- Usable as video player, audio player and image viewer with a wide range of supported formats
|
||||||
|
- Built-in decoders, no external codecs have to be installed
|
||||||
|
- Setup as x64, x86, installer, portable, Chocolatey and Scoop
|
||||||
|
- Build-in media streaming via youtube-dl
|
||||||
|
- File associations can be created by the setup and from the player
|
||||||
|
- External audio and subtitle files can be loaded manually or automatically
|
||||||
|
- Screenshot feature
|
||||||
|
- File history feature to log time and filename
|
||||||
|
- Watch later feature to save the position
|
||||||
|
- Files can be enqueued from File Explorer
|
||||||
|
- Update check and update routine
|
||||||
|
|
||||||
|
|
||||||
|
## [Support](Manual.md#support)
|
||||||
|
|
||||||
|
[Support section of the manual.](Manual.md#support)
|
||||||
|
|
||||||
|
|
||||||
|
## [Download](Manual.md#download)
|
||||||
|
|
||||||
|
[Download section of the manual.](Manual.md#download)
|
||||||
|
|
||||||
|
|
||||||
|
## [Manual](Manual.md)
|
||||||
|
|
||||||
|
[The mpv.net documentation.](Manual.md)
|
||||||
|
|
||||||
|
|
||||||
|
Screenshots
|
||||||
|
-----------
|
||||||
|
|
||||||
|
#### Main Window
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
#### Context Menu Screenshot
|
|
||||||
|
|
||||||
Context menu defined in the input.conf file with dark mode support.
|
#### Context Menu
|
||||||
|
|
||||||
|
Context menu using dark mode.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
#### Config Editor Screenshot
|
|
||||||
|
|
||||||
A searchable config editor as alternative to edit the mpv.conf file manually.
|
#### Config Editor
|
||||||
|
|
||||||
|
Searchable config editor as alternative to edit the conf file manually.
|
||||||
|
|
||||||

|

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

|

|
||||||
|
|
||||||
#### Input Editor Screenshot
|
|
||||||
|
|
||||||
A searchable key and mouse binding editor.
|
#### Input Editor
|
||||||
|
|
||||||
|
Searchable key and mouse binding editor.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
#### Command Palette Screenshot
|
|
||||||
|
|
||||||
Forgot where a command in the menu is located or what shortcut key it has?
|
#### Command Palette
|
||||||
Just press F1 and find it easily in the searchable command palette.
|
|
||||||
|
Command Palette to find commands and shortcut keys easily.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
#### Media Search Screenshot
|
|
||||||
|
|
||||||
Media search feature powered by [Everything](https://www.voidtools.com) to find and play media.
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
### Manual
|
|
||||||
|
|
||||||
[Manual](Manual.md)
|
|
||||||
|
|
||||||
### Context Menu
|
|
||||||
|
|
||||||
The context menu can be customized via input.conf file located in the config directory:
|
|
||||||
|
|
||||||
```Text
|
|
||||||
C:\Users\%username%\AppData\Roaming\mpv\input.conf
|
|
||||||
```
|
|
||||||
|
|
||||||
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>
|
|
||||||
|
|
||||||
input.conf defines mpv's key and mouse bindings and mpv.net uses comments to define the context menu.
|
|
||||||
|
|
||||||
### Settings
|
|
||||||
|
|
||||||
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
|
|
||||||
<startup>\portable_config\
|
|
||||||
```
|
|
||||||
|
|
||||||
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>
|
|
||||||
|
|
||||||
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)
|
|
||||||
|
|
||||||
### Extensions
|
|
||||||
|
|
||||||
[Extensions wiki page](https://github.com/stax76/mpv.net/wiki/Extensions)
|
|
||||||
|
|
||||||
### Architecture
|
|
||||||
|
|
||||||
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 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 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](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 6000 lines of code and markup.
|
|
||||||
|
|
||||||
IDE, Editor: Visual Studio, Visual Studio Code.
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
[Support thread in Doom9 forum](https://forum.doom9.org/showthread.php?t=174841)
|
|
||||||
|
|
||||||
[Support thread in VideoHelp forum](https://forum.videohelp.com/threads/392514-mpv-net-a-extendable-media-player-for-windows)
|
|
||||||
|
|
||||||
[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.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
|
|
||||||
|
|
||||||
[Changelog](Changelog.md)
|
|
||||||
|
|
||||||
### Download
|
|
||||||
|
|
||||||
<https://github.com/stax76/mpv.net/releases>
|
|
||||||
|
|||||||
114
Release.ps1
Normal file
114
Release.ps1
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
|
||||||
|
$ErrorActionPreference = 'Stop'
|
||||||
|
|
||||||
|
$include = @(
|
||||||
|
'*.cs',
|
||||||
|
'*.csproj',
|
||||||
|
'*.iss',
|
||||||
|
'*.js',
|
||||||
|
'*.lua',
|
||||||
|
'*.md',
|
||||||
|
'*.ps1',
|
||||||
|
'*.resx',
|
||||||
|
'*.sln',
|
||||||
|
'*.txt',
|
||||||
|
'*.xaml'
|
||||||
|
)
|
||||||
|
|
||||||
|
$files = Get-ChildItem -Path $PSScriptRoot -Recurse -File -Include $include
|
||||||
|
|
||||||
|
foreach ($file in $files)
|
||||||
|
{
|
||||||
|
$lines = Get-Content $file
|
||||||
|
|
||||||
|
foreach ($line in $lines)
|
||||||
|
{
|
||||||
|
foreach ($char in $line.ToCharArray())
|
||||||
|
{
|
||||||
|
$codePoint = [int]$char
|
||||||
|
|
||||||
|
if ($codePoint -gt 127)
|
||||||
|
{
|
||||||
|
throw "Non ASCII char $char in file '$($file.FullName)' in line: $line"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$desktopDir = [Environment]::GetFolderPath('Desktop')
|
||||||
|
$exePath = $PSScriptRoot + '\mpv.net\bin\x64\mpvnet.exe'
|
||||||
|
$versionInfo = [Diagnostics.FileVersionInfo]::GetVersionInfo($exePath)
|
||||||
|
$vsDir = 'C:\Program Files (x86)\Microsoft Visual Studio\2019'
|
||||||
|
$msBuild = $vsDir + '\Community\MSBuild\Current\Bin\MSBuild.exe'
|
||||||
|
$inno = 'C:\Program Files (x86)\Inno Setup 6\ISCC.exe'
|
||||||
|
$7z = 'C:\Program Files\7-Zip\7z.exe'
|
||||||
|
|
||||||
|
if ($versionInfo.FilePrivatePart -eq 0)
|
||||||
|
{
|
||||||
|
& $msBuild mpv.net.sln -t:Rebuild -p:Configuration=Debug -p:Platform=x64
|
||||||
|
if ($LastExitCode) { throw $LastExitCode }
|
||||||
|
|
||||||
|
& $msBuild mpv.net.sln -t:Rebuild -p:Configuration=Debug -p:Platform=x86
|
||||||
|
if ($LastExitCode) { throw $LastExitCode }
|
||||||
|
|
||||||
|
& $inno /Darch=x64 setup.iss
|
||||||
|
if ($LastExitCode) { throw $LastExitCode }
|
||||||
|
|
||||||
|
& $inno /Darch=x86 setup.iss
|
||||||
|
if ($LastExitCode) { throw $LastExitCode }
|
||||||
|
|
||||||
|
$targetDir = $desktopDir + "\mpv.net-portable-x64-$($versionInfo.FileVersion)"
|
||||||
|
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-$($versionInfo.FileVersion)"
|
||||||
|
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 }
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
& $msBuild mpv.net.sln -t:Rebuild -p:Configuration=Debug -p:Platform=x64
|
||||||
|
if ($LastExitCode) { throw $LastExitCode }
|
||||||
|
|
||||||
|
$targetDir = "$desktopDir\mpv.net-portable-x64-$($versionInfo.FileVersion)-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 }
|
||||||
|
|
||||||
|
$cloudDirectories = 'C:\Users\frank\OneDrive\Public\mpv.net\',
|
||||||
|
'C:\Users\frank\Dropbox\Public\mpv.net\'
|
||||||
|
|
||||||
|
foreach ($cloudDirectory in $cloudDirectories)
|
||||||
|
{
|
||||||
|
if (-not (Test-Path $cloudDirectory))
|
||||||
|
{
|
||||||
|
throw $cloudDirectory
|
||||||
|
}
|
||||||
|
|
||||||
|
$targetFile = $cloudDirectory + (Split-Path $targetDir -Leaf) + '.7z'
|
||||||
|
|
||||||
|
if (Test-Path $targetFile)
|
||||||
|
{
|
||||||
|
throw $targetFile
|
||||||
|
}
|
||||||
|
|
||||||
|
Copy-Item ($targetDir + '.7z') $targetFile
|
||||||
|
Invoke-Item $cloudDirectory
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Set-Clipboard ($versionInfo.FileVersion + "`n`n" +
|
||||||
|
'https://github.com/stax76/mpv.net/blob/master/Changelog.md' + "`n`n" +
|
||||||
|
'https://github.com/stax76/mpv.net#download')
|
||||||
|
|
||||||
|
Write-Host 'successfully finished' -ForegroundColor Green
|
||||||
@@ -6,11 +6,11 @@ using System.Runtime.InteropServices;
|
|||||||
// set of attributes. Change these attribute values to modify the information
|
// set of attributes. Change these attribute values to modify the information
|
||||||
// associated with an assembly.
|
// associated with an assembly.
|
||||||
[assembly: AssemblyTitle("RatingExtension")]
|
[assembly: AssemblyTitle("RatingExtension")]
|
||||||
[assembly: AssemblyDescription("")]
|
[assembly: AssemblyDescription("RatingExtension")]
|
||||||
[assembly: AssemblyConfiguration("")]
|
[assembly: AssemblyConfiguration("")]
|
||||||
[assembly: AssemblyCompany("")]
|
[assembly: AssemblyCompany("Frank Skare (stax76)")]
|
||||||
[assembly: AssemblyProduct("RatingExtension")]
|
[assembly: AssemblyProduct("RatingExtension")]
|
||||||
[assembly: AssemblyCopyright("Copyright © 2017-2019 Frank Skare (stax76)")]
|
[assembly: AssemblyCopyright("Copyright (C) 2017-2020 Frank Skare (stax76)")]
|
||||||
[assembly: AssemblyTrademark("")]
|
[assembly: AssemblyTrademark("")]
|
||||||
[assembly: AssemblyCulture("")]
|
[assembly: AssemblyCulture("")]
|
||||||
|
|
||||||
|
|||||||
@@ -6,11 +6,11 @@ using System.Runtime.InteropServices;
|
|||||||
// set of attributes. Change these attribute values to modify the information
|
// set of attributes. Change these attribute values to modify the information
|
||||||
// associated with an assembly.
|
// associated with an assembly.
|
||||||
[assembly: AssemblyTitle("RatingExtension")]
|
[assembly: AssemblyTitle("RatingExtension")]
|
||||||
[assembly: AssemblyDescription("")]
|
[assembly: AssemblyDescription("RatingExtension")]
|
||||||
[assembly: AssemblyConfiguration("")]
|
[assembly: AssemblyConfiguration("")]
|
||||||
[assembly: AssemblyCompany("")]
|
[assembly: AssemblyCompany("Frank Skare (stax76)")]
|
||||||
[assembly: AssemblyProduct("RatingExtension")]
|
[assembly: AssemblyProduct("RatingExtension")]
|
||||||
[assembly: AssemblyCopyright("Copyright © 2017-2019 Frank Skare (stax76)")]
|
[assembly: AssemblyCopyright("Copyright (C) 2017-2020 Frank Skare (stax76)")]
|
||||||
[assembly: AssemblyTrademark("")]
|
[assembly: AssemblyTrademark("")]
|
||||||
[assembly: AssemblyCulture("")]
|
[assembly: AssemblyCulture("")]
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
|
||||||
// This extension implements the C# scripting feature of mpv.net which
|
// This extension implements the C# scripting feature of mpv.net which
|
||||||
// is based on CS-Script (https://www.cs-script.net).
|
// is based on CS-Script (https://www.cs-script.net).
|
||||||
|
|
||||||
@@ -13,7 +14,8 @@ using System.IO;
|
|||||||
using mpvnet;
|
using mpvnet;
|
||||||
using CSScriptLibrary;
|
using CSScriptLibrary;
|
||||||
|
|
||||||
namespace ScriptingExtension // the file name of extensions must end with 'Extension'
|
// the file name of extensions must end with 'Extension'
|
||||||
|
namespace ScriptingExtension
|
||||||
{
|
{
|
||||||
[Export(typeof(IExtension))]
|
[Export(typeof(IExtension))]
|
||||||
public class ScriptingExtension : IExtension
|
public class ScriptingExtension : IExtension
|
||||||
@@ -23,24 +25,29 @@ namespace ScriptingExtension // the file name of extensions must end with 'Exten
|
|||||||
public ScriptingExtension()
|
public ScriptingExtension()
|
||||||
{
|
{
|
||||||
//Script = new Script();
|
//Script = new Script();
|
||||||
List<string> scriptFiles = new List<string>();
|
List<string> files = new List<string>();
|
||||||
|
|
||||||
if (Directory.Exists(mp.ConfigFolder + "scripts"))
|
if (Directory.Exists(mp.ConfigFolder + "scripts-cs"))
|
||||||
scriptFiles.AddRange(Directory.GetFiles(mp.ConfigFolder + "scripts", "*.cs"));
|
files.AddRange(Directory.GetFiles(mp.ConfigFolder + "scripts-cs", "*.cs"));
|
||||||
|
|
||||||
if (Directory.Exists(Folder.Startup + "scripts"))
|
if (Directory.Exists(Folder.Startup + "scripts"))
|
||||||
foreach (string path in Directory.GetFiles(Folder.Startup + "scripts", "*.cs"))
|
foreach (string path in Directory.GetFiles(Folder.Startup + "scripts", "*.cs"))
|
||||||
scriptFiles.AddRange(Directory.GetFiles(Folder.Startup + "scripts", "*.cs"));
|
files.AddRange(Directory.GetFiles(Folder.Startup + "scripts", "*.cs"));
|
||||||
|
|
||||||
|
if (files.Count == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
if (scriptFiles.Count == 0) return;
|
|
||||||
CSScriptLibrary.CSScript.EvaluatorConfig.Engine = EvaluatorEngine.CodeDom;
|
CSScriptLibrary.CSScript.EvaluatorConfig.Engine = EvaluatorEngine.CodeDom;
|
||||||
|
|
||||||
foreach (var i in scriptFiles)
|
foreach (string file in files)
|
||||||
{
|
{
|
||||||
try {
|
try
|
||||||
CSScriptLibrary.CSScript.Evaluator.LoadCode(File.ReadAllText(i));
|
{
|
||||||
} catch (Exception e) {
|
CSScriptLibrary.CSScript.Evaluator.LoadCode(File.ReadAllText(file));
|
||||||
Msg.ShowException(e);
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
App.ShowException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System.IO;
|
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
using mpvnet;
|
using mpvnet;
|
||||||
|
|
||||||
@@ -9,7 +10,7 @@ class Script
|
|||||||
mp.Shutdown += Shutdown;
|
mp.Shutdown += Shutdown;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Shutdown()
|
void Shutdown()
|
||||||
{
|
{
|
||||||
foreach (string file in Directory.GetFiles(@"C:\Users\frank\Desktop\aaa"))
|
foreach (string file in Directory.GetFiles(@"C:\Users\frank\Desktop\aaa"))
|
||||||
File.Delete(file);
|
File.Delete(file);
|
||||||
|
|||||||
12
mpv.net.sln
12
mpv.net.sln
@@ -19,24 +19,24 @@ Global
|
|||||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
{1751F378-8EDF-4B62-BE6D-304C7C287089}.Debug|x64.ActiveCfg = Debug|x64
|
{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|x64.Build.0 = Debug|x64
|
||||||
{1751F378-8EDF-4B62-BE6D-304C7C287089}.Debug|x86.ActiveCfg = Debug|x64
|
{1751F378-8EDF-4B62-BE6D-304C7C287089}.Debug|x86.ActiveCfg = Debug|x86
|
||||||
{1751F378-8EDF-4B62-BE6D-304C7C287089}.Debug|x86.Build.0 = Debug|x64
|
{1751F378-8EDF-4B62-BE6D-304C7C287089}.Debug|x86.Build.0 = Debug|x86
|
||||||
{1751F378-8EDF-4B62-BE6D-304C7C287089}.Release|x64.ActiveCfg = Release|x64
|
{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|x64.Build.0 = Release|x64
|
||||||
{1751F378-8EDF-4B62-BE6D-304C7C287089}.Release|x86.ActiveCfg = Release|x86
|
{1751F378-8EDF-4B62-BE6D-304C7C287089}.Release|x86.ActiveCfg = Release|x86
|
||||||
{1751F378-8EDF-4B62-BE6D-304C7C287089}.Release|x86.Build.0 = Release|x86
|
{1751F378-8EDF-4B62-BE6D-304C7C287089}.Release|x86.Build.0 = Release|x86
|
||||||
{55C88710-539D-4402-84C8-31694841C731}.Debug|x64.ActiveCfg = Debug|x64
|
{55C88710-539D-4402-84C8-31694841C731}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
{55C88710-539D-4402-84C8-31694841C731}.Debug|x64.Build.0 = Debug|x64
|
{55C88710-539D-4402-84C8-31694841C731}.Debug|x64.Build.0 = Debug|x64
|
||||||
{55C88710-539D-4402-84C8-31694841C731}.Debug|x86.ActiveCfg = Debug|x64
|
{55C88710-539D-4402-84C8-31694841C731}.Debug|x86.ActiveCfg = Debug|x86
|
||||||
{55C88710-539D-4402-84C8-31694841C731}.Debug|x86.Build.0 = Debug|x64
|
{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.ActiveCfg = Release|x64
|
||||||
{55C88710-539D-4402-84C8-31694841C731}.Release|x64.Build.0 = 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.ActiveCfg = Release|x86
|
||||||
{55C88710-539D-4402-84C8-31694841C731}.Release|x86.Build.0 = Release|x86
|
{55C88710-539D-4402-84C8-31694841C731}.Release|x86.Build.0 = Release|x86
|
||||||
{94255EF2-C823-4D82-9017-0E993CC0F5A1}.Debug|x64.ActiveCfg = Debug|x64
|
{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|x64.Build.0 = Debug|x64
|
||||||
{94255EF2-C823-4D82-9017-0E993CC0F5A1}.Debug|x86.ActiveCfg = Debug|x64
|
{94255EF2-C823-4D82-9017-0E993CC0F5A1}.Debug|x86.ActiveCfg = Debug|x86
|
||||||
{94255EF2-C823-4D82-9017-0E993CC0F5A1}.Debug|x86.Build.0 = Debug|x64
|
{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.ActiveCfg = Release|x64
|
||||||
{94255EF2-C823-4D82-9017-0E993CC0F5A1}.Release|x64.Build.0 = 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.ActiveCfg = Release|x86
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
@@ -113,7 +114,7 @@ namespace DynamicGUI
|
|||||||
|
|
||||||
public OptionSetting OptionSetting { get; set; }
|
public OptionSetting OptionSetting { get; set; }
|
||||||
|
|
||||||
private string _Text;
|
string _Text;
|
||||||
|
|
||||||
public string Text
|
public string Text
|
||||||
{
|
{
|
||||||
@@ -144,7 +145,7 @@ namespace DynamicGUI
|
|||||||
|
|
||||||
public class HyperlinkEx : Hyperlink
|
public class HyperlinkEx : Hyperlink
|
||||||
{
|
{
|
||||||
private void HyperLinkEx_RequestNavigate(object sender, RequestNavigateEventArgs e)
|
void HyperLinkEx_RequestNavigate(object sender, RequestNavigateEventArgs e)
|
||||||
{
|
{
|
||||||
Process.Start(e.Uri.AbsoluteUri);
|
Process.Start(e.Uri.AbsoluteUri);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,35 +1,42 @@
|
|||||||
using System.Windows;
|
|
||||||
|
using System.Windows;
|
||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
|
|
||||||
namespace DynamicGUI
|
namespace DynamicGUI
|
||||||
{
|
{
|
||||||
public partial class OptionSettingControl : UserControl, ISettingControl
|
public partial class OptionSettingControl : UserControl, ISettingControl
|
||||||
{
|
{
|
||||||
private OptionSetting OptionSetting;
|
OptionSetting OptionSetting;
|
||||||
|
|
||||||
public OptionSettingControl(OptionSetting optionSetting)
|
public OptionSettingControl(OptionSetting optionSetting)
|
||||||
{
|
{
|
||||||
OptionSetting = optionSetting;
|
OptionSetting = optionSetting;
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
TitleTextBox.Text = optionSetting.Name;
|
TitleTextBox.Text = optionSetting.Name;
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(optionSetting.Help))
|
if (string.IsNullOrEmpty(optionSetting.Help))
|
||||||
HelpTextBox.Visibility = Visibility.Collapsed;
|
HelpTextBox.Visibility = Visibility.Collapsed;
|
||||||
|
|
||||||
HelpTextBox.Text = optionSetting.Help;
|
HelpTextBox.Text = optionSetting.Help;
|
||||||
ItemsControl.ItemsSource = optionSetting.Options;
|
ItemsControl.ItemsSource = optionSetting.Options;
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(optionSetting.URL))
|
if (string.IsNullOrEmpty(optionSetting.URL))
|
||||||
LinkTextBlock.Visibility = Visibility.Collapsed;
|
LinkTextBlock.Visibility = Visibility.Collapsed;
|
||||||
|
|
||||||
Link.SetURL(optionSetting.URL);
|
Link.SetURL(optionSetting.URL);
|
||||||
}
|
}
|
||||||
|
|
||||||
private string _SearchableText;
|
string _SearchableText;
|
||||||
|
|
||||||
public string SearchableText {
|
public string SearchableText {
|
||||||
get {
|
get {
|
||||||
if (_SearchableText is null)
|
if (_SearchableText is null)
|
||||||
{
|
{
|
||||||
_SearchableText = TitleTextBox.Text + HelpTextBox.Text;
|
_SearchableText = TitleTextBox.Text + HelpTextBox.Text;
|
||||||
|
|
||||||
foreach (var i in OptionSetting.Options)
|
foreach (var i in OptionSetting.Options)
|
||||||
_SearchableText += i.Text + i.Help + i.Name;
|
_SearchableText += i.Text + i.Help + i.Name;
|
||||||
|
|
||||||
_SearchableText = _SearchableText.ToLower();
|
_SearchableText = _SearchableText.ToLower();
|
||||||
}
|
}
|
||||||
return _SearchableText;
|
return _SearchableText;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
using System;
|
|
||||||
using System.Diagnostics;
|
using System;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
@@ -10,7 +10,7 @@ namespace DynamicGUI
|
|||||||
{
|
{
|
||||||
public partial class StringSettingControl : UserControl, ISettingControl
|
public partial class StringSettingControl : UserControl, ISettingControl
|
||||||
{
|
{
|
||||||
private StringSetting StringSetting;
|
StringSetting StringSetting;
|
||||||
|
|
||||||
public StringSettingControl(StringSetting stringSetting)
|
public StringSettingControl(StringSetting stringSetting)
|
||||||
{
|
{
|
||||||
@@ -19,21 +19,26 @@ namespace DynamicGUI
|
|||||||
TitleTextBox.Text = stringSetting.Name;
|
TitleTextBox.Text = stringSetting.Name;
|
||||||
HelpTextBox.Text = stringSetting.Help;
|
HelpTextBox.Text = stringSetting.Help;
|
||||||
ValueTextBox.Text = StringSetting.Value;
|
ValueTextBox.Text = StringSetting.Value;
|
||||||
|
|
||||||
if (StringSetting.Width > 0)
|
if (StringSetting.Width > 0)
|
||||||
ValueTextBox.Width = StringSetting.Width;
|
ValueTextBox.Width = StringSetting.Width;
|
||||||
|
|
||||||
if (StringSetting.Type != "folder" && StringSetting.Type != "color")
|
if (StringSetting.Type != "folder" && StringSetting.Type != "color")
|
||||||
Button.Visibility = Visibility.Hidden;
|
Button.Visibility = Visibility.Hidden;
|
||||||
|
|
||||||
Link.SetURL(StringSetting.URL);
|
Link.SetURL(StringSetting.URL);
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(stringSetting.URL))
|
if (string.IsNullOrEmpty(stringSetting.URL))
|
||||||
LinkTextBlock.Visibility = Visibility.Collapsed;
|
LinkTextBlock.Visibility = Visibility.Collapsed;
|
||||||
}
|
}
|
||||||
|
|
||||||
private string _SearchableText;
|
string _SearchableText;
|
||||||
|
|
||||||
public string SearchableText {
|
public string SearchableText {
|
||||||
get {
|
get {
|
||||||
if (_SearchableText is null)
|
if (_SearchableText is null)
|
||||||
_SearchableText = (TitleTextBox.Text + HelpTextBox.Text +ValueTextBox.Text).ToLower();
|
_SearchableText = (TitleTextBox.Text + HelpTextBox.Text +ValueTextBox.Text).ToLower();
|
||||||
|
|
||||||
return _SearchableText;
|
return _SearchableText;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -47,7 +52,7 @@ namespace DynamicGUI
|
|||||||
set => StringSetting.Value = value;
|
set => StringSetting.Value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Button_Click(object sender, RoutedEventArgs e)
|
void Button_Click(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
switch (StringSetting.Type)
|
switch (StringSetting.Type)
|
||||||
{
|
{
|
||||||
@@ -56,6 +61,7 @@ namespace DynamicGUI
|
|||||||
{
|
{
|
||||||
d.Description = "Choose a folder.";
|
d.Description = "Choose a folder.";
|
||||||
d.SelectedPath = ValueTextBox.Text;
|
d.SelectedPath = ValueTextBox.Text;
|
||||||
|
|
||||||
if (d.ShowDialog() == WinForms.DialogResult.OK)
|
if (d.ShowDialog() == WinForms.DialogResult.OK)
|
||||||
ValueTextBox.Text = d.SelectedPath;
|
ValueTextBox.Text = d.SelectedPath;
|
||||||
}
|
}
|
||||||
@@ -65,7 +71,8 @@ namespace DynamicGUI
|
|||||||
{
|
{
|
||||||
dialog.FullOpen = true;
|
dialog.FullOpen = true;
|
||||||
|
|
||||||
try {
|
try
|
||||||
|
{
|
||||||
if (!string.IsNullOrEmpty(ValueTextBox.Text))
|
if (!string.IsNullOrEmpty(ValueTextBox.Text))
|
||||||
{
|
{
|
||||||
Color col = GetColor(ValueTextBox.Text);
|
Color col = GetColor(ValueTextBox.Text);
|
||||||
@@ -80,7 +87,7 @@ namespace DynamicGUI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ValueTextBox_TextChanged(object sender, TextChangedEventArgs e) => Update();
|
void ValueTextBox_TextChanged(object sender, TextChangedEventArgs e) => Update();
|
||||||
|
|
||||||
Color GetColor(string value)
|
Color GetColor(string value)
|
||||||
{
|
{
|
||||||
@@ -104,7 +111,10 @@ namespace DynamicGUI
|
|||||||
if (StringSetting.Type == "color")
|
if (StringSetting.Type == "color")
|
||||||
{
|
{
|
||||||
Color c = Colors.Transparent;
|
Color c = Colors.Transparent;
|
||||||
if (ValueTextBox.Text != "") try { c = GetColor(ValueTextBox.Text); } catch {}
|
|
||||||
|
if (ValueTextBox.Text != "")
|
||||||
|
try { c = GetColor(ValueTextBox.Text); } catch {}
|
||||||
|
|
||||||
ValueTextBox.Background = new SolidColorBrush(c);
|
ValueTextBox.Background = new SolidColorBrush(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,16 @@
|
|||||||
using System;
|
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
|
|
||||||
using UI;
|
using UI;
|
||||||
|
|
||||||
|
using static libmpv;
|
||||||
|
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace mpvnet
|
namespace mpvnet
|
||||||
{
|
{
|
||||||
public static class App
|
public static class App
|
||||||
@@ -20,20 +26,20 @@ namespace mpvnet
|
|||||||
public static string DarkMode { get; set; } = "always";
|
public static string DarkMode { get; set; } = "always";
|
||||||
public static string DarkTheme { get; set; } = "dark";
|
public static string DarkTheme { get; set; } = "dark";
|
||||||
public static string LightTheme { get; set; } = "light";
|
public static string LightTheme { get; set; } = "light";
|
||||||
|
public static string StartSize { get; set; } = "previous";
|
||||||
|
|
||||||
public static bool RememberHeight { get; set; } = true;
|
|
||||||
public static bool RememberPosition { get; set; }
|
public static bool RememberPosition { get; set; }
|
||||||
public static bool Maximized { get; set; }
|
|
||||||
public static bool DebugMode { get; set; }
|
public static bool DebugMode { get; set; }
|
||||||
public static bool IsStartedFromTerminal { get; } = Environment.GetEnvironmentVariable("_started_from_console") == "yes";
|
public static bool IsStartedFromTerminal { get; } = Environment.GetEnvironmentVariable("_started_from_console") == "yes";
|
||||||
public static bool RememberVolume { get; set; } = true;
|
public static bool RememberVolume { get; set; } = true;
|
||||||
public static bool AutoLoadFolder { get; set; } = true;
|
public static bool AutoLoadFolder { get; set; } = true;
|
||||||
public static bool Queue { get; set; }
|
public static bool Queue { get; set; }
|
||||||
|
public static bool UpdateCheck { get; set; }
|
||||||
|
|
||||||
public static int StartThreshold { get; set; } = 1500;
|
public static int StartThreshold { get; set; } = 1500;
|
||||||
public static int RecentCount { get; set; } = 15;
|
public static int RecentCount { get; set; } = 15;
|
||||||
|
|
||||||
public static float MinimumAspectRatio { get; set; } = 1.3f;
|
public static float MinimumAspectRatio { get; set; } = 1.2f;
|
||||||
|
|
||||||
public static Extension Extension { get; set; }
|
public static Extension Extension { get; set; }
|
||||||
|
|
||||||
@@ -47,17 +53,22 @@ namespace mpvnet
|
|||||||
var dummy2 = mp.Conf;
|
var dummy2 = mp.Conf;
|
||||||
|
|
||||||
foreach (var i in Conf)
|
foreach (var i in Conf)
|
||||||
ProcessProperty(i.Key, i.Value);
|
ProcessProperty(i.Key, i.Value, true);
|
||||||
|
|
||||||
if (App.DebugMode)
|
if (App.DebugMode)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
string filePath = mp.ConfigFolder + "mpvnet-debug.log";
|
string filePath = mp.ConfigFolder + "mpvnet-debug.log";
|
||||||
if (File.Exists(filePath)) File.Delete(filePath);
|
|
||||||
|
if (File.Exists(filePath))
|
||||||
|
File.Delete(filePath);
|
||||||
|
|
||||||
Trace.Listeners.Add(new TextWriterTraceListener(filePath));
|
Trace.Listeners.Add(new TextWriterTraceListener(filePath));
|
||||||
Trace.AutoFlush = true;
|
Trace.AutoFlush = true;
|
||||||
//if (App.DebugMode) Trace.WriteLine("");
|
|
||||||
|
//if (App.DebugMode)
|
||||||
|
// Trace.WriteLine("");
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
@@ -77,23 +88,62 @@ namespace mpvnet
|
|||||||
|
|
||||||
mp.Shutdown += Shutdown;
|
mp.Shutdown += Shutdown;
|
||||||
mp.Initialized += Initialized;
|
mp.Initialized += Initialized;
|
||||||
|
mp.LogMessage += ShowFatalError;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void Initialized()
|
static void ShowFatalError(mpv_log_level level, string msg)
|
||||||
{
|
{
|
||||||
if (RememberVolume)
|
if (!App.IsStartedFromTerminal && level == mpv_log_level.MPV_LOG_LEVEL_FATAL)
|
||||||
|
Msg.ShowError(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void RunAction(Action action)
|
||||||
|
{
|
||||||
|
Task.Run(() => {
|
||||||
|
try
|
||||||
|
{
|
||||||
|
action.Invoke();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
ShowException(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void ShowException(object obj)
|
||||||
|
{
|
||||||
|
if (obj is Exception e)
|
||||||
{
|
{
|
||||||
mp.set_property_int("volume", RegHelp.GetInt(App.RegPath, "Volume", 70));
|
if (App.IsStartedFromTerminal)
|
||||||
mp.set_property_string("mute", RegHelp.GetString(App.RegPath, "Mute", "no"));
|
ConsoleHelp.WriteError(e.ToString(), "mpv.net");
|
||||||
|
else
|
||||||
|
Msg.ShowException(e);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (App.IsStartedFromTerminal)
|
||||||
|
ConsoleHelp.WriteError(obj.ToString(), "mpv.net");
|
||||||
|
else
|
||||||
|
Msg.ShowError(obj.ToString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void Shutdown()
|
static void Initialized()
|
||||||
{
|
{
|
||||||
if (RememberVolume)
|
if (RememberVolume)
|
||||||
{
|
{
|
||||||
RegHelp.SetObject(App.RegPath, "Volume", mp.get_property_int("volume"));
|
mp.set_property_int("volume", RegistryHelp.GetInt(App.RegPath, "Volume", 70));
|
||||||
RegHelp.SetObject(App.RegPath, "Mute", mp.get_property_string("mute"));
|
mp.set_property_string("mute", RegistryHelp.GetString(App.RegPath, "Mute", "no"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -114,26 +164,29 @@ namespace mpvnet
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool ProcessProperty(string name, string value)
|
public static bool ProcessProperty(string name, string value, bool writeError = false)
|
||||||
{
|
{
|
||||||
switch (name)
|
switch (name)
|
||||||
{
|
{
|
||||||
case "remember-position": RememberPosition = value == "yes"; return true;
|
case "remember-position": RememberPosition = value == "yes"; return true;
|
||||||
case "maximized": Maximized = value == "yes"; return true;
|
|
||||||
case "start-size": RememberHeight = value == "previous"; return true;
|
|
||||||
case "process-instance": ProcessInstance = value; return true;
|
|
||||||
case "dark-mode": DarkMode = value; return true;
|
|
||||||
case "debug-mode": DebugMode = value == "yes"; return true;
|
case "debug-mode": DebugMode = value == "yes"; return true;
|
||||||
case "remember-volume": RememberVolume = value == "yes"; return true;
|
case "remember-volume": RememberVolume = value == "yes"; return true;
|
||||||
case "start-threshold": StartThreshold = value.Int(); return true;
|
|
||||||
case "minimum-aspect-ratio": MinimumAspectRatio = value.Float(); return true;
|
|
||||||
case "auto-load-folder": AutoLoadFolder = value == "yes"; return true;
|
|
||||||
case "recent-count": RecentCount = value.Int(); return true;
|
|
||||||
case "queue": Queue = 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": StartSize = value; 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 "dark-theme": DarkTheme = value.Trim('\'', '"'); return true;
|
||||||
case "light-theme": LightTheme = value.Trim('\'', '"'); return true;
|
case "light-theme": LightTheme = value.Trim('\'', '"'); return true;
|
||||||
|
default:
|
||||||
|
if (writeError)
|
||||||
|
ConsoleHelp.WriteError($"unknown mpvnet.conf property: {name}", "mpv.net");
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
|
||||||
|
using System;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@@ -7,6 +8,9 @@ using System.Windows.Forms;
|
|||||||
using System.Windows.Interop;
|
using System.Windows.Interop;
|
||||||
|
|
||||||
using VB = Microsoft.VisualBasic;
|
using VB = Microsoft.VisualBasic;
|
||||||
|
using ScriptHost;
|
||||||
|
|
||||||
|
using static NewLine;
|
||||||
|
|
||||||
namespace mpvnet
|
namespace mpvnet
|
||||||
{
|
{
|
||||||
@@ -17,6 +21,7 @@ namespace mpvnet
|
|||||||
switch (id)
|
switch (id)
|
||||||
{
|
{
|
||||||
case "open-files": OpenFiles(args); break;
|
case "open-files": OpenFiles(args); break;
|
||||||
|
case "update-check": UpdateCheck.CheckOnline(true); break;
|
||||||
case "open-url": OpenURL(); break;
|
case "open-url": OpenURL(); break;
|
||||||
case "open-optical-media": Open_DVD_Or_BD_Folder(); break;
|
case "open-optical-media": Open_DVD_Or_BD_Folder(); break;
|
||||||
case "manage-file-associations": // deprecated 2019
|
case "manage-file-associations": // deprecated 2019
|
||||||
@@ -34,15 +39,14 @@ namespace mpvnet
|
|||||||
case "open-conf-folder": Process.Start(mp.ConfigFolder); break;
|
case "open-conf-folder": Process.Start(mp.ConfigFolder); break;
|
||||||
case "shell-execute": Process.Start(args[0]); break;
|
case "shell-execute": Process.Start(args[0]); break;
|
||||||
case "show-info": ShowInfo(); break;
|
case "show-info": ShowInfo(); break;
|
||||||
|
case "playlist-first": PlaylistFirst(); break;
|
||||||
case "playlist-last": PlaylistLast(); break;
|
case "playlist-last": PlaylistLast(); break;
|
||||||
|
case "show-profiles": ShowProfiles(); break;
|
||||||
|
case "show-properties": ShowProperties(); break;
|
||||||
|
case "show-commands": ShowCommands(); break;
|
||||||
case "add-files-to-playlist": OpenFiles("append"); break; // deprecated 2019
|
case "add-files-to-playlist": OpenFiles("append"); break; // deprecated 2019
|
||||||
default: Msg.ShowError($"No command '{id}' found."); break;
|
default: Msg.ShowError($"No command '{id}' found."); break;
|
||||||
}
|
}
|
||||||
|
|
||||||
MainForm.Instance.BeginInvoke(new Action(() => {
|
|
||||||
Message m = new Message() { Msg = 0x0202 }; // WM_LBUTTONUP
|
|
||||||
Native.SendMessage(MainForm.Instance.Handle, m.Msg, m.WParam, m.LParam);
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void InvokeOnMainThread(Action action) => MainForm.Instance.Invoke(action);
|
public static void InvokeOnMainThread(Action action) => MainForm.Instance.Invoke(action);
|
||||||
@@ -70,7 +74,7 @@ namespace mpvnet
|
|||||||
InvokeOnMainThread(new Action(() => {
|
InvokeOnMainThread(new Action(() => {
|
||||||
using (var d = new OpenFileDialog() { Multiselect = true })
|
using (var d = new OpenFileDialog() { Multiselect = true })
|
||||||
if (d.ShowDialog() == DialogResult.OK)
|
if (d.ShowDialog() == DialogResult.OK)
|
||||||
mp.Load(d.FileNames, loadFolder, append);
|
mp.LoadFiles(d.FileNames, loadFolder, append);
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -87,19 +91,34 @@ namespace mpvnet
|
|||||||
if (Directory.Exists(d.SelectedPath + "\\BDMV"))
|
if (Directory.Exists(d.SelectedPath + "\\BDMV"))
|
||||||
{
|
{
|
||||||
mp.set_property_string("bluray-device", d.SelectedPath);
|
mp.set_property_string("bluray-device", d.SelectedPath);
|
||||||
mp.Load(new[] { @"bd://" }, false, false);
|
mp.LoadFiles(new[] { @"bd://" }, false, false);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mp.set_property_string("dvd-device", d.SelectedPath);
|
mp.set_property_string("dvd-device", d.SelectedPath);
|
||||||
mp.Load(new[] { @"dvd://" }, false, false);
|
mp.LoadFiles(new[] { @"dvd://" }, false, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void PlaylistLast() => mp.set_property_int("playlist-pos", mp.get_property_int("playlist-count") - 1);
|
public static void PlaylistFirst()
|
||||||
|
{
|
||||||
|
int pos = mp.get_property_int("playlist-pos");
|
||||||
|
|
||||||
|
if (pos != 0)
|
||||||
|
mp.set_property_int("playlist-pos", 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void PlaylistLast()
|
||||||
|
{
|
||||||
|
int pos = mp.get_property_int("playlist-pos");
|
||||||
|
int count = mp.get_property_int("playlist-count");
|
||||||
|
|
||||||
|
if (pos < count - 1)
|
||||||
|
mp.set_property_int("playlist-pos", count - 1);
|
||||||
|
}
|
||||||
|
|
||||||
public static void ShowHistory()
|
public static void ShowHistory()
|
||||||
{
|
{
|
||||||
@@ -201,9 +220,9 @@ namespace mpvnet
|
|||||||
public static void ExecuteMpvCommand() // deprecated 2019
|
public static void ExecuteMpvCommand() // deprecated 2019
|
||||||
{
|
{
|
||||||
InvokeOnMainThread(new Action(() => {
|
InvokeOnMainThread(new Action(() => {
|
||||||
string command = VB.Interaction.InputBox("Enter a mpv command to be executed.", "Execute Command", RegHelp.GetString(App.RegPath, "RecentExecutedCommand"));
|
string command = VB.Interaction.InputBox("Enter a mpv command to be executed.", "Execute Command", RegistryHelp.GetString(App.RegPath, "RecentExecutedCommand"));
|
||||||
if (string.IsNullOrEmpty(command)) return;
|
if (string.IsNullOrEmpty(command)) return;
|
||||||
RegHelp.SetObject(App.RegPath, "RecentExecutedCommand", command);
|
RegistryHelp.SetValue(App.RegPath, "RecentExecutedCommand", command);
|
||||||
mp.command(command, false);
|
mp.command(command, false);
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
@@ -217,7 +236,7 @@ namespace mpvnet
|
|||||||
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.");
|
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;
|
return;
|
||||||
}
|
}
|
||||||
mp.Load(new [] { clipboard }, false, Control.ModifierKeys.HasFlag(Keys.Control));
|
mp.LoadFiles(new [] { clipboard }, false, Control.ModifierKeys.HasFlag(Keys.Control));
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -227,11 +246,15 @@ namespace mpvnet
|
|||||||
using (var d = new OpenFileDialog())
|
using (var d = new OpenFileDialog())
|
||||||
{
|
{
|
||||||
string path = mp.get_property_string("path");
|
string path = mp.get_property_string("path");
|
||||||
if (File.Exists(path)) d.InitialDirectory = Path.GetDirectoryName(path);
|
|
||||||
|
if (File.Exists(path))
|
||||||
|
d.InitialDirectory = Path.GetDirectoryName(path);
|
||||||
|
|
||||||
d.Multiselect = true;
|
d.Multiselect = true;
|
||||||
|
|
||||||
if (d.ShowDialog() == DialogResult.OK)
|
if (d.ShowDialog() == DialogResult.OK)
|
||||||
foreach (string i in d.FileNames)
|
foreach (string filename in d.FileNames)
|
||||||
mp.commandv("sub-add", i);
|
mp.commandv("sub-add", filename);
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
@@ -256,18 +279,83 @@ namespace mpvnet
|
|||||||
public static void CycleAudio()
|
public static void CycleAudio()
|
||||||
{
|
{
|
||||||
string path = mp.get_property_string("path");
|
string path = mp.get_property_string("path");
|
||||||
if (!File.Exists(path)) return;
|
|
||||||
|
if (!File.Exists(path))
|
||||||
|
return;
|
||||||
|
|
||||||
using (MediaInfo mi = new MediaInfo(path))
|
using (MediaInfo mi = new MediaInfo(path))
|
||||||
{
|
{
|
||||||
MediaTrack[] audTracks = mp.MediaTracks.Where(track => track.Type == "a").ToArray();
|
MediaTrack[] audTracks = mp.MediaTracks.Where(track => track.Type == "a").ToArray();
|
||||||
if (audTracks.Length < 2) return;
|
|
||||||
|
if (audTracks.Length < 2)
|
||||||
|
return;
|
||||||
|
|
||||||
int aid = mp.get_property_int("aid");
|
int aid = mp.get_property_int("aid");
|
||||||
aid += 1;
|
aid += 1;
|
||||||
if (aid > audTracks.Length) aid = 1;
|
|
||||||
|
if (aid > audTracks.Length)
|
||||||
|
aid = 1;
|
||||||
|
|
||||||
mp.commandv("set", "aid", aid.ToString());
|
mp.commandv("set", "aid", aid.ToString());
|
||||||
mp.commandv("show-text", audTracks[aid - 1].Text.Substring(3), "5000");
|
mp.commandv("show-text", audTracks[aid - 1].Text.Substring(3), "5000");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void ShowProfiles()
|
||||||
|
{
|
||||||
|
string code = @"
|
||||||
|
foreach ($item in ($json | ConvertFrom-Json | foreach { $_ } | sort name))
|
||||||
|
{
|
||||||
|
$item.name
|
||||||
|
''
|
||||||
|
|
||||||
|
foreach ($option in $item.options)
|
||||||
|
{
|
||||||
|
' ' + $option.key + ' = ' + $option.value
|
||||||
|
}
|
||||||
|
|
||||||
|
''
|
||||||
|
}";
|
||||||
|
|
||||||
|
string json = mp.get_property_string("profile-list");
|
||||||
|
string file = Path.GetTempPath() + @"\mpv profile-list.txt";
|
||||||
|
File.WriteAllText(file, BR + PowerShell.InvokeAndReturnString(code, "json", json));
|
||||||
|
Process.Start(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ShowCommands()
|
||||||
|
{
|
||||||
|
string code = @"
|
||||||
|
foreach ($item in ($json | ConvertFrom-Json | foreach { $_ } | sort name))
|
||||||
|
{
|
||||||
|
''
|
||||||
|
$item.name
|
||||||
|
|
||||||
|
foreach ($arg in $item.args)
|
||||||
|
{
|
||||||
|
$value = $arg.name + ' <' + $arg.type.ToLower() + '>'
|
||||||
|
|
||||||
|
if ($arg.optional -eq $true)
|
||||||
|
{
|
||||||
|
$value = '[' + $value + ']'
|
||||||
|
}
|
||||||
|
|
||||||
|
' ' + $value
|
||||||
|
}
|
||||||
|
}";
|
||||||
|
|
||||||
|
string json = mp.get_property_string("command-list");
|
||||||
|
string file = Path.GetTempPath() + @"\mpv command-list.txt";
|
||||||
|
File.WriteAllText(file, PowerShell.InvokeAndReturnString(code, "json", json) + BR);
|
||||||
|
Process.Start(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ShowProperties()
|
||||||
|
{
|
||||||
|
string file = Path.GetTempPath() + @"\mpv property-list.txt";
|
||||||
|
var props = mp.get_property_string("property-list").Split(',').OrderBy(prop => prop);
|
||||||
|
File.WriteAllText(file, BR + string.Join(BR, props) + BR);
|
||||||
|
Process.Start(file);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,11 +1,45 @@
|
|||||||
using System;
|
|
||||||
|
using System;
|
||||||
|
using System.Diagnostics;
|
||||||
|
|
||||||
class ConsoleHelp
|
public static class ConsoleHelp
|
||||||
{
|
{
|
||||||
public static void WriteError(object obj)
|
public static int Padding { get; set; }
|
||||||
|
|
||||||
|
public static void WriteError(object obj, string module = null) => Write(obj, module, ConsoleColor.Red, false);
|
||||||
|
|
||||||
|
public static void Write(object obj, string module = "mpv.net")
|
||||||
{
|
{
|
||||||
Console.ForegroundColor = ConsoleColor.Red;
|
Write(obj, module, ConsoleColor.Black, true);
|
||||||
Console.WriteLine(obj?.ToString());
|
}
|
||||||
|
|
||||||
|
public static void Write(object obj, string module, ConsoleColor color)
|
||||||
|
{
|
||||||
|
Write(obj, module, color, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Write(object obj, string module, ConsoleColor color, bool useDefaultColor)
|
||||||
|
{
|
||||||
|
if (obj == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
string value = obj.ToString();
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(module))
|
||||||
|
module = "[" + module + "] ";
|
||||||
|
|
||||||
|
if (useDefaultColor)
|
||||||
|
Console.ResetColor();
|
||||||
|
else
|
||||||
|
Console.ForegroundColor = color;
|
||||||
|
|
||||||
|
value = module + value;
|
||||||
|
|
||||||
|
if (Padding > 0 && value.Length < Padding)
|
||||||
|
value = value.PadRight(Padding);
|
||||||
|
|
||||||
|
Console.WriteLine(value);
|
||||||
Console.ResetColor();
|
Console.ResetColor();
|
||||||
|
Trace.WriteLine(obj);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -28,20 +28,6 @@ namespace mpvnet
|
|||||||
return (int)value == 0;
|
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>
|
public class StringLogicalComparer : IComparer, IComparer<string>
|
||||||
@@ -66,108 +52,51 @@ namespace mpvnet
|
|||||||
{
|
{
|
||||||
Types = types;
|
Types = types;
|
||||||
|
|
||||||
RegHelp.SetObject(@"HKCU\Software\Microsoft\Windows\CurrentVersion\App Paths\" + ExeFilename, null, ExePath);
|
RegistryHelp.SetValue(@"HKCU\Software\Microsoft\Windows\CurrentVersion\App Paths\" + ExeFilename, null, ExePath);
|
||||||
RegHelp.SetObject(@"HKCR\Applications\" + ExeFilename, "FriendlyAppName", "mpv.net media player");
|
RegistryHelp.SetValue(@"HKCR\Applications\" + ExeFilename, "FriendlyAppName", "mpv.net media player");
|
||||||
RegHelp.SetObject($@"HKCR\Applications\{ExeFilename}\shell\open\command", null, $"\"{ExePath}\" \"%1\"");
|
RegistryHelp.SetValue($@"HKCR\Applications\{ExeFilename}\shell\open\command", null, $"\"{ExePath}\" \"%1\"");
|
||||||
RegHelp.SetObject(@"HKLM\SOFTWARE\Clients\Media\mpv.net\Capabilities", "ApplicationDescription", "mpv.net media player");
|
RegistryHelp.SetValue(@"HKLM\SOFTWARE\Clients\Media\mpv.net\Capabilities", "ApplicationDescription", "mpv.net media player");
|
||||||
RegHelp.SetObject(@"HKLM\SOFTWARE\Clients\Media\mpv.net\Capabilities", "ApplicationName", "mpv.net");
|
RegistryHelp.SetValue(@"HKLM\SOFTWARE\Clients\Media\mpv.net\Capabilities", "ApplicationName", "mpv.net");
|
||||||
RegHelp.SetObject(@"HKCR\SystemFileAssociations\video\OpenWithList\" + ExeFilename, null, "");
|
RegistryHelp.SetValue(@"HKCR\SystemFileAssociations\video\OpenWithList\" + ExeFilename, null, "");
|
||||||
RegHelp.SetObject(@"HKCR\SystemFileAssociations\audio\OpenWithList\" + ExeFilename, null, "");
|
RegistryHelp.SetValue(@"HKCR\SystemFileAssociations\audio\OpenWithList\" + ExeFilename, null, "");
|
||||||
RegHelp.SetObject(@"HKLM\SOFTWARE\RegisteredApplications", "mpv.net", @"SOFTWARE\Clients\Media\mpv.net\Capabilities");
|
RegistryHelp.SetValue(@"HKLM\SOFTWARE\RegisteredApplications", "mpv.net", @"SOFTWARE\Clients\Media\mpv.net\Capabilities");
|
||||||
|
|
||||||
foreach (string ext in Types)
|
foreach (string ext in Types)
|
||||||
{
|
{
|
||||||
RegHelp.SetObject($@"HKCR\Applications\{ExeFilename}\SupportedTypes", "." + ext, "");
|
RegistryHelp.SetValue($@"HKCR\Applications\{ExeFilename}\SupportedTypes", "." + ext, "");
|
||||||
RegHelp.SetObject($@"HKCR\" + "." + ext, null, ExeFilenameNoExt + "." + ext);
|
RegistryHelp.SetValue($@"HKCR\" + "." + ext, null, ExeFilenameNoExt + "." + ext);
|
||||||
RegHelp.SetObject($@"HKCR\" + "." + ext + @"\OpenWithProgIDs", ExeFilenameNoExt + "." + ext, "");
|
RegistryHelp.SetValue($@"HKCR\" + "." + ext + @"\OpenWithProgIDs", ExeFilenameNoExt + "." + ext, "");
|
||||||
|
|
||||||
if (App.VideoTypes.Contains(ext))
|
if (App.VideoTypes.Contains(ext))
|
||||||
RegHelp.SetObject(@"HKCR\" + "." + ext, "PerceivedType", "video");
|
RegistryHelp.SetValue(@"HKCR\" + "." + ext, "PerceivedType", "video");
|
||||||
|
|
||||||
if (App.AudioTypes.Contains(ext))
|
if (App.AudioTypes.Contains(ext))
|
||||||
RegHelp.SetObject(@"HKCR\" + "." + ext, "PerceivedType", "audio");
|
RegistryHelp.SetValue(@"HKCR\" + "." + ext, "PerceivedType", "audio");
|
||||||
|
|
||||||
if (App.ImageTypes.Contains(ext))
|
if (App.ImageTypes.Contains(ext))
|
||||||
RegHelp.SetObject(@"HKCR\" + "." + ext, "PerceivedType", "image");
|
RegistryHelp.SetValue(@"HKCR\" + "." + ext, "PerceivedType", "image");
|
||||||
|
|
||||||
RegHelp.SetObject($@"HKCR\" + ExeFilenameNoExt + "." + ext + @"\shell\open", null, "Play with " + Application.ProductName);
|
RegistryHelp.SetValue($@"HKCR\" + ExeFilenameNoExt + "." + ext + @"\shell\open\command", null, $"\"{ExePath}\" \"%1\"");
|
||||||
RegHelp.SetObject($@"HKCR\" + ExeFilenameNoExt + "." + ext + @"\shell\open\command", null, $"\"{ExePath}\" \"%1\"");
|
RegistryHelp.SetValue(@"HKLM\SOFTWARE\Clients\Media\mpv.net\Capabilities\FileAssociations", "." + ext, ExeFilenameNoExt + "." + ext);
|
||||||
RegHelp.SetObject(@"HKLM\SOFTWARE\Clients\Media\mpv.net\Capabilities\FileAssociations", "." + ext, ExeFilenameNoExt + "." + ext);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Unregister()
|
public static void Unregister()
|
||||||
{
|
{
|
||||||
RegHelp.RemoveKey($@"HKCU\Software\Microsoft\Windows\CurrentVersion\App Paths\" + ExeFilename);
|
RegistryHelp.RemoveKey($@"HKCU\Software\Microsoft\Windows\CurrentVersion\App Paths\" + ExeFilename);
|
||||||
RegHelp.RemoveKey($@"HKCR\Applications\" + ExeFilename);
|
RegistryHelp.RemoveKey($@"HKCR\Applications\" + ExeFilename);
|
||||||
RegHelp.RemoveKey($@"HKLM\SOFTWARE\Clients\Media\mpv.net");
|
RegistryHelp.RemoveKey($@"HKLM\SOFTWARE\Clients\Media\mpv.net");
|
||||||
RegHelp.RemoveKey($@"HKCR\SystemFileAssociations\video\OpenWithList\" + ExeFilename);
|
RegistryHelp.RemoveKey($@"HKCR\SystemFileAssociations\video\OpenWithList\" + ExeFilename);
|
||||||
RegHelp.RemoveKey($@"HKCR\SystemFileAssociations\audio\OpenWithList\" + ExeFilename);
|
RegistryHelp.RemoveKey($@"HKCR\SystemFileAssociations\audio\OpenWithList\" + ExeFilename);
|
||||||
RegHelp.RemoveValue(@"HKLM\SOFTWARE\RegisteredApplications", "mpv.net");
|
RegistryHelp.RemoveValue(@"HKLM\SOFTWARE\RegisteredApplications", "mpv.net");
|
||||||
|
|
||||||
foreach (string id in Registry.ClassesRoot.GetSubKeyNames())
|
foreach (string id in Registry.ClassesRoot.GetSubKeyNames())
|
||||||
{
|
{
|
||||||
if (id.StartsWith(ExeFilenameNoExt + "."))
|
if (id.StartsWith(ExeFilenameNoExt + "."))
|
||||||
Registry.ClassesRoot.DeleteSubKeyTree(id);
|
Registry.ClassesRoot.DeleteSubKeyTree(id);
|
||||||
|
|
||||||
RegHelp.RemoveValue($@"HKCR\Software\Classes\{id}\OpenWithProgIDs", ExeFilenameNoExt + id);
|
RegistryHelp.RemoveValue($@"HKCR\Software\Classes\{id}\OpenWithProgIDs", ExeFilenameNoExt + id);
|
||||||
RegHelp.RemoveValue($@"HKLM\Software\Classes\{id}\OpenWithProgIDs", ExeFilenameNoExt + id);
|
RegistryHelp.RemoveValue($@"HKLM\Software\Classes\{id}\OpenWithProgIDs", ExeFilenameNoExt + id);
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class RegHelp
|
|
||||||
{
|
|
||||||
public static void SetObject(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 = GetObject(path, name, defaultValue);
|
|
||||||
return !(value is string) ? defaultValue : value.ToString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int GetInt(string path, string name, int defaultValue = 0)
|
|
||||||
{
|
|
||||||
object value = GetObject(path, name, defaultValue);
|
|
||||||
return !(value is int) ? defaultValue : (int)value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static object GetObject(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();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -190,12 +119,12 @@ namespace mpvnet
|
|||||||
|
|
||||||
public CommandItem(SerializationInfo info, StreamingContext context) { }
|
public CommandItem(SerializationInfo info, StreamingContext context) { }
|
||||||
|
|
||||||
private void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
|
void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
|
||||||
{
|
{
|
||||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||||
}
|
}
|
||||||
|
|
||||||
private string _Input = "";
|
string _Input = "";
|
||||||
|
|
||||||
public string Input {
|
public string Input {
|
||||||
get => _Input;
|
get => _Input;
|
||||||
@@ -246,14 +175,13 @@ namespace mpvnet
|
|||||||
if (item.Command.ToLower() == "ignore")
|
if (item.Command.ToLower() == "ignore")
|
||||||
item.Command = "";
|
item.Command = "";
|
||||||
|
|
||||||
MigrateCommands(item);
|
|
||||||
items.Add(item);
|
items.Add(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return items;
|
return items;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ObservableCollection<CommandItem> _Items;
|
static ObservableCollection<CommandItem> _Items;
|
||||||
|
|
||||||
public static ObservableCollection<CommandItem> Items {
|
public static ObservableCollection<CommandItem> Items {
|
||||||
get {
|
get {
|
||||||
@@ -263,25 +191,6 @@ namespace mpvnet
|
|||||||
return _Items;
|
return _Items;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void MigrateCommands(CommandItem item)
|
|
||||||
{
|
|
||||||
switch (item.Command)
|
|
||||||
{
|
|
||||||
case "script-message mpv.net show-prefs":
|
|
||||||
item.Command = "script-message mpv.net show-conf-editor";
|
|
||||||
break;
|
|
||||||
case "script-message mpv.net show-keys":
|
|
||||||
item.Command = "script-message mpv.net show-input-editor";
|
|
||||||
break;
|
|
||||||
case "script-message mpv.net history":
|
|
||||||
item.Command = "script-message mpv.net show-history";
|
|
||||||
break;
|
|
||||||
case "script-message mpv.net open-config-folder":
|
|
||||||
item.Command = "script-message open-conf-folder";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class CursorHelp
|
public class CursorHelp
|
||||||
@@ -316,32 +225,6 @@ namespace mpvnet
|
|||||||
|
|
||||||
public class Folder
|
public class Folder
|
||||||
{
|
{
|
||||||
public static string Startup { get; } = Application.StartupPath + "\\";
|
public static string Startup { get; } = Application.StartupPath + @"\";
|
||||||
}
|
|
||||||
|
|
||||||
public class PathHelp
|
|
||||||
{
|
|
||||||
public static string GetBaseName(string value)
|
|
||||||
{
|
|
||||||
if (string.IsNullOrEmpty(value))
|
|
||||||
return "";
|
|
||||||
|
|
||||||
int index = value.IndexOf("/");
|
|
||||||
|
|
||||||
if (index > -1)
|
|
||||||
value = value.Substring(index + 1);
|
|
||||||
|
|
||||||
index = value.IndexOf("\\");
|
|
||||||
|
|
||||||
if (index > -1)
|
|
||||||
value = value.Substring(index + 1);
|
|
||||||
|
|
||||||
index = value.LastIndexOf(".");
|
|
||||||
|
|
||||||
if (index > -1)
|
|
||||||
value = value.Substring(0, index);
|
|
||||||
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
8
mpv.net/Misc/NewLine.cs
Normal file
8
mpv.net/Misc/NewLine.cs
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
|
||||||
|
using System;
|
||||||
|
|
||||||
|
public static class NewLine
|
||||||
|
{
|
||||||
|
public static string BR = Environment.NewLine;
|
||||||
|
public static string BR2 = Environment.NewLine + Environment.NewLine;
|
||||||
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
|
||||||
|
using System;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
@@ -18,7 +19,7 @@ namespace mpvnet
|
|||||||
Application.SetCompatibleTextRenderingDefault(false);
|
Application.SetCompatibleTextRenderingDefault(false);
|
||||||
|
|
||||||
if (App.IsStartedFromTerminal)
|
if (App.IsStartedFromTerminal)
|
||||||
Native.AttachConsole(-1 /*ATTACH_PARENT_PROCESS*/);
|
WinAPI.AttachConsole(-1 /*ATTACH_PARENT_PROCESS*/);
|
||||||
|
|
||||||
if (mp.ConfigFolder == "")
|
if (mp.ConfigFolder == "")
|
||||||
return;
|
return;
|
||||||
@@ -60,15 +61,15 @@ namespace mpvnet
|
|||||||
{
|
{
|
||||||
if (proc.MainWindowHandle != IntPtr.Zero)
|
if (proc.MainWindowHandle != IntPtr.Zero)
|
||||||
{
|
{
|
||||||
Native.AllowSetForegroundWindow(proc.Id);
|
WinAPI.AllowSetForegroundWindow(proc.Id);
|
||||||
var data = new Native.COPYDATASTRUCT();
|
var data = new WinAPI.COPYDATASTRUCT();
|
||||||
data.lpData = string.Join("\n", files.ToArray());
|
data.lpData = string.Join("\n", files.ToArray());
|
||||||
data.cbData = data.lpData.Length * 2 + 1;
|
data.cbData = data.lpData.Length * 2 + 1;
|
||||||
Native.SendMessage(proc.MainWindowHandle, 0x004A /*WM_COPYDATA*/, IntPtr.Zero, ref data);
|
WinAPI.SendMessage(proc.MainWindowHandle, 0x004A /*WM_COPYDATA*/, IntPtr.Zero, ref data);
|
||||||
mutex.Dispose();
|
mutex.Dispose();
|
||||||
|
|
||||||
if (App.IsStartedFromTerminal)
|
if (App.IsStartedFromTerminal)
|
||||||
Native.FreeConsole();
|
WinAPI.FreeConsole();
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -84,7 +85,7 @@ namespace mpvnet
|
|||||||
Application.Run(new MainForm());
|
Application.Run(new MainForm());
|
||||||
|
|
||||||
if (App.IsStartedFromTerminal)
|
if (App.IsStartedFromTerminal)
|
||||||
Native.FreeConsole();
|
WinAPI.FreeConsole();
|
||||||
|
|
||||||
mutex.Dispose();
|
mutex.Dispose();
|
||||||
}
|
}
|
||||||
|
|||||||
70
mpv.net/Misc/RegistryHelp.cs
Normal file
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -45,7 +45,7 @@ namespace UI
|
|||||||
if (!theme.Dictionary.ContainsKey(key))
|
if (!theme.Dictionary.ContainsKey(key))
|
||||||
{
|
{
|
||||||
isKeyMissing = true;
|
isKeyMissing = true;
|
||||||
ConsoleHelp.WriteError($"Theme '{activeTheme}' misses '{key}'");
|
ConsoleHelp.WriteError($"Theme '{activeTheme}' misses '{key}'", "mpv.net");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
77
mpv.net/Misc/UpdateCheck.cs
Normal file
77
mpv.net/Misc/UpdateCheck.cs
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
|
||||||
|
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() || showUpToDateMessage) && 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.UseShellExecute = true;
|
||||||
|
proc.StartInfo.WorkingDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
|
||||||
|
proc.StartInfo.FileName = "PowerShell";
|
||||||
|
proc.StartInfo.Arguments = $"-NoLogo -NoExit -File \"{Folder.Startup + "Update.ps1"}\" \"{url}\" \"{Application.StartupPath.TrimEnd('\\')}\"";
|
||||||
|
|
||||||
|
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,45 +1,44 @@
|
|||||||
using System;
|
|
||||||
|
using System;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
public class MediaInfo : IDisposable
|
public class MediaInfo : IDisposable
|
||||||
{
|
{
|
||||||
IntPtr Handle;
|
IntPtr Handle;
|
||||||
static bool Loaded;
|
|
||||||
|
|
||||||
public MediaInfo(string sourcepath)
|
public MediaInfo(string file)
|
||||||
{
|
{
|
||||||
if (!Loaded)
|
if ((Handle = MediaInfo_New()) == IntPtr.Zero)
|
||||||
{
|
throw new Exception("Failed to call MediaInfo_New");
|
||||||
if (Native.LoadLibrary("MediaInfo.dll") == IntPtr.Zero)
|
|
||||||
throw new Exception("Failed to load MediaInfo.dll.");
|
|
||||||
|
|
||||||
Loaded = true;
|
if (MediaInfo_Open(Handle, file) == 0)
|
||||||
}
|
throw new Exception("Error MediaInfo_Open");
|
||||||
|
|
||||||
Handle = MediaInfo_New();
|
|
||||||
MediaInfo_Open(Handle, sourcepath);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GetInfo(MediaInfoStreamKind streamKind, string parameter)
|
public string GetInfo(MediaInfoStreamKind kind, string parameter)
|
||||||
{
|
{
|
||||||
return Marshal.PtrToStringUni(MediaInfo_Get(Handle, streamKind, 0, parameter, MediaInfoInfoKind.Text, MediaInfoInfoKind.Name));
|
return Marshal.PtrToStringUni(MediaInfo_Get(Handle, kind, 0,
|
||||||
|
parameter, MediaInfoKind.Text, MediaInfoKind.Name));
|
||||||
}
|
}
|
||||||
|
|
||||||
public int GetCount(MediaInfoStreamKind streamKind) => MediaInfo_Count_Get(Handle, streamKind, -1);
|
public int GetCount(MediaInfoStreamKind kind) => MediaInfo_Count_Get(Handle, kind, -1);
|
||||||
|
|
||||||
public string GetVideo(int streamNumber, string parameter)
|
public string GetVideo(int stream, string parameter)
|
||||||
{
|
{
|
||||||
return Marshal.PtrToStringUni(MediaInfo_Get(Handle, MediaInfoStreamKind.Video, streamNumber, parameter, MediaInfoInfoKind.Text, MediaInfoInfoKind.Name));
|
return Marshal.PtrToStringUni(MediaInfo_Get(Handle, MediaInfoStreamKind.Video,
|
||||||
|
stream, parameter, MediaInfoKind.Text, MediaInfoKind.Name));
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GetAudio(int streamNumber, string parameter)
|
public string GetAudio(int stream, string parameter)
|
||||||
{
|
{
|
||||||
return Marshal.PtrToStringUni(MediaInfo_Get(Handle, MediaInfoStreamKind.Audio, streamNumber, parameter, MediaInfoInfoKind.Text, MediaInfoInfoKind.Name));
|
return Marshal.PtrToStringUni(MediaInfo_Get(Handle, MediaInfoStreamKind.Audio,
|
||||||
|
stream, parameter, MediaInfoKind.Text, MediaInfoKind.Name));
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GetText(int streamNumber, string parameter)
|
public string GetText(int stream, string parameter)
|
||||||
{
|
{
|
||||||
return Marshal.PtrToStringUni(MediaInfo_Get(Handle, MediaInfoStreamKind.Text, streamNumber, parameter, MediaInfoInfoKind.Text, MediaInfoInfoKind.Name));
|
return Marshal.PtrToStringUni(MediaInfo_Get(Handle, MediaInfoStreamKind.Text,
|
||||||
|
stream, parameter, MediaInfoKind.Text, MediaInfoKind.Name));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Disposed;
|
bool Disposed;
|
||||||
@@ -48,13 +47,20 @@ public class MediaInfo : IDisposable
|
|||||||
{
|
{
|
||||||
if (!Disposed)
|
if (!Disposed)
|
||||||
{
|
{
|
||||||
|
if (Handle != IntPtr.Zero)
|
||||||
|
{
|
||||||
|
MediaInfo_Close(Handle);
|
||||||
|
MediaInfo_Delete(Handle);
|
||||||
|
}
|
||||||
|
|
||||||
Disposed = true;
|
Disposed = true;
|
||||||
MediaInfo_Close(Handle);
|
|
||||||
MediaInfo_Delete(Handle);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
~MediaInfo() { Dispose(); }
|
~MediaInfo()
|
||||||
|
{
|
||||||
|
Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
[DllImport("MediaInfo.dll")]
|
[DllImport("MediaInfo.dll")]
|
||||||
static extern IntPtr MediaInfo_New();
|
static extern IntPtr MediaInfo_New();
|
||||||
@@ -63,7 +69,7 @@ public class MediaInfo : IDisposable
|
|||||||
static extern int MediaInfo_Open(IntPtr handle, string path);
|
static extern int MediaInfo_Open(IntPtr handle, string path);
|
||||||
|
|
||||||
[DllImport("MediaInfo.dll", CharSet = CharSet.Unicode)]
|
[DllImport("MediaInfo.dll", CharSet = CharSet.Unicode)]
|
||||||
static extern IntPtr MediaInfo_Option(IntPtr handle, string optionString, string value);
|
static extern IntPtr MediaInfo_Option(IntPtr handle, string option, string value);
|
||||||
|
|
||||||
[DllImport("MediaInfo.dll")]
|
[DllImport("MediaInfo.dll")]
|
||||||
static extern IntPtr MediaInfo_Inform(IntPtr handle, int reserved);
|
static extern IntPtr MediaInfo_Inform(IntPtr handle, int reserved);
|
||||||
@@ -75,17 +81,11 @@ public class MediaInfo : IDisposable
|
|||||||
static extern void MediaInfo_Delete(IntPtr handle);
|
static extern void MediaInfo_Delete(IntPtr handle);
|
||||||
|
|
||||||
[DllImport("MediaInfo.dll", CharSet = CharSet.Unicode)]
|
[DllImport("MediaInfo.dll", CharSet = CharSet.Unicode)]
|
||||||
static extern IntPtr MediaInfo_Get(IntPtr handle,
|
static extern IntPtr MediaInfo_Get(IntPtr handle, MediaInfoStreamKind kind,
|
||||||
MediaInfoStreamKind streamKind,
|
int stream, string parameter, MediaInfoKind infoKind, MediaInfoKind searchKind);
|
||||||
int streamNumber,
|
|
||||||
string parameter,
|
|
||||||
MediaInfoInfoKind kindOfInfo,
|
|
||||||
MediaInfoInfoKind kindOfSearch);
|
|
||||||
|
|
||||||
[DllImport("MediaInfo.dll", CharSet = CharSet.Unicode)]
|
[DllImport("MediaInfo.dll", CharSet = CharSet.Unicode)]
|
||||||
static extern int MediaInfo_Count_Get(IntPtr handle,
|
static extern int MediaInfo_Count_Get(IntPtr handle, MediaInfoStreamKind streamKind, int stream);
|
||||||
MediaInfoStreamKind streamKind,
|
|
||||||
int streamNumber);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum MediaInfoStreamKind
|
public enum MediaInfoStreamKind
|
||||||
@@ -100,7 +100,7 @@ public enum MediaInfoStreamKind
|
|||||||
Max,
|
Max,
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum MediaInfoInfoKind
|
public enum MediaInfoKind
|
||||||
{
|
{
|
||||||
Name,
|
Name,
|
||||||
Text,
|
Text,
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
using System;
|
|
||||||
|
using System;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
public class Native
|
public class WinAPI
|
||||||
{
|
{
|
||||||
[DllImport("kernel32.dll")]
|
[DllImport("kernel32.dll")]
|
||||||
public static extern bool AttachConsole(int dwProcessId);
|
public static extern bool AttachConsole(int dwProcessId);
|
||||||
@@ -38,13 +39,13 @@ public class Native
|
|||||||
public static extern bool AdjustWindowRect(ref RECT lpRect, uint dwStyle, bool bMenu);
|
public static extern bool AdjustWindowRect(ref RECT lpRect, uint dwStyle, bool bMenu);
|
||||||
|
|
||||||
[DllImport("user32.dll")]
|
[DllImport("user32.dll")]
|
||||||
public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, int uFlags);
|
public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int x, int y, int cx, int cy, uint uFlags);
|
||||||
|
|
||||||
[DllImport("user32.dll", EntryPoint = "GetWindowLong")]
|
[DllImport("user32.dll", EntryPoint = "GetWindowLong")]
|
||||||
private static extern IntPtr GetWindowLong32(IntPtr hWnd, int nIndex);
|
static extern IntPtr GetWindowLong32(IntPtr hWnd, int nIndex);
|
||||||
|
|
||||||
[DllImport("user32.dll", EntryPoint = "GetWindowLongPtr")]
|
[DllImport("user32.dll", EntryPoint = "GetWindowLongPtr")]
|
||||||
private static extern IntPtr GetWindowLong64(IntPtr hWnd, int nIndex);
|
static extern IntPtr GetWindowLong64(IntPtr hWnd, int nIndex);
|
||||||
|
|
||||||
public static IntPtr GetWindowLong(IntPtr hWnd, int nIndex)
|
public static IntPtr GetWindowLong(IntPtr hWnd, int nIndex)
|
||||||
{
|
{
|
||||||
@@ -54,6 +55,9 @@ public class Native
|
|||||||
return GetWindowLong32(hWnd, nIndex);
|
return GetWindowLong32(hWnd, nIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[DllImport("gdi32.dll")]
|
||||||
|
public static extern int GetDeviceCaps(IntPtr hdc, int nIndex);
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential)]
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
public struct RECT
|
public struct RECT
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -20,9 +20,9 @@ namespace mpvnet
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void SubtractWindowBorders(IntPtr hwnd, ref Native.RECT rc)
|
public static void SubtractWindowBorders(IntPtr hwnd, ref WinAPI.RECT rc)
|
||||||
{
|
{
|
||||||
var b = new Native.RECT(0, 0, 0, 0);
|
var b = new WinAPI.RECT(0, 0, 0, 0);
|
||||||
AddWindowBorders(hwnd, ref b);
|
AddWindowBorders(hwnd, ref b);
|
||||||
rc.Left -= b.Left;
|
rc.Left -= b.Left;
|
||||||
rc.Top -= b.Top;
|
rc.Top -= b.Top;
|
||||||
@@ -30,9 +30,9 @@ namespace mpvnet
|
|||||||
rc.Bottom -= b.Bottom;
|
rc.Bottom -= b.Bottom;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void AddWindowBorders(IntPtr hwnd, ref Native.RECT rc)
|
public static void AddWindowBorders(IntPtr hwnd, ref WinAPI.RECT rc)
|
||||||
{
|
{
|
||||||
Native.AdjustWindowRect(ref rc, (uint)Native.GetWindowLong(hwnd, -16 /* GWL_STYLE */), false);
|
WinAPI.AdjustWindowRect(ref rc, (uint)WinAPI.GetWindowLong(hwnd, -16 /* GWL_STYLE */), false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
|
||||||
|
using System;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
@@ -11,7 +12,7 @@ using System.Windows.Forms;
|
|||||||
|
|
||||||
public class Msg
|
public class Msg
|
||||||
{
|
{
|
||||||
private static string ShownMessages;
|
static string ShownMessages;
|
||||||
|
|
||||||
public static string SupportURL { get; set; }
|
public static string SupportURL { get; set; }
|
||||||
|
|
||||||
@@ -66,7 +67,7 @@ public class Msg
|
|||||||
td.MainInstruction = exception.GetType().Name;
|
td.MainInstruction = exception.GetType().Name;
|
||||||
td.Content = exception.Message;
|
td.Content = exception.Message;
|
||||||
td.MainIcon = MsgIcon.Error;
|
td.MainIcon = MsgIcon.Error;
|
||||||
td.ExpandedInformation = exception.ToString();
|
td.ExpandedInformation = exception.StackTrace;
|
||||||
td.Footer = "[Copy Message](copymsg)";
|
td.Footer = "[Copy Message](copymsg)";
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(Msg.SupportURL))
|
if (!string.IsNullOrEmpty(Msg.SupportURL))
|
||||||
@@ -77,8 +78,7 @@ public class Msg
|
|||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
MessageBox.Show(e.GetType().Name + "\n\n" + e.Message + "\n\n" + e,
|
MessageBox.Show(e.ToString(), Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -95,24 +95,24 @@ public class Msg
|
|||||||
Msg.ShownMessages += mainInstruction + content;
|
Msg.ShownMessages += mainInstruction + content;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static MsgResult ShowQuestion(string mainInstruction,
|
public static MsgResult ShowQuestion(
|
||||||
MsgButtons buttons = MsgButtons.OkCancel)
|
string mainInstruction, MsgButtons buttons = MsgButtons.OkCancel)
|
||||||
{
|
{
|
||||||
return Msg.Show(mainInstruction, null, MsgIcon.None, buttons, MsgResult.None);
|
return Msg.Show(mainInstruction, null, MsgIcon.None, buttons, MsgResult.None);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static MsgResult ShowQuestion(string mainInstruction,
|
public static MsgResult ShowQuestion(
|
||||||
string content,
|
string mainInstruction, string content, MsgButtons buttons = MsgButtons.OkCancel)
|
||||||
MsgButtons buttons = MsgButtons.OkCancel)
|
|
||||||
{
|
{
|
||||||
return Msg.Show(mainInstruction, content, MsgIcon.None, buttons, MsgResult.None);
|
return Msg.Show(mainInstruction, content, MsgIcon.None, buttons, MsgResult.None);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static MsgResult Show(string mainInstruction,
|
public static MsgResult Show(
|
||||||
string content,
|
string mainInstruction,
|
||||||
MsgIcon icon,
|
string content,
|
||||||
MsgButtons buttons,
|
MsgIcon icon,
|
||||||
MsgResult defaultButton = MsgResult.None)
|
MsgButtons buttons,
|
||||||
|
MsgResult defaultButton = MsgResult.None)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -154,14 +154,20 @@ public class Msg
|
|||||||
|
|
||||||
public class TaskDialog<T> : TaskDialogNative, IDisposable
|
public class TaskDialog<T> : TaskDialogNative, IDisposable
|
||||||
{
|
{
|
||||||
private Dictionary<int, T> IdValueDic;
|
Dictionary<int, T> IdValueDic;
|
||||||
private Dictionary<int, string> IdTextDic;
|
Dictionary<int, string> IdTextDic;
|
||||||
private List<int> CommandLinkShieldList;
|
List<int> CommandLinkShieldList;
|
||||||
private IntPtr ButtonArray;
|
IntPtr ButtonArray;
|
||||||
private IntPtr RadioButtonArray;
|
IntPtr RadioButtonArray;
|
||||||
private List<TaskDialogNative.TASKDIALOG_BUTTON> Buttons;
|
T SelectedValueValue;
|
||||||
private List<TaskDialogNative.TASKDIALOG_BUTTON> RadioButtons;
|
string SelectedTextValue;
|
||||||
private TaskDialogNative.TASKDIALOGCONFIG Config;
|
int TimeoutValue;
|
||||||
|
int ExitTickCount;
|
||||||
|
bool Disposed;
|
||||||
|
List<TaskDialogNative.TASKDIALOG_BUTTON> Buttons;
|
||||||
|
List<TaskDialogNative.TASKDIALOG_BUTTON> RadioButtons;
|
||||||
|
TaskDialogNative.TASKDIALOGCONFIG Config;
|
||||||
|
|
||||||
const int TDE_CONTENT = 0;
|
const int TDE_CONTENT = 0;
|
||||||
const int TDE_EXPANDED_INFORMATION = 1;
|
const int TDE_EXPANDED_INFORMATION = 1;
|
||||||
const int TDE_FOOTER = 2;
|
const int TDE_FOOTER = 2;
|
||||||
@@ -192,11 +198,6 @@ public class TaskDialog<T> : TaskDialogNative, IDisposable
|
|||||||
const int TDM_UPDATE_ELEMENT_TEXT = 1138;
|
const int TDM_UPDATE_ELEMENT_TEXT = 1138;
|
||||||
const int TDM_SET_BUTTON_ELEVATION_REQUIRED_STATE = 1139;
|
const int TDM_SET_BUTTON_ELEVATION_REQUIRED_STATE = 1139;
|
||||||
const int TDM_UPDATE_ICON = 1140;
|
const int TDM_UPDATE_ICON = 1140;
|
||||||
private T SelectedValueValue;
|
|
||||||
private string SelectedTextValue;
|
|
||||||
private int TimeoutValue;
|
|
||||||
private int ExitTickCount;
|
|
||||||
private bool disposed;
|
|
||||||
|
|
||||||
public TaskDialog()
|
public TaskDialog()
|
||||||
{
|
{
|
||||||
@@ -284,13 +285,14 @@ public class TaskDialog<T> : TaskDialogNative, IDisposable
|
|||||||
set => Config.MainIcon = new TaskDialogNative.TASKDIALOGCONFIG_ICON_UNION((int)value);
|
set => Config.MainIcon = new TaskDialogNative.TASKDIALOGCONFIG_ICON_UNION((int)value);
|
||||||
}
|
}
|
||||||
|
|
||||||
private int _SelectedID;
|
int _SelectedID;
|
||||||
|
|
||||||
public int SelectedID {
|
public int SelectedID {
|
||||||
get => _SelectedID;
|
get => _SelectedID;
|
||||||
set {
|
set {
|
||||||
foreach (var i in IdValueDic)
|
foreach (var i in IdValueDic)
|
||||||
if (i.Key == value) _SelectedID = value;
|
if (i.Key == value)
|
||||||
|
_SelectedID = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -298,6 +300,7 @@ public class TaskDialog<T> : TaskDialogNative, IDisposable
|
|||||||
get {
|
get {
|
||||||
if (IdValueDic.ContainsKey(SelectedID))
|
if (IdValueDic.ContainsKey(SelectedID))
|
||||||
return IdValueDic[SelectedID];
|
return IdValueDic[SelectedID];
|
||||||
|
|
||||||
return SelectedValueValue;
|
return SelectedValueValue;
|
||||||
}
|
}
|
||||||
set => SelectedValueValue = value;
|
set => SelectedValueValue = value;
|
||||||
@@ -307,13 +310,15 @@ public class TaskDialog<T> : TaskDialogNative, IDisposable
|
|||||||
get {
|
get {
|
||||||
if (IdTextDic.ContainsKey(SelectedID))
|
if (IdTextDic.ContainsKey(SelectedID))
|
||||||
return IdTextDic[SelectedID];
|
return IdTextDic[SelectedID];
|
||||||
|
|
||||||
return SelectedTextValue;
|
return SelectedTextValue;
|
||||||
}
|
}
|
||||||
set => SelectedTextValue = value;
|
set => SelectedTextValue = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool CheckBoxChecked {
|
public bool CheckBoxChecked {
|
||||||
get => (Config.dwFlags & TaskDialogNative.TASKDIALOG_FLAGS.TDF_VERIFICATION_FLAG_CHECKED) == TaskDialogNative.TASKDIALOG_FLAGS.TDF_VERIFICATION_FLAG_CHECKED;
|
get => (Config.dwFlags & TaskDialogNative.TASKDIALOG_FLAGS.TDF_VERIFICATION_FLAG_CHECKED)
|
||||||
|
== TaskDialogNative.TASKDIALOG_FLAGS.TDF_VERIFICATION_FLAG_CHECKED;
|
||||||
set {
|
set {
|
||||||
if (value)
|
if (value)
|
||||||
Config.dwFlags |= TaskDialogNative.TASKDIALOG_FLAGS.TDF_VERIFICATION_FLAG_CHECKED;
|
Config.dwFlags |= TaskDialogNative.TASKDIALOG_FLAGS.TDF_VERIFICATION_FLAG_CHECKED;
|
||||||
@@ -354,10 +359,11 @@ public class TaskDialog<T> : TaskDialogNative, IDisposable
|
|||||||
value = regex.Replace(value, "<a href=\"$2\">$1</a>");
|
value = regex.Replace(value, "<a href=\"$2\">$1</a>");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddCommandLink(string text, T value)
|
public void AddCommand(string text, T value)
|
||||||
{
|
{
|
||||||
int n = 1000 + IdValueDic.Count + 1;
|
int n = 1000 + IdValueDic.Count + 1;
|
||||||
IdValueDic[n] = value;
|
IdValueDic[n] = value;
|
||||||
@@ -366,12 +372,17 @@ public class TaskDialog<T> : TaskDialogNative, IDisposable
|
|||||||
Config.dwFlags |= TaskDialogNative.TASKDIALOG_FLAGS.TDF_USE_COMMAND_LINKS;
|
Config.dwFlags |= TaskDialogNative.TASKDIALOG_FLAGS.TDF_USE_COMMAND_LINKS;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddCommandLink(string text, string description, T value, bool setShield = false)
|
public void AddCommand(string text, string description, T value, bool setShield = false)
|
||||||
{
|
{
|
||||||
int n = 1000 + IdValueDic.Count + 1;
|
int n = 1000 + IdValueDic.Count + 1;
|
||||||
IdValueDic[n] = value;
|
IdValueDic[n] = value;
|
||||||
if (setShield) CommandLinkShieldList.Add(n);
|
|
||||||
if (!string.IsNullOrEmpty(description)) text += "\n" + description;
|
if (setShield)
|
||||||
|
CommandLinkShieldList.Add(n);
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(description))
|
||||||
|
text += "\n" + description;
|
||||||
|
|
||||||
Buttons.Add(new TaskDialogNative.TASKDIALOG_BUTTON(n, text));
|
Buttons.Add(new TaskDialogNative.TASKDIALOG_BUTTON(n, text));
|
||||||
Config.dwFlags |= TaskDialogNative.TASKDIALOG_FLAGS.TDF_USE_COMMAND_LINKS;
|
Config.dwFlags |= TaskDialogNative.TASKDIALOG_FLAGS.TDF_USE_COMMAND_LINKS;
|
||||||
}
|
}
|
||||||
@@ -387,10 +398,17 @@ public class TaskDialog<T> : TaskDialogNative, IDisposable
|
|||||||
{
|
{
|
||||||
MarshalDialogControlStructs();
|
MarshalDialogControlStructs();
|
||||||
TaskDialogNative.TASKDIALOGCONFIG config = Config;
|
TaskDialogNative.TASKDIALOGCONFIG config = Config;
|
||||||
int errorCode = TaskDialogNative.TaskDialogIndirect(config, out int dummy1, out int dummy2, out bool isChecked);
|
int hr = TaskDialogNative.TaskDialogIndirect(
|
||||||
if (errorCode < 0) Marshal.ThrowExceptionForHR(errorCode);
|
config, out int dummy1, out int dummy2, out bool isChecked);
|
||||||
|
|
||||||
|
if (hr < 0)
|
||||||
|
Marshal.ThrowExceptionForHR(hr);
|
||||||
|
|
||||||
CheckBoxChecked = isChecked;
|
CheckBoxChecked = isChecked;
|
||||||
if (SelectedValue is MsgResult) SelectedValue = (T)(object)SelectedID;
|
|
||||||
|
if (SelectedValue is MsgResult)
|
||||||
|
SelectedValue = (T)(object)SelectedID;
|
||||||
|
|
||||||
return SelectedValue;
|
return SelectedValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -411,8 +429,10 @@ public class TaskDialog<T> : TaskDialogNative, IDisposable
|
|||||||
break;
|
break;
|
||||||
case 3: //TDN_HYPERLINK_CLICKED
|
case 3: //TDN_HYPERLINK_CLICKED
|
||||||
string stringUni = Marshal.PtrToStringUni(lParam);
|
string stringUni = Marshal.PtrToStringUni(lParam);
|
||||||
|
|
||||||
if (stringUni.StartsWith("mailto") || stringUni.StartsWith("http"))
|
if (stringUni.StartsWith("mailto") || stringUni.StartsWith("http"))
|
||||||
Process.Start(stringUni);
|
Process.Start(stringUni);
|
||||||
|
|
||||||
if (stringUni == "copymsg")
|
if (stringUni == "copymsg")
|
||||||
{
|
{
|
||||||
Thread thread = new Thread((ThreadStart)(() => {
|
Thread thread = new Thread((ThreadStart)(() => {
|
||||||
@@ -474,8 +494,10 @@ public class TaskDialog<T> : TaskDialogNative, IDisposable
|
|||||||
|
|
||||||
protected void Dispose(bool disposing)
|
protected void Dispose(bool disposing)
|
||||||
{
|
{
|
||||||
if (disposed) return;
|
if (Disposed)
|
||||||
disposed = true;
|
return;
|
||||||
|
|
||||||
|
Disposed = true;
|
||||||
|
|
||||||
if (ButtonArray != IntPtr.Zero)
|
if (ButtonArray != IntPtr.Zero)
|
||||||
{
|
{
|
||||||
@@ -492,36 +514,27 @@ public class TaskDialog<T> : TaskDialogNative, IDisposable
|
|||||||
}
|
}
|
||||||
|
|
||||||
public delegate int PFTASKDIALOGCALLBACK(
|
public delegate int PFTASKDIALOGCALLBACK(
|
||||||
IntPtr hwnd,
|
IntPtr hwnd, uint msg, IntPtr wParam, IntPtr lParam, IntPtr lpRefData);
|
||||||
uint msg,
|
|
||||||
IntPtr wParam,
|
|
||||||
IntPtr lParam,
|
|
||||||
IntPtr lpRefData);
|
|
||||||
|
|
||||||
public class TaskDialogNative
|
public class TaskDialogNative
|
||||||
{
|
{
|
||||||
[DllImport("comctl32", CharSet = CharSet.Unicode, SetLastError = true)]
|
[DllImport("comctl32", CharSet = CharSet.Unicode, SetLastError = true)]
|
||||||
public static extern int TaskDialogIndirect(
|
public static extern int TaskDialogIndirect(
|
||||||
[In] TaskDialogNative.TASKDIALOGCONFIG pTaskConfig,
|
TaskDialogNative.TASKDIALOGCONFIG pTaskConfig,
|
||||||
out int pnButton,
|
out int pnButton,
|
||||||
out int pnRadioButton,
|
out int pnRadioButton,
|
||||||
[MarshalAs(UnmanagedType.Bool)] out bool pVerificationFlagChecked);
|
out bool pVerificationFlagChecked);
|
||||||
|
|
||||||
[DllImport("user32.dll")]
|
[DllImport("user32.dll")]
|
||||||
public static extern IntPtr GetForegroundWindow();
|
public static extern IntPtr GetForegroundWindow();
|
||||||
|
|
||||||
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
|
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
|
||||||
public static extern uint GetWindowModuleFileName(
|
public static extern uint GetWindowModuleFileName(
|
||||||
IntPtr hwnd,
|
IntPtr hwnd, StringBuilder lpszFileName, uint cchFileNameMax);
|
||||||
StringBuilder lpszFileName,
|
|
||||||
uint cchFileNameMax);
|
|
||||||
|
|
||||||
[DllImport("user32.dll")]
|
[DllImport("user32.dll")]
|
||||||
public static extern IntPtr SendMessage(
|
public static extern IntPtr SendMessage(
|
||||||
IntPtr handle,
|
IntPtr handle, int message, IntPtr wParam, IntPtr lParam);
|
||||||
int message,
|
|
||||||
IntPtr wParam,
|
|
||||||
IntPtr lParam);
|
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential, Pack = 4, CharSet = CharSet.Unicode)]
|
[StructLayout(LayoutKind.Sequential, Pack = 4, CharSet = CharSet.Unicode)]
|
||||||
public class TASKDIALOGCONFIG
|
public class TASKDIALOGCONFIG
|
||||||
@@ -531,12 +544,9 @@ public class TaskDialogNative
|
|||||||
public IntPtr hInstance;
|
public IntPtr hInstance;
|
||||||
public TaskDialogNative.TASKDIALOG_FLAGS dwFlags;
|
public TaskDialogNative.TASKDIALOG_FLAGS dwFlags;
|
||||||
public MsgButtons dwCommonButtons;
|
public MsgButtons dwCommonButtons;
|
||||||
[MarshalAs(UnmanagedType.LPWStr)]
|
|
||||||
public string pszWindowTitle;
|
public string pszWindowTitle;
|
||||||
public TaskDialogNative.TASKDIALOGCONFIG_ICON_UNION MainIcon;
|
public TaskDialogNative.TASKDIALOGCONFIG_ICON_UNION MainIcon;
|
||||||
[MarshalAs(UnmanagedType.LPWStr)]
|
|
||||||
public string pszMainInstruction;
|
public string pszMainInstruction;
|
||||||
[MarshalAs(UnmanagedType.LPWStr)]
|
|
||||||
public string pszContent;
|
public string pszContent;
|
||||||
public uint cButtons;
|
public uint cButtons;
|
||||||
public IntPtr pButtons;
|
public IntPtr pButtons;
|
||||||
@@ -544,16 +554,11 @@ public class TaskDialogNative
|
|||||||
public uint cRadioButtons;
|
public uint cRadioButtons;
|
||||||
public IntPtr pRadioButtons;
|
public IntPtr pRadioButtons;
|
||||||
public int nDefaultRadioButton;
|
public int nDefaultRadioButton;
|
||||||
[MarshalAs(UnmanagedType.LPWStr)]
|
|
||||||
public string pszVerificationText;
|
public string pszVerificationText;
|
||||||
[MarshalAs(UnmanagedType.LPWStr)]
|
|
||||||
public string pszExpandedInformation;
|
public string pszExpandedInformation;
|
||||||
[MarshalAs(UnmanagedType.LPWStr)]
|
|
||||||
public string pszExpandedControlText;
|
public string pszExpandedControlText;
|
||||||
[MarshalAs(UnmanagedType.LPWStr)]
|
|
||||||
public string pszCollapsedControlText;
|
public string pszCollapsedControlText;
|
||||||
public TaskDialogNative.TASKDIALOGCONFIG_ICON_UNION FooterIcon;
|
public TaskDialogNative.TASKDIALOGCONFIG_ICON_UNION FooterIcon;
|
||||||
[MarshalAs(UnmanagedType.LPWStr)]
|
|
||||||
public string pszFooter;
|
public string pszFooter;
|
||||||
public PFTASKDIALOGCALLBACK pfCallback;
|
public PFTASKDIALOGCALLBACK pfCallback;
|
||||||
public IntPtr lpCallbackData;
|
public IntPtr lpCallbackData;
|
||||||
|
|||||||
@@ -1,18 +1,18 @@
|
|||||||
using System;
|
|
||||||
|
using System;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
public class Taskbar
|
public class Taskbar
|
||||||
{
|
{
|
||||||
private ITaskbarList3 Instance = (ITaskbarList3)new TaskBarCommunication();
|
|
||||||
|
|
||||||
public IntPtr Handle { get; set; }
|
public IntPtr Handle { get; set; }
|
||||||
|
|
||||||
public Taskbar(IntPtr handle) => Handle = handle;
|
public Taskbar(IntPtr handle) => Handle = handle;
|
||||||
|
|
||||||
[ComImportAttribute]
|
ITaskbarList3 Instance = (ITaskbarList3)new TaskBarCommunication();
|
||||||
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
|
|
||||||
[GuidAttribute("ea1afb91-9e28-4b86-90e9-9e9f8a5eefaf")]
|
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
||||||
private interface ITaskbarList3
|
[Guid("EA1AFB91-9E28-4B86-90E9-9E9F8A5EEFAF")]
|
||||||
|
interface ITaskbarList3
|
||||||
{
|
{
|
||||||
// ITaskbarList
|
// ITaskbarList
|
||||||
[PreserveSig] void HrInit();
|
[PreserveSig] void HrInit();
|
||||||
@@ -27,10 +27,12 @@ public class Taskbar
|
|||||||
[PreserveSig] void SetProgressState(IntPtr hwnd, TaskbarStates state);
|
[PreserveSig] void SetProgressState(IntPtr hwnd, TaskbarStates state);
|
||||||
}
|
}
|
||||||
|
|
||||||
[ComImportAttribute]
|
[ComImport]
|
||||||
[ClassInterfaceAttribute(ClassInterfaceType.None)]
|
[ClassInterface(ClassInterfaceType.None)]
|
||||||
[GuidAttribute("56FDF344-FD6D-11d0-958A-006097C9A090")]
|
[Guid("56FDF344-FD6D-11d0-958A-006097C9A090")]
|
||||||
private class TaskBarCommunication { }
|
class TaskBarCommunication
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
public void SetState(TaskbarStates taskbarState)
|
public void SetState(TaskbarStates taskbarState)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -6,11 +6,11 @@ using System.Runtime.InteropServices;
|
|||||||
// set of attributes. Change these attribute values to modify the information
|
// set of attributes. Change these attribute values to modify the information
|
||||||
// associated with an assembly.
|
// associated with an assembly.
|
||||||
[assembly: AssemblyTitle("mpv.net")]
|
[assembly: AssemblyTitle("mpv.net")]
|
||||||
[assembly: AssemblyDescription("media player")]
|
[assembly: AssemblyDescription("mpv based media player")]
|
||||||
[assembly: AssemblyConfiguration("")]
|
[assembly: AssemblyConfiguration("")]
|
||||||
[assembly: AssemblyCompany("Frank Skare (stax76)")]
|
[assembly: AssemblyCompany("Frank Skare (stax76)")]
|
||||||
[assembly: AssemblyProduct("mpv.net")]
|
[assembly: AssemblyProduct("mpv.net")]
|
||||||
[assembly: AssemblyCopyright("Copyright 2017-2019 Frank Skare (stax76)")]
|
[assembly: AssemblyCopyright("Copyright (C) 2017-2020 Frank Skare (stax76)")]
|
||||||
[assembly: AssemblyTrademark("")]
|
[assembly: AssemblyTrademark("")]
|
||||||
[assembly: AssemblyCulture("")]
|
[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
|
// You can specify all the values or you can default the Build and Revision Numbers
|
||||||
// by using the '*' as shown below:
|
// by using the '*' as shown below:
|
||||||
// [assembly: AssemblyVersion("1.0.*")]
|
// [assembly: AssemblyVersion("1.0.*")]
|
||||||
[assembly: AssemblyVersion("5.4.3.0")]
|
[assembly: AssemblyVersion("5.4.5.0")]
|
||||||
[assembly: AssemblyFileVersion("5.4.3.0")]
|
[assembly: AssemblyFileVersion("5.4.5.0")]
|
||||||
|
|||||||
50
mpv.net/Properties/Resources.Designer.cs
generated
50
mpv.net/Properties/Resources.Designer.cs
generated
@@ -61,7 +61,8 @@ namespace mpvnet.Properties {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Looks up a localized string similar to [[settings]]
|
/// Looks up a localized string similar to
|
||||||
|
///[[settings]]
|
||||||
///name = "hwdec"
|
///name = "hwdec"
|
||||||
///file = "mpv"
|
///file = "mpv"
|
||||||
///default = "no"
|
///default = "no"
|
||||||
@@ -69,18 +70,18 @@ namespace mpvnet.Properties {
|
|||||||
///url = "https://mpv.io/manual/master/#options-hwdec"
|
///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:"
|
///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" },
|
///options = [{ name = "no", help = "always use software decoding" },
|
||||||
/// { name = "auto", hel [rest of string was truncated]";.
|
/// { name = "auto", h [rest of string was truncated]";.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal static string confToml {
|
internal static string editor_toml {
|
||||||
get {
|
get {
|
||||||
return ResourceManager.GetString("confToml", resourceCulture);
|
return ResourceManager.GetString("editor_toml", resourceCulture);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Looks up a localized string similar to
|
/// Looks up a localized string similar to
|
||||||
/// # This file defines the key and mouse bindings and the context menu
|
/// # 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
|
/// # of mpv.net. A input and config editor can be found in mpv.nets
|
||||||
/// # context menu under 'Settings'. The defaults of this file can be found at:
|
/// # 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
|
/// # https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/inputConf.txt
|
||||||
@@ -90,34 +91,34 @@ namespace mpvnet.Properties {
|
|||||||
/// # https://github.com/mpv-player/mpv/blob/master/etc/input.conf
|
/// # https://github.com/mpv-player/mpv/blob/master/etc/input.conf
|
||||||
///
|
///
|
||||||
/// # mpv.net's defaults of mpv.conf contain: 'input-default-bindings = no'
|
/// # mpv.net's defaults of mpv.conf contain: 'input-default-bindings = no'
|
||||||
/// # which disables mpv's [rest of string was truncated]";.
|
/// # which disables mpv's i [rest of string was truncated]";.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal static string inputConf {
|
internal static string input_conf {
|
||||||
get {
|
get {
|
||||||
return ResourceManager.GetString("inputConf", resourceCulture);
|
return ResourceManager.GetString("input_conf", resourceCulture);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Looks up a localized string similar to input-default-bindings = no
|
/// Looks up a localized string similar to
|
||||||
|
///input-default-bindings = no
|
||||||
///input-ar-delay = 500
|
///input-ar-delay = 500
|
||||||
///input-ar-rate = 20
|
///input-ar-rate = 20
|
||||||
///keep-open = yes
|
///keep-open = yes
|
||||||
///keep-open-pause = no
|
///keep-open-pause = no
|
||||||
|
///osd-duration = 2000
|
||||||
///osd-playing-msg = '${filename}'
|
///osd-playing-msg = '${filename}'
|
||||||
///script-opts = osc-scalewindowed=1.5
|
///script-opts = osc-scalewindowed=1.5,osc-hidetimeout=2000,console-scale=1
|
||||||
///screenshot-directory = '~~desktop/'
|
///screenshot-directory = '~~desktop/'
|
||||||
///cscale = spline36
|
|
||||||
///dscale = spline36
|
|
||||||
///scale = spline36
|
|
||||||
///hwdec = yes
|
///hwdec = yes
|
||||||
///
|
///
|
||||||
///[protocol.https]
|
///[protocol.https]
|
||||||
///osd-playing-msg = '${media-title}'.
|
///osd-playing-msg = '${media-title}'
|
||||||
|
///.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal static string mpvConf {
|
internal static string mpv_conf {
|
||||||
get {
|
get {
|
||||||
return ResourceManager.GetString("mpvConf", resourceCulture);
|
return ResourceManager.GetString("mpv_conf", resourceCulture);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -135,23 +136,24 @@ namespace mpvnet.Properties {
|
|||||||
/// Looks up a localized string similar to
|
/// Looks up a localized string similar to
|
||||||
///[dark]
|
///[dark]
|
||||||
///
|
///
|
||||||
///heading = #1E90FF
|
///heading = #3C8CC8
|
||||||
///foreground = #FFFFFF
|
///foreground = #DDDDDD
|
||||||
///foreground2 = #C0C0C0
|
///foreground2 = #AAAAAA
|
||||||
///background = #323232
|
///background = #323232
|
||||||
///
|
///
|
||||||
///menu-foreground = #FFFFFF
|
///menu-foreground = #DDDDDD
|
||||||
///menu-background = #323232
|
///menu-background = #323232
|
||||||
///menu-highlight = #505050
|
///menu-highlight = #505050
|
||||||
///menu-border = #FFFFFF
|
///menu-border = #FFFFFF
|
||||||
///menu-checked = #5A5A5A
|
///menu-checked = #5A5A5A
|
||||||
///
|
///
|
||||||
|
///
|
||||||
///[light]
|
///[light]
|
||||||
///
|
///
|
||||||
///heading = #0068B2
|
///heading = #0068B2
|
||||||
///foreground = #000000
|
///foreground = #000000
|
||||||
///foreground2 = #4C4C4C
|
///foreground2 = #4C4C4C
|
||||||
///background = #F7F7F7
|
///background = #F7F7F7
|
||||||
///
|
///
|
||||||
///menu-foreground = #000000
|
///menu-foreground = #000000
|
||||||
///menu-background = #DFDFDF
|
///menu-background = #DFDFDF
|
||||||
|
|||||||
@@ -118,18 +118,18 @@
|
|||||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
</resheader>
|
</resheader>
|
||||||
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
<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">
|
<data name="editor_toml" 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>
|
<value>..\Resources\editor.toml.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="inputConf" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
<data name="input_conf" 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>
|
<value>..\Resources\input.conf.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252</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>
|
||||||
<data name="mpvnet" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
<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>
|
<value>..\Resources\mpvnet.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="mpv_conf" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||||
|
<value>..\Resources\mpv.conf.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
|
||||||
|
</data>
|
||||||
<data name="theme" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
<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>
|
<value>..\Resources\theme.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
|
||||||
</data>
|
</data>
|
||||||
|
|||||||
@@ -152,6 +152,25 @@ help = "Enable the debanding algorithm. This greatly reduces the amount of visib
|
|||||||
options = [{ name = "yes" },
|
options = [{ name = "yes" },
|
||||||
{ name = "no" }]
|
{ name = "no" }]
|
||||||
|
|
||||||
|
[[settings]]
|
||||||
|
name = "d3d11va-zero-copy"
|
||||||
|
file = "mpv"
|
||||||
|
default = "no"
|
||||||
|
filter = "Video"
|
||||||
|
help = "By default, when using hardware decoding with --gpu-api=d3d11, the video image will be copied (GPU-to-GPU) from the decoder surface to a shader resource. Set this option to avoid that copy by sampling directly from the decoder image. This may increase performance and reduce power usage, but can cause the image to be sampled incorrectly on the bottom and right edges due to padding, and may invoke driver bugs, since Direct3D 11 technically does not allow sampling from a decoder surface (though most drivers support it.)"
|
||||||
|
options = [{ name = "yes" },
|
||||||
|
{ name = "no" }]
|
||||||
|
|
||||||
|
[[settings]]
|
||||||
|
name = "hdr-compute-peak"
|
||||||
|
file = "mpv"
|
||||||
|
default = "auto"
|
||||||
|
filter = "Video"
|
||||||
|
help = "Compute the HDR peak and frame average brightness per-frame instead of relying on tagged metadata. These values are averaged over local regions as well as over several frames to prevent the value from jittering around too much. This option basically gives you dynamic, per-scene tone mapping. Requires compute shaders, which is a fairly recent OpenGL feature, and will probably also perform horribly on some drivers, so enable at your own risk. The special value auto (default) will enable HDR peak computation automatically if compute shaders and SSBOs are supported."
|
||||||
|
options = [{ name = "auto" },
|
||||||
|
{ name = "yes" },
|
||||||
|
{ name = "no" }]
|
||||||
|
|
||||||
[[settings]]
|
[[settings]]
|
||||||
name = "volume"
|
name = "volume"
|
||||||
file = "mpv"
|
file = "mpv"
|
||||||
@@ -276,6 +295,12 @@ file = "mpv"
|
|||||||
filter = "Screen"
|
filter = "Screen"
|
||||||
help = "Specify the OSD font size. See sub-font-size for details. Default: 55"
|
help = "Specify the OSD font size. See sub-font-size for details. Default: 55"
|
||||||
|
|
||||||
|
[[settings]]
|
||||||
|
name = "osd-duration"
|
||||||
|
file = "mpv"
|
||||||
|
filter = "Screen"
|
||||||
|
help = "Set the duration of the OSD messages in ms. Default: 1000"
|
||||||
|
|
||||||
[[settings]]
|
[[settings]]
|
||||||
name = "osd-scale-by-window"
|
name = "osd-scale-by-window"
|
||||||
file = "mpv"
|
file = "mpv"
|
||||||
@@ -295,22 +320,23 @@ help = "<int> Initial window height in percent. Default: 50"
|
|||||||
name = "autofit-smaller"
|
name = "autofit-smaller"
|
||||||
file = "mpv"
|
file = "mpv"
|
||||||
filter = "Screen"
|
filter = "Screen"
|
||||||
help = "<int> Minimum window height in percent. Default: 40"
|
help = "<int> Minimum window height in percent. Default: 30"
|
||||||
|
|
||||||
[[settings]]
|
[[settings]]
|
||||||
name = "autofit-larger"
|
name = "autofit-larger"
|
||||||
file = "mpv"
|
file = "mpv"
|
||||||
filter = "Screen"
|
filter = "Screen"
|
||||||
help = "<int> Maximum window height in percent. Default: 75"
|
help = "<int> Maximum window height in percent. Default: 80"
|
||||||
|
|
||||||
[[settings]]
|
[[settings]]
|
||||||
name = "start-size"
|
name = "start-size"
|
||||||
file = "mpvnet"
|
file = "mpvnet"
|
||||||
default = "previous"
|
default = "previous"
|
||||||
filter = "Screen"
|
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)"
|
help = "Setting to remember the window height. (mpv.net specific setting)"
|
||||||
options = [{ name = "video", help = "Window size is set to native video resolution" },
|
options = [{ name = "video", help = "Window size is set to video resolution" },
|
||||||
{ name = "previous", help = "Window size is remembered but only from the current session" }]
|
{ name = "previous", help = "Window size is remembered but only in the current session" },
|
||||||
|
{ name = "always", help = "Window size is always remembered"}]
|
||||||
|
|
||||||
[[settings]]
|
[[settings]]
|
||||||
name = "start-threshold"
|
name = "start-threshold"
|
||||||
@@ -322,7 +348,7 @@ help = "Threshold in milliseconds to wait for libmpv returning the video resolut
|
|||||||
name = "minimum-aspect-ratio"
|
name = "minimum-aspect-ratio"
|
||||||
file = "mpvnet"
|
file = "mpvnet"
|
||||||
filter = "Screen"
|
filter = "Screen"
|
||||||
help = "<float> Minimum aspect ratio for the window. Default: 1.3 (mpv.net specific setting)"
|
help = "<float> Minimum aspect ratio for the window. Default: 1.2 (mpv.net specific setting)"
|
||||||
|
|
||||||
[[settings]]
|
[[settings]]
|
||||||
name = "remember-position"
|
name = "remember-position"
|
||||||
@@ -334,11 +360,11 @@ options = [{ name = "yes" },
|
|||||||
{ name = "no" }]
|
{ name = "no" }]
|
||||||
|
|
||||||
[[settings]]
|
[[settings]]
|
||||||
name = "maximized"
|
name = "window-maximized"
|
||||||
file = "mpvnet"
|
file = "mpv"
|
||||||
default = "no"
|
default = "no"
|
||||||
filter = "Screen"
|
filter = "Screen"
|
||||||
help = "Start with a maximized window. (mpv.net specific setting)"
|
help = "Start with a maximized window."
|
||||||
options = [{ name = "yes" },
|
options = [{ name = "yes" },
|
||||||
{ name = "no" }]
|
{ name = "no" }]
|
||||||
|
|
||||||
@@ -502,6 +528,15 @@ file = "mpv"
|
|||||||
filter = "Input"
|
filter = "Input"
|
||||||
help = "Number of key presses to generate per second on autorepeat."
|
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]]
|
[[settings]]
|
||||||
name = "process-instance"
|
name = "process-instance"
|
||||||
file = "mpvnet"
|
file = "mpvnet"
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
|
|
||||||
# This file defines the key and mouse bindings and the context menu
|
# 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
|
# of mpv.net. A input and config editor can be found in mpv.nets
|
||||||
# context menu under 'Settings'. The defaults of this file can be found at:
|
# 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
|
# https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/input.conf.txt
|
||||||
|
|
||||||
# The defaults of mpv can be found at:
|
# The defaults of mpv can be found at:
|
||||||
|
|
||||||
@@ -12,11 +12,9 @@
|
|||||||
# mpv.net's defaults of mpv.conf contain: 'input-default-bindings = no'
|
# 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
|
# 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
|
# 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 '.
|
# if 'o' has already a binding you can do 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
|
|
||||||
|
|
||||||
# run mpv.net in input test mode with: mpvnet --input-test
|
# run mpv.net in input test mode with: mpvnet --input-test
|
||||||
|
|
||||||
@@ -41,8 +39,8 @@
|
|||||||
F11 playlist-prev #menu: Navigate > Previous File
|
F11 playlist-prev #menu: Navigate > Previous File
|
||||||
F12 playlist-next #menu: Navigate > Next File
|
F12 playlist-next #menu: Navigate > Next File
|
||||||
_ ignore #menu: Navigate > -
|
_ ignore #menu: Navigate > -
|
||||||
Home set playlist-pos 0 #menu: Navigate > First File
|
Home script-message mpv.net playlist-first #menu: Navigate > First File
|
||||||
End script-message mpv.net playlist-last #menu: Navigate > Last File
|
End script-message mpv.net playlist-last #menu: Navigate > Last File
|
||||||
_ ignore #menu: Navigate > -
|
_ ignore #menu: Navigate > -
|
||||||
PGUP add chapter 1 #menu: Navigate > Next Chapter
|
PGUP add chapter 1 #menu: Navigate > Next Chapter
|
||||||
PGDWN add chapter -1 #menu: Navigate > Previous Chapter
|
PGDWN add chapter -1 #menu: Navigate > Previous Chapter
|
||||||
@@ -50,14 +48,14 @@
|
|||||||
. frame-step #menu: Navigate > Jump Next Frame
|
. frame-step #menu: Navigate > Jump Next Frame
|
||||||
, frame-back-step #menu: Navigate > Jump Previous Frame
|
, frame-back-step #menu: Navigate > Jump Previous Frame
|
||||||
_ ignore #menu: Navigate > -
|
_ ignore #menu: Navigate > -
|
||||||
Right no-osd seek 7 #menu: Navigate > Jump 7 sec forward
|
Right seek 7 #menu: Navigate > Jump 7 sec forward
|
||||||
Left no-osd seek -7 #menu: Navigate > Jump 7 sec backward
|
Left seek -7 #menu: Navigate > Jump 7 sec backward
|
||||||
_ ignore #menu: Navigate > -
|
_ ignore #menu: Navigate > -
|
||||||
Up no-osd seek 40 #menu: Navigate > Jump 40 sec forward
|
Up seek 40 #menu: Navigate > Jump 40 sec forward
|
||||||
Down no-osd seek -40 #menu: Navigate > Jump 40 sec backward
|
Down seek -40 #menu: Navigate > Jump 40 sec backward
|
||||||
_ ignore #menu: Navigate > -
|
_ ignore #menu: Navigate > -
|
||||||
Ctrl+Right no-osd seek 300 #menu: Navigate > Jump 5 min forward
|
Ctrl+Right seek 300 #menu: Navigate > Jump 5 min forward
|
||||||
Ctrl+Left no-osd seek -300 #menu: Navigate > Jump 5 min backward
|
Ctrl+Left seek -300 #menu: Navigate > Jump 5 min backward
|
||||||
_ ignore #menu: Navigate > -
|
_ ignore #menu: Navigate > -
|
||||||
_ ignore #menu: Navigate > Chapters
|
_ ignore #menu: Navigate > Chapters
|
||||||
|
|
||||||
@@ -132,46 +130,43 @@
|
|||||||
_ ignore #menu: Extensions > Rating > -
|
_ ignore #menu: Extensions > Rating > -
|
||||||
_ script-message rate-file about #menu: Extensions > Rating > About
|
_ script-message rate-file about #menu: Extensions > Rating > About
|
||||||
|
|
||||||
Ctrl+t set ontop yes #menu: View > On Top > Enable
|
Ctrl+t set ontop yes #menu: View > On Top > Enable
|
||||||
Ctrl+T set ontop no #menu: View > On Top > Disable
|
Ctrl+T set ontop no #menu: View > On Top > Disable
|
||||||
Alt++ no-osd set window-scale 1.2 #menu: View > Window Size > Enlarge
|
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
|
Alt+- no-osd set window-scale 0.8 #menu: View > Window Size > Shrink
|
||||||
b cycle border #menu: View > Toggle Border
|
b cycle border #menu: View > Toggle Border
|
||||||
i script-message mpv.net show-info #menu: View > File/Stream Info
|
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 #menu: View > Show Statistics
|
||||||
T script-binding stats/display-stats-toggle #menu: View > Toggle Statistics
|
T script-binding stats/display-stats-toggle #menu: View > Toggle Statistics
|
||||||
Del script-binding osc/visibility #menu: View > Toggle OSC Visibility
|
Del script-binding osc/visibility #menu: View > Toggle OSC Visibility
|
||||||
F8 script-binding show-playlist #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
|
F9 show-text ${track-list} 5000 #menu: View > Show Audio/Video/Subtitle List
|
||||||
|
p show-progress #menu: View > Show Progress
|
||||||
|
Ctrl+p script-message mpv.net show-profiles #menu: View > Show Profiles
|
||||||
|
Shift+p script-message mpv.net show-properties #menu: View > Show Properties
|
||||||
|
Shift+c script-message mpv.net show-commands #menu: View > Show Commands
|
||||||
|
` script-binding console/enable #menu: View > Show Console
|
||||||
|
|
||||||
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+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+f script-message mpv.net open-conf-folder #menu: Settings > Open Config Folder
|
||||||
|
|
||||||
F1 script-message mpv.net show-command-palette #menu: Tools > Show All Commands
|
F1 script-message mpv.net show-command-palette #menu: Tools > Show All Commands
|
||||||
h script-message mpv.net show-history #menu: Tools > Show History
|
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 ab-loop #menu: Tools > Set/clear A-B loop points
|
L cycle-values loop-file "inf" "no" #menu: Tools > Toggle infinite file looping
|
||||||
L cycle-values loop-file "inf" "no" #menu: Tools > Toggle infinite file looping
|
_ cycle shuffle #menu: Tools > Toggle Shuffle
|
||||||
_ cycle shuffle #menu: Tools > Toggle Shuffle
|
Ctrl+h cycle-values hwdec "auto" "no" #menu: Tools > Toggle Hardware Decoding
|
||||||
Ctrl+h cycle-values hwdec "auto" "no" #menu: Tools > Toggle Hardware Decoding
|
_ script-message mpv.net show-setup-dialog #menu: Tools > Setup...
|
||||||
_ script-message mpv.net show-setup-dialog #menu: Tools > OS Setup...
|
|
||||||
|
|
||||||
_ script-message mpv.net shell-execute https://github.com/stax76/mpv.net/blob/master/Manual.md #menu: Help > mpv.net Manual
|
_ 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 > mpv.net GitHub
|
_ script-message mpv.net shell-execute https://github.com/stax76/mpv.net #menu: Help > Website mpv.net
|
||||||
_ script-message mpv.net shell-execute https://github.com/stax76/mpv.net/wiki #menu: Help > mpv.net Wiki
|
_ ignore #menu: Help > -
|
||||||
_ script-message mpv.net shell-execute https://github.com/stax76/mpv.net#support #menu: Help > mpv.net Support
|
_ 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/releases #menu: Help > mpv.net Download
|
_ script-message mpv.net shell-execute https://github.com/stax76/mpv.net/blob/master/Manual.md #menu: Help > Manual mpv.net
|
||||||
_ script-message mpv.net shell-execute https://github.com/stax76/mpv.net/blob/master/mpv.net/Resources/inputConf.txt #menu: Help > mpv.net Default Key Bindings
|
_ ignore #menu: Help > -
|
||||||
_ ignore #menu: Help > -
|
_ script-message mpv.net update-check #menu: Help > Check for Updates
|
||||||
_ script-message mpv.net shell-execute https://mpv.io/manual/stable/ #menu: Help > mpv Manual
|
_ script-message mpv.net show-about #menu: Help > About mpv.net
|
||||||
_ script-message mpv.net shell-execute https://github.com/mpv-player/mpv/wiki #menu: Help > mpv Wiki
|
|
||||||
_ script-message mpv.net shell-execute https://github.com/mpv-player/mpv/wiki/User-Scripts #menu: Help > mpv User Scripts
|
|
||||||
_ script-message mpv.net shell-execute https://mpv.io/bug-reports/ #menu: Help > mpv Bugs and Requests
|
|
||||||
_ script-message mpv.net shell-execute https://mpv.io/installation/ #menu: Help > mpv Download
|
|
||||||
_ script-message mpv.net shell-execute https://github.com/mpv-player/mpv/blob/master/etc/input.conf #menu: Help > mpv Default Key Bindings
|
|
||||||
_ ignore #menu: Help > -
|
|
||||||
_ script-message mpv.net show-about #menu: Help > About mpv.net
|
|
||||||
|
|
||||||
_ ignore #menu: -
|
_ ignore #menu: -
|
||||||
Esc quit #menu: Exit
|
Esc quit #menu: Exit
|
||||||
@@ -190,6 +185,8 @@
|
|||||||
Volume_Down add volume -10
|
Volume_Down add volume -10
|
||||||
Wheel_Up add volume 10
|
Wheel_Up add volume 10
|
||||||
Wheel_Down add volume -10
|
Wheel_Down add volume -10
|
||||||
|
Wheel_Left add volume -10
|
||||||
|
Wheel_Right add volume 10
|
||||||
Prev playlist-prev
|
Prev playlist-prev
|
||||||
Next playlist-next
|
Next playlist-next
|
||||||
MBTN_Forward playlist-next
|
MBTN_Forward playlist-next
|
||||||
@@ -200,3 +197,4 @@
|
|||||||
Ctrl+Wheel_Down no-osd seek -7
|
Ctrl+Wheel_Down no-osd seek -7
|
||||||
MBTN_Left_DBL cycle fullscreen
|
MBTN_Left_DBL cycle fullscreen
|
||||||
KP_Enter cycle fullscreen
|
KP_Enter cycle fullscreen
|
||||||
|
|
||||||
@@ -1,14 +1,13 @@
|
|||||||
input-default-bindings = no
|
|
||||||
|
input-default-bindings = no
|
||||||
input-ar-delay = 500
|
input-ar-delay = 500
|
||||||
input-ar-rate = 20
|
input-ar-rate = 20
|
||||||
keep-open = yes
|
keep-open = yes
|
||||||
keep-open-pause = no
|
keep-open-pause = no
|
||||||
|
osd-duration = 2000
|
||||||
osd-playing-msg = '${filename}'
|
osd-playing-msg = '${filename}'
|
||||||
script-opts = osc-scalewindowed=1.5
|
script-opts = osc-scalewindowed=1.5,osc-hidetimeout=2000,console-scale=1
|
||||||
screenshot-directory = '~~desktop/'
|
screenshot-directory = '~~desktop/'
|
||||||
cscale = spline36
|
|
||||||
dscale = spline36
|
|
||||||
scale = spline36
|
|
||||||
hwdec = yes
|
hwdec = yes
|
||||||
|
|
||||||
[protocol.https]
|
[protocol.https]
|
||||||
@@ -1,12 +1,12 @@
|
|||||||
|
|
||||||
[dark]
|
[dark]
|
||||||
|
|
||||||
heading = #1E90FF
|
heading = #3C8CC8
|
||||||
foreground = #FFFFFF
|
foreground = #DDDDDD
|
||||||
foreground2 = #C0C0C0
|
foreground2 = #AAAAAA
|
||||||
background = #323232
|
background = #323232
|
||||||
|
|
||||||
menu-foreground = #FFFFFF
|
menu-foreground = #DDDDDD
|
||||||
menu-background = #323232
|
menu-background = #323232
|
||||||
menu-highlight = #505050
|
menu-highlight = #505050
|
||||||
menu-border = #FFFFFF
|
menu-border = #FFFFFF
|
||||||
@@ -15,10 +15,10 @@ menu-checked = #5A5A5A
|
|||||||
|
|
||||||
[light]
|
[light]
|
||||||
|
|
||||||
heading = #0068B2
|
heading = #0068B2
|
||||||
foreground = #000000
|
foreground = #000000
|
||||||
foreground2 = #4C4C4C
|
foreground2 = #4C4C4C
|
||||||
background = #F7F7F7
|
background = #F7F7F7
|
||||||
|
|
||||||
menu-foreground = #000000
|
menu-foreground = #000000
|
||||||
menu-background = #DFDFDF
|
menu-background = #DFDFDF
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
|
||||||
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
|
||||||
123
mpv.net/Scripting/PowerShell.cs
Normal file
123
mpv.net/Scripting/PowerShell.cs
Normal file
@@ -0,0 +1,123 @@
|
|||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Management.Automation;
|
||||||
|
using System.Management.Automation.Runspaces;
|
||||||
|
using System.Threading;
|
||||||
|
|
||||||
|
namespace ScriptHost
|
||||||
|
{
|
||||||
|
public class PowerShell
|
||||||
|
{
|
||||||
|
public Runspace Runspace { get; set; }
|
||||||
|
public Pipeline Pipeline { get; set; }
|
||||||
|
public string Module { get; set; }
|
||||||
|
public bool Print { get; set; }
|
||||||
|
public List<string> Scripts { get; } = new List<string>();
|
||||||
|
public string[] Parameters { get; }
|
||||||
|
|
||||||
|
public static List<PowerShell> Instances { get; } = new List<PowerShell>();
|
||||||
|
|
||||||
|
string NL = Environment.NewLine;
|
||||||
|
|
||||||
|
public object Invoke() => Invoke(null, null);
|
||||||
|
|
||||||
|
public object Invoke(string variable, object obj)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Runspace = RunspaceFactory.CreateRunspace();
|
||||||
|
Runspace.ApartmentState = ApartmentState.STA;
|
||||||
|
Runspace.Open();
|
||||||
|
Pipeline = Runspace.CreatePipeline();
|
||||||
|
|
||||||
|
foreach (string script in Scripts)
|
||||||
|
Pipeline.Commands.AddScript(script);
|
||||||
|
|
||||||
|
if (Parameters != null)
|
||||||
|
foreach (string param in Parameters)
|
||||||
|
foreach (Command command in Pipeline.Commands)
|
||||||
|
command.Parameters.Add(null, param);
|
||||||
|
|
||||||
|
Runspace.SessionStateProxy.SetVariable("ScriptHost", this);
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(variable))
|
||||||
|
Runspace.SessionStateProxy.SetVariable(variable, obj);
|
||||||
|
|
||||||
|
if (Print)
|
||||||
|
{
|
||||||
|
Pipeline.Output.DataReady += Output_DataReady;
|
||||||
|
Pipeline.Error.DataReady += Error_DataReady;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Pipeline.Invoke();
|
||||||
|
}
|
||||||
|
catch (RuntimeException e)
|
||||||
|
{
|
||||||
|
string message = e.Message + NL + NL + e.ErrorRecord.ScriptStackTrace.Replace(
|
||||||
|
" <ScriptBlock>, <No file>", "") + NL + NL + Module + NL;
|
||||||
|
|
||||||
|
throw new PowerShellException(message);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string InvokeAndReturnString(string code, string varName, object varValue)
|
||||||
|
{
|
||||||
|
PowerShell ps = new PowerShell() { Print = false };
|
||||||
|
ps.Scripts.Add(code);
|
||||||
|
string ret = string.Join(Environment.NewLine, (ps.Invoke(varName, varValue)
|
||||||
|
as IEnumerable<object>).Select(item => item.ToString())).ToString();
|
||||||
|
ps.Runspace.Dispose();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Output_DataReady(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
var output = sender as PipelineReader<PSObject>;
|
||||||
|
|
||||||
|
while (output.Count > 0)
|
||||||
|
ConsoleHelp.Write(output.Read(), Module);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Error_DataReady(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
var output = sender as PipelineReader<Object>;
|
||||||
|
|
||||||
|
while (output.Count > 0)
|
||||||
|
ConsoleHelp.WriteError(output.Read(), Module);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RedirectEventJobStreams(PSEventJob job)
|
||||||
|
{
|
||||||
|
if (Print)
|
||||||
|
{
|
||||||
|
job.Output.DataAdded += Output_DataAdded;
|
||||||
|
job.Error.DataAdded += Error_DataAdded;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Output_DataAdded(object sender, DataAddedEventArgs e)
|
||||||
|
{
|
||||||
|
var output = sender as PSDataCollection<PSObject>;
|
||||||
|
ConsoleHelp.Write(output[e.Index], Module);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Error_DataAdded(object sender, DataAddedEventArgs e)
|
||||||
|
{
|
||||||
|
var error = sender as PSDataCollection<ErrorRecord>;
|
||||||
|
ConsoleHelp.WriteError(error[e.Index], Module);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class PowerShellException : Exception
|
||||||
|
{
|
||||||
|
public PowerShellException(string message) : base(message)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,129 +0,0 @@
|
|||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
23
mpv.net/Update.ps1
Normal file
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
|
||||||
@@ -19,7 +19,7 @@
|
|||||||
<Grid>
|
<Grid>
|
||||||
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
|
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
|
||||||
<TextBlock FontSize="48" HorizontalAlignment="Center" Margin="0,0,0,10">mpv.net</TextBlock>
|
<TextBlock FontSize="48" HorizontalAlignment="Center" Margin="0,0,0,10">mpv.net</TextBlock>
|
||||||
<TextBlock HorizontalAlignment="Center">Copyright (c) 2017-2019 Frank Skare (stax76)</TextBlock>
|
<TextBlock HorizontalAlignment="Center">Copyright (C) 2017-2020 Frank Skare (stax76)</TextBlock>
|
||||||
<TextBlock Name="Version" HorizontalAlignment="Center" />
|
<TextBlock Name="Version" HorizontalAlignment="Center" />
|
||||||
<TextBlock Name="mpvVersion" HorizontalAlignment="Center" />
|
<TextBlock Name="mpvVersion" HorizontalAlignment="Center" />
|
||||||
<TextBlock HorizontalAlignment="Center" Margin="0,0,0,20">MIT License</TextBlock>
|
<TextBlock HorizontalAlignment="Center" Margin="0,0,0,20">MIT License</TextBlock>
|
||||||
|
|||||||
@@ -1,13 +1,10 @@
|
|||||||
using Microsoft.Win32;
|
|
||||||
using System;
|
using System;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
using System.Text;
|
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Data;
|
using System.Windows.Data;
|
||||||
using System.Windows.Input;
|
using System.Windows.Input;
|
||||||
using System.Windows.Interop;
|
using System.Windows.Interop;
|
||||||
using System.Windows.Media;
|
|
||||||
|
|
||||||
namespace mpvnet
|
namespace mpvnet
|
||||||
{
|
{
|
||||||
@@ -29,16 +26,22 @@ namespace mpvnet
|
|||||||
{
|
{
|
||||||
if (item.Command == "" || item.Path == "")
|
if (item.Command == "" || item.Path == "")
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
string filter = FilterTextBox.Text.ToLower();
|
string filter = FilterTextBox.Text.ToLower();
|
||||||
if (filter == "") return true;
|
|
||||||
|
if (filter == "")
|
||||||
|
return true;
|
||||||
|
|
||||||
if (item.Command.ToLower().Contains(filter) ||
|
if (item.Command.ToLower().Contains(filter) ||
|
||||||
item.Input.ToLower().Contains(filter) ||
|
item.Input.ToLower().Contains(filter) ||
|
||||||
item.Path.ToLower().Contains(filter))
|
item.Path.ToLower().Contains(filter))
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Window_Loaded(object sender, RoutedEventArgs e)
|
void Window_Loaded(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
HwndSource source = HwndSource.FromHwnd(new WindowInteropHelper(this).Handle);
|
HwndSource source = HwndSource.FromHwnd(new WindowInteropHelper(this).Handle);
|
||||||
source.AddHook(new HwndSourceHook(WndProc));
|
source.AddHook(new HwndSourceHook(WndProc));
|
||||||
@@ -52,14 +55,15 @@ namespace mpvnet
|
|||||||
ListView.SelectedIndex = 0;
|
ListView.SelectedIndex = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
|
IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
|
||||||
{
|
{
|
||||||
if (msg == 0x200 /*WM_MOUSEMOVE*/ && Mouse.LeftButton != MouseButtonState.Pressed)
|
if (msg == 0x200 /*WM_MOUSEMOVE*/ && Mouse.LeftButton != MouseButtonState.Pressed)
|
||||||
handled = true;
|
handled = true;
|
||||||
|
|
||||||
return IntPtr.Zero;
|
return IntPtr.Zero;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void FilterTextBox_PreviewKeyDown(object sender, KeyEventArgs e)
|
void FilterTextBox_PreviewKeyDown(object sender, KeyEventArgs e)
|
||||||
{
|
{
|
||||||
switch (e.Key)
|
switch (e.Key)
|
||||||
{
|
{
|
||||||
@@ -67,7 +71,10 @@ namespace mpvnet
|
|||||||
{
|
{
|
||||||
int index = ListView.SelectedIndex;
|
int index = ListView.SelectedIndex;
|
||||||
index -= 1;
|
index -= 1;
|
||||||
if (index < 0) index = 0;
|
|
||||||
|
if (index < 0)
|
||||||
|
index = 0;
|
||||||
|
|
||||||
ListView.SelectedIndex = index;
|
ListView.SelectedIndex = index;
|
||||||
ListView.ScrollIntoView(ListView.SelectedItem);
|
ListView.ScrollIntoView(ListView.SelectedItem);
|
||||||
}
|
}
|
||||||
@@ -76,7 +83,10 @@ namespace mpvnet
|
|||||||
{
|
{
|
||||||
int index = ListView.SelectedIndex;
|
int index = ListView.SelectedIndex;
|
||||||
index += 1;
|
index += 1;
|
||||||
if (index > ListView.Items.Count - 1) index = ListView.Items.Count - 1;
|
|
||||||
|
if (index > ListView.Items.Count - 1)
|
||||||
|
index = ListView.Items.Count - 1;
|
||||||
|
|
||||||
ListView.SelectedIndex = index;
|
ListView.SelectedIndex = index;
|
||||||
ListView.ScrollIntoView(ListView.SelectedItem);
|
ListView.ScrollIntoView(ListView.SelectedItem);
|
||||||
}
|
}
|
||||||
@@ -100,12 +110,12 @@ namespace mpvnet
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ListView_MouseUp(object sender, MouseButtonEventArgs e)
|
void ListView_MouseUp(object sender, MouseButtonEventArgs e)
|
||||||
{
|
{
|
||||||
Execute();
|
Execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void FilterTextBox_TextChanged(object sender, System.Windows.Controls.TextChangedEventArgs e)
|
void FilterTextBox_TextChanged(object sender, System.Windows.Controls.TextChangedEventArgs e)
|
||||||
{
|
{
|
||||||
CollectionView.Refresh();
|
CollectionView.Refresh();
|
||||||
SelectFirst();
|
SelectFirst();
|
||||||
|
|||||||
@@ -26,13 +26,14 @@
|
|||||||
<ColumnDefinition Width="*" />
|
<ColumnDefinition Width="*" />
|
||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
|
|
||||||
<Controls:SearchTextBoxUserControl HintText="Find a setting"
|
<Controls:SearchTextBoxUserControl
|
||||||
x:Name="SearchControl"
|
x:Name="SearchControl"
|
||||||
Width="250"
|
HintText="Find a setting"
|
||||||
Margin="0,20,0,0"
|
Width="250"
|
||||||
Grid.ColumnSpan="2"/>
|
Margin="0,20,0,0"
|
||||||
|
Grid.ColumnSpan="2"/>
|
||||||
|
|
||||||
<ScrollViewer x:Name="MainScrollViewer"
|
<ScrollViewer Name="MainScrollViewer"
|
||||||
VerticalScrollBarVisibility="Auto"
|
VerticalScrollBarVisibility="Auto"
|
||||||
Grid.Row="1"
|
Grid.Row="1"
|
||||||
Grid.Column="2"
|
Grid.Column="2"
|
||||||
@@ -42,7 +43,7 @@
|
|||||||
</ScrollViewer>
|
</ScrollViewer>
|
||||||
|
|
||||||
<StackPanel Margin="20,0,0,0" Grid.Row="1">
|
<StackPanel Margin="20,0,0,0" Grid.Row="1">
|
||||||
<ListBox x:Name="FilterListBox"
|
<ListBox Name="FilterListBox"
|
||||||
ItemsSource="{Binding FilterStrings}"
|
ItemsSource="{Binding FilterStrings}"
|
||||||
BorderThickness="0"
|
BorderThickness="0"
|
||||||
SelectionChanged="FilterListBox_SelectionChanged"
|
SelectionChanged="FilterListBox_SelectionChanged"
|
||||||
@@ -56,10 +57,10 @@
|
|||||||
</ListBox.ItemTemplate>
|
</ListBox.ItemTemplate>
|
||||||
</ListBox>
|
</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 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 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 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>
|
<TextBlock 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>
|
</StackPanel>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Window>
|
</Window>
|
||||||
@@ -16,7 +16,7 @@ namespace mpvnet
|
|||||||
{
|
{
|
||||||
public partial class ConfWindow : Window
|
public partial class ConfWindow : Window
|
||||||
{
|
{
|
||||||
List<SettingBase> SettingsDefinitions = Settings.LoadSettings(Properties.Resources.confToml);
|
List<SettingBase> SettingsDefinitions = Settings.LoadSettings(Properties.Resources.editor_toml);
|
||||||
List<ConfItem> ConfItems = new List<ConfItem>();
|
List<ConfItem> ConfItems = new List<ConfItem>();
|
||||||
public ObservableCollection<string> FilterStrings { get; } = new ObservableCollection<string>();
|
public ObservableCollection<string> FilterStrings { get; } = new ObservableCollection<string>();
|
||||||
string InitialContent;
|
string InitialContent;
|
||||||
@@ -30,10 +30,11 @@ namespace mpvnet
|
|||||||
LoadConf(App.ConfPath);
|
LoadConf(App.ConfPath);
|
||||||
LoadSettings();
|
LoadSettings();
|
||||||
InitialContent = GetCompareString();
|
InitialContent = GetCompareString();
|
||||||
SearchControl.Text = RegHelp.GetString(App.RegPath, "ConfigEditorSearch");
|
SearchControl.Text = RegistryHelp.GetString(App.RegPath, "ConfigEditorSearch");
|
||||||
|
FilterListBox.SelectedItem = SearchControl.Text.TrimEnd(':');
|
||||||
}
|
}
|
||||||
|
|
||||||
private void LoadSettings()
|
void LoadSettings()
|
||||||
{
|
{
|
||||||
foreach (SettingBase setting in SettingsDefinitions)
|
foreach (SettingBase setting in SettingsDefinitions)
|
||||||
{
|
{
|
||||||
@@ -68,7 +69,7 @@ namespace mpvnet
|
|||||||
protected override void OnClosed(EventArgs e)
|
protected override void OnClosed(EventArgs e)
|
||||||
{
|
{
|
||||||
base.OnClosed(e);
|
base.OnClosed(e);
|
||||||
RegHelp.SetObject(App.RegPath, "ConfigEditorSearch", SearchControl.Text);
|
RegistryHelp.SetValue(App.RegPath, "ConfigEditorSearch", SearchControl.Text);
|
||||||
|
|
||||||
if (InitialContent == GetCompareString())
|
if (InitialContent == GetCompareString())
|
||||||
return;
|
return;
|
||||||
@@ -247,7 +248,7 @@ namespace mpvnet
|
|||||||
return "\r\n" + sb.ToString().Trim() + "\r\n";
|
return "\r\n" + sb.ToString().Trim() + "\r\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SearchTextBox_TextChanged(object sender, TextChangedEventArgs e)
|
void SearchTextBox_TextChanged(object sender, TextChangedEventArgs e)
|
||||||
{
|
{
|
||||||
string activeFilter = "";
|
string activeFilter = "";
|
||||||
|
|
||||||
@@ -275,7 +276,7 @@ namespace mpvnet
|
|||||||
MainScrollViewer.ScrollToTop();
|
MainScrollViewer.ScrollToTop();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ConfWindow1_Loaded(object sender, RoutedEventArgs e)
|
void ConfWindow1_Loaded(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
SearchControl.SearchTextBox.SelectAll();
|
SearchControl.SearchTextBox.SelectAll();
|
||||||
Keyboard.Focus(SearchControl.SearchTextBox);
|
Keyboard.Focus(SearchControl.SearchTextBox);
|
||||||
@@ -284,27 +285,28 @@ namespace mpvnet
|
|||||||
i.Update();
|
i.Update();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void FilterListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
void FilterListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||||
{
|
{
|
||||||
if (e.AddedItems.Count > 0) SearchControl.Text = e.AddedItems[0] + ":";
|
if (e.AddedItems.Count > 0)
|
||||||
|
SearchControl.Text = e.AddedItems[0] + ":";
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OpenSettingsTextBlock_MouseUp(object sender, MouseButtonEventArgs e)
|
void OpenSettingsTextBlock_MouseUp(object sender, MouseButtonEventArgs e)
|
||||||
{
|
{
|
||||||
Process.Start(Path.GetDirectoryName(mp.ConfPath));
|
Process.Start(Path.GetDirectoryName(mp.ConfPath));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void PreviewTextBlock_MouseUp(object sender, MouseButtonEventArgs e)
|
void PreviewTextBlock_MouseUp(object sender, MouseButtonEventArgs e)
|
||||||
{
|
{
|
||||||
Msg.Show("mpv.conf Preview", GetContent("mpv"));
|
Msg.Show("mpv.conf Preview", GetContent("mpv"));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ShowManualTextBlock_MouseUp(object sender, MouseButtonEventArgs e)
|
void ShowManualTextBlock_MouseUp(object sender, MouseButtonEventArgs e)
|
||||||
{
|
{
|
||||||
Process.Start("https://mpv.io/manual/master/");
|
Process.Start("https://mpv.io/manual/master/");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SupportTextBlock_MouseUp(object sender, MouseButtonEventArgs e)
|
void SupportTextBlock_MouseUp(object sender, MouseButtonEventArgs e)
|
||||||
{
|
{
|
||||||
Process.Start("https://github.com/stax76/mpv.net#Support");
|
Process.Start("https://github.com/stax76/mpv.net#Support");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ namespace mpvnet
|
|||||||
[DllImport("Everything.dll")]
|
[DllImport("Everything.dll")]
|
||||||
public static extern UInt32 Everything_GetNumResults();
|
public static extern UInt32 Everything_GetNumResults();
|
||||||
|
|
||||||
private void Window_Loaded(object sender, RoutedEventArgs e)
|
void Window_Loaded(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
HwndSource source = HwndSource.FromHwnd(new WindowInteropHelper(this).Handle);
|
HwndSource source = HwndSource.FromHwnd(new WindowInteropHelper(this).Handle);
|
||||||
source.AddHook(new HwndSourceHook(WndProc));
|
source.AddHook(new HwndSourceHook(WndProc));
|
||||||
@@ -56,7 +56,7 @@ namespace mpvnet
|
|||||||
ListView.SelectedIndex = 0;
|
ListView.SelectedIndex = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
|
IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
|
||||||
{
|
{
|
||||||
if (msg == 0x200 /*WM_MOUSEMOVE*/ && Mouse.LeftButton != MouseButtonState.Pressed)
|
if (msg == 0x200 /*WM_MOUSEMOVE*/ && Mouse.LeftButton != MouseButtonState.Pressed)
|
||||||
handled = true;
|
handled = true;
|
||||||
@@ -64,7 +64,7 @@ namespace mpvnet
|
|||||||
return IntPtr.Zero;
|
return IntPtr.Zero;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void FilterTextBox_PreviewKeyDown(object sender, KeyEventArgs e)
|
void FilterTextBox_PreviewKeyDown(object sender, KeyEventArgs e)
|
||||||
{
|
{
|
||||||
switch (e.Key)
|
switch (e.Key)
|
||||||
{
|
{
|
||||||
@@ -91,7 +91,7 @@ namespace mpvnet
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ListView_PreviewKeyDown(object sender, KeyEventArgs e)
|
void ListView_PreviewKeyDown(object sender, KeyEventArgs e)
|
||||||
{
|
{
|
||||||
if (e.Key == Key.Escape)
|
if (e.Key == Key.Escape)
|
||||||
Close();
|
Close();
|
||||||
@@ -103,14 +103,14 @@ namespace mpvnet
|
|||||||
void Execute()
|
void Execute()
|
||||||
{
|
{
|
||||||
if (ListView.SelectedItem != null)
|
if (ListView.SelectedItem != null)
|
||||||
mp.Load(new[] { ListView.SelectedItem as string }, true, Keyboard.Modifiers == ModifierKeys.Control);
|
mp.LoadFiles(new[] { ListView.SelectedItem as string }, true, Keyboard.Modifiers == ModifierKeys.Control);
|
||||||
|
|
||||||
Keyboard.Focus(FilterTextBox);
|
Keyboard.Focus(FilterTextBox);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ListView_MouseUp(object sender, MouseButtonEventArgs e) => Execute();
|
void ListView_MouseUp(object sender, MouseButtonEventArgs e) => Execute();
|
||||||
|
|
||||||
private void FilterTextBox_TextChanged(object sender, TextChangedEventArgs e)
|
void FilterTextBox_TextChanged(object sender, TextChangedEventArgs e)
|
||||||
{
|
{
|
||||||
string searchtext = FilterTextBox.Text;
|
string searchtext = FilterTextBox.Text;
|
||||||
Task.Run(() => Search(searchtext));
|
Task.Run(() => Search(searchtext));
|
||||||
@@ -137,12 +137,13 @@ namespace mpvnet
|
|||||||
Everything_GetResultFullPathName(i, buf, bufsize);
|
Everything_GetResultFullPathName(i, buf, bufsize);
|
||||||
string ext = buf.ToString().ShortExt();
|
string ext = buf.ToString().ShortExt();
|
||||||
|
|
||||||
if (App.AudioTypes.Contains(ext) || App.VideoTypes.Contains(ext) ||
|
if (App.AudioTypes.Contains(ext) || App.VideoTypes.Contains(ext)
|
||||||
App.ImageTypes.Contains(ext))
|
|| App.ImageTypes.Contains(ext))
|
||||||
|
|
||||||
items.Add(buf.ToString());
|
items.Add(buf.ToString());
|
||||||
|
|
||||||
if (items.Count > 100) break;
|
if (items.Count > 100)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
Application.Current.Dispatcher.Invoke(() => {
|
Application.Current.Dispatcher.Invoke(() => {
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ namespace mpvnet
|
|||||||
DataGrid.ItemsSource = CollectionView;
|
DataGrid.ItemsSource = CollectionView;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SearchTextBox_TextChanged(object sender, TextChangedEventArgs e)
|
void SearchTextBox_TextChanged(object sender, TextChangedEventArgs e)
|
||||||
{
|
{
|
||||||
CollectionView.Refresh();
|
CollectionView.Refresh();
|
||||||
|
|
||||||
@@ -70,7 +70,7 @@ namespace mpvnet
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ButtonClick(object sender, RoutedEventArgs e)
|
void ButtonClick(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
CommandItem item = ((Button)e.Source).DataContext as CommandItem;
|
CommandItem item = ((Button)e.Source).DataContext as CommandItem;
|
||||||
if (item is null) return;
|
if (item is null) return;
|
||||||
@@ -88,13 +88,13 @@ namespace mpvnet
|
|||||||
items[i.Input] = i;
|
items[i.Input] = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Window_Loaded(object sender, RoutedEventArgs e) => Keyboard.Focus(SearchControl.SearchTextBox);
|
void Window_Loaded(object sender, RoutedEventArgs e) => Keyboard.Focus(SearchControl.SearchTextBox);
|
||||||
|
|
||||||
string GetInputConfContent()
|
string GetInputConfContent()
|
||||||
{
|
{
|
||||||
string text = null;
|
string text = null;
|
||||||
|
|
||||||
foreach (string line in Properties.Resources.inputConf.Split(new[] { "\r\n" }, StringSplitOptions.None))
|
foreach (string line in Properties.Resources.input_conf.Split(new[] { "\r\n" }, StringSplitOptions.None))
|
||||||
{
|
{
|
||||||
string test = line.Trim();
|
string test = line.Trim();
|
||||||
if (test == "" || test.StartsWith("#")) text += test + "\r\n";
|
if (test == "" || test.StartsWith("#")) text += test + "\r\n";
|
||||||
@@ -120,14 +120,14 @@ namespace mpvnet
|
|||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Window_Closed(object sender, EventArgs e)
|
void Window_Closed(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
if (InitialInputConfContent == GetInputConfContent()) return;
|
if (InitialInputConfContent == GetInputConfContent()) return;
|
||||||
File.WriteAllText(mp.InputConfPath, GetInputConfContent());
|
File.WriteAllText(mp.InputConfPath, GetInputConfContent());
|
||||||
Msg.Show("Changes will be available on next mpv.net startup.");
|
Msg.Show("Changes will be available on next mpv.net startup.");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DataGrid_PreviewCanExecute(object sender, CanExecuteRoutedEventArgs e)
|
void DataGrid_PreviewCanExecute(object sender, CanExecuteRoutedEventArgs e)
|
||||||
{
|
{
|
||||||
DataGrid grid = (DataGrid)sender;
|
DataGrid grid = (DataGrid)sender;
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ namespace mpvnet
|
|||||||
|
|
||||||
public LearnWindow() => InitializeComponent();
|
public LearnWindow() => InitializeComponent();
|
||||||
|
|
||||||
private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
|
IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
|
||||||
{
|
{
|
||||||
WinForms.Message m = new WinForms.Message();
|
WinForms.Message m = new WinForms.Message();
|
||||||
m.HWnd = hwnd;
|
m.HWnd = hwnd;
|
||||||
@@ -183,6 +183,9 @@ namespace mpvnet
|
|||||||
OnKeyUp(new WinForms.KeyEventArgs((WinForms.Keys)(unchecked((int)(long)m.WParam)) | ModifierKeys));
|
OnKeyUp(new WinForms.KeyEventArgs((WinForms.Keys)(unchecked((int)(long)m.WParam)) | ModifierKeys));
|
||||||
else if (m.Msg == WM_APPCOMMAND)
|
else if (m.Msg == WM_APPCOMMAND)
|
||||||
{
|
{
|
||||||
|
if (!mp.get_property_bool("input-media-keys"))
|
||||||
|
return;
|
||||||
|
|
||||||
var value = (AppCommand)(m.LParam.ToInt64() >> 16 & ~0xf000);
|
var value = (AppCommand)(m.LParam.ToInt64() >> 16 & ~0xf000);
|
||||||
|
|
||||||
switch (value)
|
switch (value)
|
||||||
@@ -317,26 +320,26 @@ namespace mpvnet
|
|||||||
out uint lpChar,
|
out uint lpChar,
|
||||||
uint flags);
|
uint flags);
|
||||||
|
|
||||||
private void Window_Loaded(object sender, RoutedEventArgs e)
|
void Window_Loaded(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
HwndSource source = HwndSource.FromHwnd(new WindowInteropHelper(this).Handle);
|
HwndSource source = HwndSource.FromHwnd(new WindowInteropHelper(this).Handle);
|
||||||
source.AddHook(new HwndSourceHook(WndProc));
|
source.AddHook(new HwndSourceHook(WndProc));
|
||||||
SetKey(InputItem.Input);
|
SetKey(InputItem.Input);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ConfirmButton_Click(object sender, RoutedEventArgs e)
|
void ConfirmButton_Click(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
InputItem.Input = NewKey;
|
InputItem.Input = NewKey;
|
||||||
Close();
|
Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ClearButton_Click(object sender, RoutedEventArgs e)
|
void ClearButton_Click(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
InputItem.Input = "_";
|
InputItem.Input = "_";
|
||||||
Close();
|
Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Window_MouseWheel(object sender, MouseWheelEventArgs e)
|
void Window_MouseWheel(object sender, MouseWheelEventArgs e)
|
||||||
{
|
{
|
||||||
if (e.Delta > 0)
|
if (e.Delta > 0)
|
||||||
SetKey("WHEEL_UP");
|
SetKey("WHEEL_UP");
|
||||||
@@ -344,7 +347,7 @@ namespace mpvnet
|
|||||||
SetKey("WHEEL_DOWN");
|
SetKey("WHEEL_DOWN");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Window_MouseUp(object sender, MouseButtonEventArgs e)
|
void Window_MouseUp(object sender, MouseButtonEventArgs e)
|
||||||
{
|
{
|
||||||
switch (e.ChangedButton)
|
switch (e.ChangedButton)
|
||||||
{
|
{
|
||||||
@@ -368,7 +371,7 @@ namespace mpvnet
|
|||||||
|
|
||||||
bool BlockMBTN_LEFT;
|
bool BlockMBTN_LEFT;
|
||||||
|
|
||||||
private void Window_MouseDoubleClick(object sender, MouseButtonEventArgs e)
|
void Window_MouseDoubleClick(object sender, MouseButtonEventArgs e)
|
||||||
{
|
{
|
||||||
if (e.ChangedButton == MouseButton.Left)
|
if (e.ChangedButton == MouseButton.Left)
|
||||||
{
|
{
|
||||||
@@ -377,7 +380,7 @@ namespace mpvnet
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Window_TextInput(object sender, TextCompositionEventArgs e)
|
void Window_TextInput(object sender, TextCompositionEventArgs e)
|
||||||
{
|
{
|
||||||
KeyChar = e.Text;
|
KeyChar = e.Text;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System.Windows;
|
|
||||||
|
using System.Windows;
|
||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
using System.Windows.Input;
|
using System.Windows.Input;
|
||||||
|
|
||||||
@@ -13,7 +14,7 @@ namespace Controls
|
|||||||
|
|
||||||
public string Text { get => SearchTextBox.Text; set => SearchTextBox.Text = value; }
|
public string Text { get => SearchTextBox.Text; set => SearchTextBox.Text = value; }
|
||||||
|
|
||||||
private string _HintText;
|
string _HintText;
|
||||||
|
|
||||||
public string HintText {
|
public string HintText {
|
||||||
get => _HintText;
|
get => _HintText;
|
||||||
@@ -23,13 +24,13 @@ namespace Controls
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SearchClearButton_Click(object sender, RoutedEventArgs e)
|
void SearchClearButton_Click(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
SearchTextBox.Text = "";
|
SearchTextBox.Text = "";
|
||||||
Keyboard.Focus(SearchTextBox);
|
Keyboard.Focus(SearchTextBox);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SearchTextBox_TextChanged(object sender, TextChangedEventArgs e)
|
void SearchTextBox_TextChanged(object sender, TextChangedEventArgs e)
|
||||||
{
|
{
|
||||||
UpdateControls();
|
UpdateControls();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
xmlns:UI="clr-namespace:UI"
|
xmlns:UI="clr-namespace:UI"
|
||||||
mc:Ignorable="d"
|
mc:Ignorable="d"
|
||||||
|
|
||||||
Title="mpv.net OS Setup"
|
Title="mpv.net Setup"
|
||||||
FontSize="13"
|
FontSize="13"
|
||||||
Foreground="{x:Static UI:Theme.Foreground}"
|
Foreground="{x:Static UI:Theme.Foreground}"
|
||||||
Background="{x:Static UI:Theme.Background}"
|
Background="{x:Static UI:Theme.Background}"
|
||||||
@@ -22,10 +22,10 @@
|
|||||||
|
|
||||||
<Grid>
|
<Grid>
|
||||||
<StackPanel Margin="10">
|
<StackPanel Margin="10">
|
||||||
<Button Name="RegisterVideo" Click="RegisterVideo_Click">Register video file extensions (requires elevated privileges)</Button>
|
<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 elevated privileges)</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 elevated privileges)</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 elevated privileges)</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="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>
|
<Button Name="RemoveFromPathEnvVar" Click="RemoveFromPathEnvVar_Click">Remove mpv.net from Path environment variable</Button>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ namespace mpvnet
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
using (var proc = new Process())
|
using (Process proc = new Process())
|
||||||
{
|
{
|
||||||
proc.StartInfo.FileName = WinForms.Application.ExecutablePath;
|
proc.StartInfo.FileName = WinForms.Application.ExecutablePath;
|
||||||
proc.StartInfo.Arguments = "--reg-file-assoc " + value;
|
proc.StartInfo.Arguments = "--reg-file-assoc " + value;
|
||||||
@@ -27,13 +27,13 @@ namespace mpvnet
|
|||||||
} catch {}
|
} catch {}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void RegisterVideo_Click(object sender, RoutedEventArgs e) => RegisterFileAssociations("video");
|
void RegisterVideo_Click(object sender, RoutedEventArgs e) => RegisterFileAssociations("video");
|
||||||
private void RegisterAudio_Click(object sender, RoutedEventArgs e) => RegisterFileAssociations("audio");
|
void RegisterAudio_Click(object sender, RoutedEventArgs e) => RegisterFileAssociations("audio");
|
||||||
private void RegisterImage_Click(object sender, RoutedEventArgs e) => RegisterFileAssociations("image");
|
void RegisterImage_Click(object sender, RoutedEventArgs e) => RegisterFileAssociations("image");
|
||||||
|
|
||||||
private void UnregisterFileAssociations_Click(object sender, RoutedEventArgs e) => RegisterFileAssociations("unreg");
|
void UnregisterFileAssociations_Click(object sender, RoutedEventArgs e) => RegisterFileAssociations("unreg");
|
||||||
|
|
||||||
private void AddToPathEnvVar_Click(object sender, RoutedEventArgs e)
|
void AddToPathEnvVar_Click(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
string var = WinForms.Application.StartupPath + ";";
|
string var = WinForms.Application.StartupPath + ";";
|
||||||
string path = Environment.GetEnvironmentVariable("Path", EnvironmentVariableTarget.User);
|
string path = Environment.GetEnvironmentVariable("Path", EnvironmentVariableTarget.User);
|
||||||
@@ -47,7 +47,7 @@ namespace mpvnet
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void RemoveFromPathEnvVar_Click(object sender, RoutedEventArgs e)
|
void RemoveFromPathEnvVar_Click(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
string var = WinForms.Application.StartupPath + ";";
|
string var = WinForms.Application.StartupPath + ";";
|
||||||
string path = Environment.GetEnvironmentVariable("Path", EnvironmentVariableTarget.User);
|
string path = Environment.GetEnvironmentVariable("Path", EnvironmentVariableTarget.User);
|
||||||
|
|||||||
@@ -10,7 +10,9 @@ using System.ComponentModel;
|
|||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
using UI;
|
using UI;
|
||||||
|
using ScriptHost;
|
||||||
|
|
||||||
namespace mpvnet
|
namespace mpvnet
|
||||||
{
|
{
|
||||||
@@ -19,12 +21,15 @@ namespace mpvnet
|
|||||||
public static MainForm Instance { get; set; }
|
public static MainForm Instance { get; set; }
|
||||||
public static IntPtr Hwnd { get; set; }
|
public static IntPtr Hwnd { get; set; }
|
||||||
public new ContextMenuStripEx ContextMenu { get; set; }
|
public new ContextMenuStripEx ContextMenu { get; set; }
|
||||||
Point LastCursorPosChanged;
|
Point LastCursorPosition;
|
||||||
int LastCursorChangedTickCount;
|
int LastCursorChanged;
|
||||||
|
int LastCycleFullscreen;
|
||||||
int TaskbarButtonCreatedMessage;
|
int TaskbarButtonCreatedMessage;
|
||||||
bool WasShown;
|
int ShownTickCount;
|
||||||
Taskbar Taskbar;
|
|
||||||
|
Taskbar Taskbar;
|
||||||
List<string> RecentFiles;
|
List<string> RecentFiles;
|
||||||
|
bool WasMaximized;
|
||||||
|
|
||||||
public MainForm()
|
public MainForm()
|
||||||
{
|
{
|
||||||
@@ -32,7 +37,7 @@ namespace mpvnet
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
object recent = RegHelp.GetObject(App.RegPath, "Recent");
|
object recent = RegistryHelp.GetValue(App.RegPath, "Recent");
|
||||||
|
|
||||||
if (recent is string[] r)
|
if (recent is string[] r)
|
||||||
RecentFiles = new List<string>(r);
|
RecentFiles = new List<string>(r);
|
||||||
@@ -41,6 +46,7 @@ namespace mpvnet
|
|||||||
|
|
||||||
Instance = this;
|
Instance = this;
|
||||||
Hwnd = Handle;
|
Hwnd = Handle;
|
||||||
|
ConsoleHelp.Padding = 60;
|
||||||
mp.Init();
|
mp.Init();
|
||||||
|
|
||||||
mp.Shutdown += Shutdown;
|
mp.Shutdown += Shutdown;
|
||||||
@@ -49,24 +55,28 @@ namespace mpvnet
|
|||||||
mp.Idle += Idle;
|
mp.Idle += Idle;
|
||||||
mp.Seek += () => UpdateProgressBar();
|
mp.Seek += () => UpdateProgressBar();
|
||||||
|
|
||||||
|
mp.observe_property("window-maximized", PropChangeWindowMaximized);
|
||||||
|
mp.observe_property("window-minimized", PropChangeWindowMinimized);
|
||||||
mp.observe_property_bool("pause", PropChangePause);
|
mp.observe_property_bool("pause", PropChangePause);
|
||||||
mp.observe_property_bool("fullscreen", PropChangeFullscreen);
|
mp.observe_property_bool("fullscreen", PropChangeFullscreen);
|
||||||
mp.observe_property_bool("ontop", PropChangeOnTop);
|
mp.observe_property_bool("ontop", PropChangeOnTop);
|
||||||
mp.observe_property_bool("border", PropChangeBorder);
|
mp.observe_property_bool("border", PropChangeBorder);
|
||||||
|
|
||||||
mp.observe_property_string("sid", PropChangeSid);
|
mp.observe_property_string("sid", PropChangeSid);
|
||||||
mp.observe_property_string("aid", PropChangeAid);
|
mp.observe_property_string("aid", PropChangeAid);
|
||||||
mp.observe_property_string("vid", PropChangeVid);
|
mp.observe_property_string("vid", PropChangeVid);
|
||||||
|
|
||||||
mp.observe_property_int("edition", PropChangeEdition);
|
mp.observe_property_int("edition", PropChangeEdition);
|
||||||
mp.observe_property_double("window-scale", PropChangeWindowScale);
|
mp.observe_property_double("window-scale", PropChangeWindowScale);
|
||||||
|
|
||||||
if (mp.GPUAPI != "vulkan")
|
if (mp.GPUAPI != "vulkan")
|
||||||
mp.ProcessCommandLine(false);
|
mp.ProcessCommandLine(false);
|
||||||
|
|
||||||
AppDomain.CurrentDomain.UnhandledException += (sender, e) => Msg.ShowError(e.ExceptionObject.ToString());
|
AppDomain.CurrentDomain.UnhandledException += (sender, e) => App.ShowException(e.ExceptionObject);
|
||||||
Application.ThreadException += (sender, e) => Msg.ShowException(e.Exception);
|
Application.ThreadException += (sender, e) => App.ShowException(e.Exception);
|
||||||
Msg.SupportURL = "https://github.com/stax76/mpv.net#support";
|
Msg.SupportURL = "https://github.com/stax76/mpv.net#support";
|
||||||
Text = "mpv.net " + Application.ProductVersion;
|
Text = "mpv.net " + Application.ProductVersion;
|
||||||
TaskbarButtonCreatedMessage = Native.RegisterWindowMessage("TaskbarButtonCreated");
|
TaskbarButtonCreatedMessage = WinAPI.RegisterWindowMessage("TaskbarButtonCreated");
|
||||||
|
|
||||||
ContextMenu = new ContextMenuStripEx(components);
|
ContextMenu = new ContextMenuStripEx(components);
|
||||||
ContextMenu.Opened += ContextMenu_Opened;
|
ContextMenu.Opened += ContextMenu_Opened;
|
||||||
@@ -89,8 +99,11 @@ namespace mpvnet
|
|||||||
Left = target.X + (target.Width - Width) / 2;
|
Left = target.X + (target.Width - Width) / 2;
|
||||||
Top = target.Y + (target.Height - Height) / 2;
|
Top = target.Y + (target.Height - Height) / 2;
|
||||||
|
|
||||||
int posX = RegHelp.GetInt(App.RegPath, "PosX");
|
if (!mp.Border)
|
||||||
int posY = RegHelp.GetInt(App.RegPath, "PosY");
|
FormBorderStyle = FormBorderStyle.None;
|
||||||
|
|
||||||
|
int posX = RegistryHelp.GetInt(App.RegPath, "PosX");
|
||||||
|
int posY = RegistryHelp.GetInt(App.RegPath, "PosY");
|
||||||
|
|
||||||
if (posX != 0 && posY != 0 && App.RememberPosition)
|
if (posX != 0 && posY != 0 && App.RememberPosition)
|
||||||
{
|
{
|
||||||
@@ -98,11 +111,17 @@ namespace mpvnet
|
|||||||
Top = posY - Height / 2;
|
Top = posY - Height / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (App.Maximized)
|
if (mp.WindowMaximized)
|
||||||
{
|
{
|
||||||
SetFormPosAndSize(1, true);
|
SetFormPosAndSize(1, true);
|
||||||
WindowState = FormWindowState.Maximized;
|
WindowState = FormWindowState.Maximized;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mp.WindowMinimized)
|
||||||
|
{
|
||||||
|
SetFormPosAndSize(1, true);
|
||||||
|
WindowState = FormWindowState.Minimized;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@@ -119,6 +138,8 @@ namespace mpvnet
|
|||||||
BeginInvoke(new Action(() => Text = "mpv.net " + Application.ProductVersion));
|
BeginInvoke(new Action(() => Text = "mpv.net " + Application.ProductVersion));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool WasShown() => ShownTickCount != 0 && Environment.TickCount > ShownTickCount + 500;
|
||||||
|
|
||||||
void CM_Popup(object sender, EventArgs e) => CursorHelp.Show();
|
void CM_Popup(object sender, EventArgs e) => CursorHelp.Show();
|
||||||
|
|
||||||
void VideoSizeChanged() => BeginInvoke(new Action(() => SetFormPosAndSize()));
|
void VideoSizeChanged() => BeginInvoke(new Action(() => SetFormPosAndSize()));
|
||||||
@@ -129,7 +150,16 @@ namespace mpvnet
|
|||||||
|
|
||||||
bool IsFullscreen => WindowState == FormWindowState.Maximized && FormBorderStyle == FormBorderStyle.None;
|
bool IsFullscreen => WindowState == FormWindowState.Maximized && FormBorderStyle == FormBorderStyle.None;
|
||||||
|
|
||||||
bool IsMouseInOSC() => PointToClient(Control.MousePosition).Y > ClientSize.Height * 0.9;
|
bool IsMouseInOSC()
|
||||||
|
{
|
||||||
|
Point pos = PointToClient(Control.MousePosition);
|
||||||
|
float top = 0;
|
||||||
|
|
||||||
|
if (FormBorderStyle == FormBorderStyle.None)
|
||||||
|
top = ClientSize.Height * 0.1f;
|
||||||
|
|
||||||
|
return pos.Y > ClientSize.Height * 0.85 || pos.Y < top;
|
||||||
|
}
|
||||||
|
|
||||||
void ContextMenu_Opening(object sender, CancelEventArgs e)
|
void ContextMenu_Opening(object sender, CancelEventArgs e)
|
||||||
{
|
{
|
||||||
@@ -222,7 +252,7 @@ namespace mpvnet
|
|||||||
recent.DropDownItems.Clear();
|
recent.DropDownItems.Clear();
|
||||||
|
|
||||||
foreach (string path in RecentFiles)
|
foreach (string path in RecentFiles)
|
||||||
MenuItem.Add(recent.DropDownItems, path, () => mp.Load(new[] { path }, true, Control.ModifierKeys.HasFlag(Keys.Control)));
|
MenuItem.Add(recent.DropDownItems, path, () => mp.LoadFiles(new[] { path }, true, Control.ModifierKeys.HasFlag(Keys.Control)));
|
||||||
|
|
||||||
recent.DropDownItems.Add(new ToolStripSeparator());
|
recent.DropDownItems.Add(new ToolStripSeparator());
|
||||||
MenuItem mi = new MenuItem("Clear List");
|
MenuItem mi = new MenuItem("Clear List");
|
||||||
@@ -250,13 +280,11 @@ namespace mpvnet
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WasInitialSizeSet;
|
|
||||||
|
|
||||||
void SetFormPosAndSize(double scale = 1, bool force = false)
|
void SetFormPosAndSize(double scale = 1, bool force = false)
|
||||||
{
|
{
|
||||||
if (!force)
|
if (!force)
|
||||||
{
|
{
|
||||||
if (WindowState == FormWindowState.Maximized)
|
if (WindowState != FormWindowState.Normal)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (mp.Fullscreen)
|
if (mp.Fullscreen)
|
||||||
@@ -274,49 +302,49 @@ namespace mpvnet
|
|||||||
|
|
||||||
mp.VideoSize = new Size((int)(autoFitHeight * (16 / 9.0)), autoFitHeight);
|
mp.VideoSize = new Size((int)(autoFitHeight * (16 / 9.0)), autoFitHeight);
|
||||||
|
|
||||||
Size size = mp.VideoSize;
|
Size videoSize = mp.VideoSize;
|
||||||
int height = size.Height;
|
int height = videoSize.Height;
|
||||||
|
|
||||||
if (App.RememberHeight)
|
if (mp.WasInitialSizeSet || scale != 1)
|
||||||
|
height = ClientSize.Height;
|
||||||
|
else
|
||||||
{
|
{
|
||||||
if (WasInitialSizeSet)
|
int savedHeight = RegistryHelp.GetInt(App.RegPath, "Height");
|
||||||
height = ClientSize.Height;
|
|
||||||
|
if (App.StartSize == "always" && savedHeight != 0)
|
||||||
|
height = savedHeight;
|
||||||
else
|
else
|
||||||
{
|
if (App.StartSize != "video")
|
||||||
height = autoFitHeight;
|
height = autoFitHeight;
|
||||||
WasInitialSizeSet = true;
|
|
||||||
}
|
mp.WasInitialSizeSet = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
height = Convert.ToInt32(height * scale);
|
height = Convert.ToInt32(height * scale);
|
||||||
int width = Convert.ToInt32(height * size.Width / (double)size.Height);
|
int width = Convert.ToInt32(height * videoSize.Width / (double)videoSize.Height);
|
||||||
|
int maxHeight = screen.WorkingArea.Height - (Height - ClientSize.Height);
|
||||||
|
int maxWidth = screen.WorkingArea.Width - (Width - ClientSize.Width);
|
||||||
|
|
||||||
if (height > screen.WorkingArea.Height * 0.9)
|
if (height < maxHeight * mp.AutofitSmaller)
|
||||||
{
|
{
|
||||||
height = Convert.ToInt32(screen.WorkingArea.Height * 0.9);
|
height = Convert.ToInt32(maxHeight * mp.AutofitSmaller);
|
||||||
width = Convert.ToInt32(height * size.Width / (double)size.Height);
|
width = Convert.ToInt32(height * videoSize.Width / (double)videoSize.Height);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (width > screen.WorkingArea.Width * 0.9)
|
if (height > maxHeight * mp.AutofitLarger)
|
||||||
{
|
{
|
||||||
width = Convert.ToInt32(screen.WorkingArea.Width * 0.9);
|
height = Convert.ToInt32(maxHeight * mp.AutofitLarger);
|
||||||
height = Convert.ToInt32(width * size.Height / (double)size.Width);
|
width = Convert.ToInt32(height * videoSize.Width / (double)videoSize.Height);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (height < screen.WorkingArea.Height * mp.AutofitSmaller)
|
if (width > maxWidth)
|
||||||
{
|
{
|
||||||
height = Convert.ToInt32(screen.WorkingArea.Height * mp.AutofitSmaller);
|
width = maxWidth;
|
||||||
width = Convert.ToInt32(height * size.Width / (double)size.Height);
|
height = Convert.ToInt32(width * videoSize.Height / (double)videoSize.Width);
|
||||||
}
|
|
||||||
|
|
||||||
if (height > screen.WorkingArea.Height * mp.AutofitLarger)
|
|
||||||
{
|
|
||||||
height = Convert.ToInt32(screen.WorkingArea.Height * mp.AutofitLarger);
|
|
||||||
width = Convert.ToInt32(height * size.Width / (double)size.Height);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Point middlePos = new Point(Left + Width / 2, Top + Height / 2);
|
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));
|
var rect = new WinAPI.RECT(new Rectangle(screen.Bounds.X, screen.Bounds.Y, width, height));
|
||||||
NativeHelp.AddWindowBorders(Handle, ref rect);
|
NativeHelp.AddWindowBorders(Handle, ref rect);
|
||||||
int left = middlePos.X - rect.Width / 2;
|
int left = middlePos.X - rect.Width / 2;
|
||||||
int top = middlePos.Y - rect.Height / 2;
|
int top = middlePos.Y - rect.Height / 2;
|
||||||
@@ -339,29 +367,39 @@ namespace mpvnet
|
|||||||
if (top + rect.Height > maxBottom)
|
if (top + rect.Height > maxBottom)
|
||||||
top = maxBottom - rect.Height;
|
top = maxBottom - rect.Height;
|
||||||
|
|
||||||
Native.SetWindowPos(Handle, IntPtr.Zero /* HWND_TOP */, left, top, rect.Width, rect.Height, 4 /* SWP_NOZORDER */);
|
WinAPI.SetWindowPos(Handle, IntPtr.Zero /* HWND_TOP */,
|
||||||
|
left, top, rect.Width, rect.Height, 4 /* SWP_NOZORDER */);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void CycleFullscreen(bool enabled)
|
public void CycleFullscreen(bool enabled)
|
||||||
{
|
{
|
||||||
|
LastCycleFullscreen = Environment.TickCount;
|
||||||
mp.Fullscreen = enabled;
|
mp.Fullscreen = enabled;
|
||||||
|
|
||||||
if (enabled)
|
if (enabled)
|
||||||
{
|
{
|
||||||
if (WindowState != FormWindowState.Maximized || FormBorderStyle != FormBorderStyle.None)
|
if (WindowState != FormWindowState.Maximized || FormBorderStyle != FormBorderStyle.None)
|
||||||
{
|
{
|
||||||
if (WindowState == FormWindowState.Maximized)
|
|
||||||
WindowState = FormWindowState.Minimized;
|
|
||||||
|
|
||||||
FormBorderStyle = FormBorderStyle.None;
|
FormBorderStyle = FormBorderStyle.None;
|
||||||
WindowState = FormWindowState.Maximized;
|
WindowState = FormWindowState.Maximized;
|
||||||
|
|
||||||
|
if (WasMaximized)
|
||||||
|
{
|
||||||
|
Rectangle b = Screen.FromControl(this).Bounds;
|
||||||
|
uint SWP_SHOWWINDOW = 0x0040;
|
||||||
|
IntPtr HWND_TOP= IntPtr.Zero;
|
||||||
|
WinAPI.SetWindowPos(Handle, HWND_TOP, b.X, b.Y, b.Width, b.Height, SWP_SHOWWINDOW);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (WindowState == FormWindowState.Maximized && FormBorderStyle == FormBorderStyle.None)
|
if (WindowState == FormWindowState.Maximized && FormBorderStyle == FormBorderStyle.None)
|
||||||
{
|
{
|
||||||
WindowState = FormWindowState.Normal;
|
if (WasMaximized)
|
||||||
|
WindowState = FormWindowState.Maximized;
|
||||||
|
else
|
||||||
|
WindowState = FormWindowState.Normal;
|
||||||
|
|
||||||
if (mp.Border)
|
if (mp.Border)
|
||||||
FormBorderStyle = FormBorderStyle.Sizable;
|
FormBorderStyle = FormBorderStyle.Sizable;
|
||||||
@@ -369,6 +407,7 @@ namespace mpvnet
|
|||||||
FormBorderStyle = FormBorderStyle.None;
|
FormBorderStyle = FormBorderStyle.None;
|
||||||
|
|
||||||
SetFormPosAndSize();
|
SetFormPosAndSize();
|
||||||
|
SaveWindowProperties();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -380,7 +419,7 @@ namespace mpvnet
|
|||||||
|
|
||||||
if (!content.Contains("#menu:"))
|
if (!content.Contains("#menu:"))
|
||||||
{
|
{
|
||||||
var defaultItems = CommandItem.GetItems(Properties.Resources.inputConf);
|
var defaultItems = CommandItem.GetItems(Properties.Resources.input_conf);
|
||||||
|
|
||||||
foreach (CommandItem item in items)
|
foreach (CommandItem item in items)
|
||||||
foreach (CommandItem defaultItem in defaultItems)
|
foreach (CommandItem defaultItem in defaultItems)
|
||||||
@@ -410,7 +449,7 @@ namespace mpvnet
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void FileLoaded()
|
void FileLoaded()
|
||||||
{
|
{
|
||||||
string path = mp.get_property_string("path");
|
string path = mp.get_property_string("path");
|
||||||
|
|
||||||
@@ -438,6 +477,16 @@ namespace mpvnet
|
|||||||
RecentFiles.RemoveAt(App.RecentCount);
|
RecentFiles.RemoveAt(App.RecentCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SaveWindowProperties()
|
||||||
|
{
|
||||||
|
if (WindowState == FormWindowState.Normal)
|
||||||
|
{
|
||||||
|
RegistryHelp.SetValue(App.RegPath, "PosX", Left + Width / 2);
|
||||||
|
RegistryHelp.SetValue(App.RegPath, "PosY", Top + Height / 2);
|
||||||
|
RegistryHelp.SetValue(App.RegPath, "Height", ClientSize.Height);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected override CreateParams CreateParams {
|
protected override CreateParams CreateParams {
|
||||||
get {
|
get {
|
||||||
CreateParams cp = base.CreateParams;
|
CreateParams cp = base.CreateParams;
|
||||||
@@ -452,84 +501,97 @@ namespace mpvnet
|
|||||||
|
|
||||||
switch (m.Msg)
|
switch (m.Msg)
|
||||||
{
|
{
|
||||||
case 0x0201: // WM_LBUTTONDOWN
|
case 0x201: // WM_LBUTTONDOWN
|
||||||
case 0x0202: // WM_LBUTTONUP
|
case 0x202: // WM_LBUTTONUP
|
||||||
case 0x0207: // WM_MBUTTONDOWN
|
case 0x207: // WM_MBUTTONDOWN
|
||||||
case 0x0208: // WM_MBUTTONUP
|
case 0x208: // WM_MBUTTONUP
|
||||||
case 0x020b: // WM_XBUTTONDOWN
|
case 0x20b: // WM_XBUTTONDOWN
|
||||||
case 0x020c: // WM_XBUTTONUP
|
case 0x20c: // WM_XBUTTONUP
|
||||||
case 0x020A: // WM_MOUSEWHEEL
|
case 0x20A: // WM_MOUSEWHEEL
|
||||||
case 0x0100: // WM_KEYDOWN
|
case 0x100: // WM_KEYDOWN
|
||||||
case 0x0101: // WM_KEYUP
|
case 0x101: // WM_KEYUP
|
||||||
case 0x0104: // WM_SYSKEYDOWN
|
case 0x102: // WM_CHAR
|
||||||
case 0x0105: // WM_SYSKEYUP
|
case 0x104: // WM_SYSKEYDOWN
|
||||||
case 0x319: // WM_APPCOMMAND
|
case 0x105: // WM_SYSKEYUP
|
||||||
|
case 0x106: // WM_SYSCHAR
|
||||||
|
case 0x319: // WM_APPCOMMAND
|
||||||
if (mp.WindowHandle != IntPtr.Zero)
|
if (mp.WindowHandle != IntPtr.Zero)
|
||||||
Native.SendMessage(mp.WindowHandle, m.Msg, m.WParam, m.LParam);
|
m.Result = WinAPI.SendMessage(mp.WindowHandle, m.Msg, m.WParam, m.LParam);
|
||||||
break;
|
break;
|
||||||
case 0x0200: // WM_MOUSEMOVE
|
case 0x0200: // WM_MOUSEMOVE
|
||||||
|
if (Environment.TickCount - LastCycleFullscreen > 500)
|
||||||
{
|
{
|
||||||
Point pos = PointToClient(Cursor.Position);
|
Point pos = PointToClient(Cursor.Position);
|
||||||
mp.command($"mouse {pos.X} {pos.Y}");
|
mp.command($"mouse {pos.X} {pos.Y}");
|
||||||
if (CursorHelp.IsPosDifferent(LastCursorPosChanged)) CursorHelp.Show();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (CursorHelp.IsPosDifferent(LastCursorPosition))
|
||||||
|
CursorHelp.Show();
|
||||||
break;
|
break;
|
||||||
case 0x2a3: // WM_MOUSELEAVE
|
case 0x2a3: // WM_MOUSELEAVE
|
||||||
mp.command("mouse 1 1"); // osc won't always auto hide
|
//osc won't auto hide after mouse left window in borderless mode
|
||||||
|
mp.command($"mouse {ClientSize.Width / 2} {ClientSize.Height / 3}");
|
||||||
break;
|
break;
|
||||||
case 0x203: // Native.WM.LBUTTONDBLCLK
|
case 0x203: // WM_LBUTTONDBLCLK
|
||||||
{
|
{
|
||||||
Point pos = PointToClient(Cursor.Position);
|
Point pos = PointToClient(Cursor.Position);
|
||||||
mp.command($"mouse {pos.X} {pos.Y} 0 double");
|
mp.command($"mouse {pos.X} {pos.Y} 0 double");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x02E0: // WM_DPICHANGED
|
case 0x02E0: // WM_DPICHANGED
|
||||||
if (!WasShown)
|
{
|
||||||
break;
|
if (!WasShown())
|
||||||
var r2 = Marshal.PtrToStructure<Native.RECT>(m.LParam);
|
break;
|
||||||
Native.SetWindowPos(Handle, IntPtr.Zero, r2.Left, r2.Top, r2.Width, r2.Height, 0);
|
|
||||||
|
WinAPI.RECT rect = Marshal.PtrToStructure<WinAPI.RECT>(m.LParam);
|
||||||
|
WinAPI.SetWindowPos(Handle, IntPtr.Zero, rect.Left, rect.Top, rect.Width, rect.Height, 0);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 0x0214: // WM_SIZING
|
case 0x0214: // WM_SIZING
|
||||||
var rc = Marshal.PtrToStructure<Native.RECT>(m.LParam);
|
{
|
||||||
var r = rc;
|
var rc = Marshal.PtrToStructure<WinAPI.RECT>(m.LParam);
|
||||||
NativeHelp.SubtractWindowBorders(Handle, ref r);
|
var r = rc;
|
||||||
int c_w = r.Right - r.Left, c_h = r.Bottom - r.Top;
|
NativeHelp.SubtractWindowBorders(Handle, ref r);
|
||||||
Size s = mp.VideoSize;
|
int c_w = r.Right - r.Left, c_h = r.Bottom - r.Top;
|
||||||
|
Size s = mp.VideoSize;
|
||||||
|
|
||||||
if (s == Size.Empty)
|
if (s == Size.Empty)
|
||||||
s = new Size(16, 9);
|
s = new Size(16, 9);
|
||||||
|
|
||||||
float aspect = s.Width / (float)s.Height;
|
float aspect = s.Width / (float)s.Height;
|
||||||
int d_w = Convert.ToInt32(c_h * aspect - c_w);
|
int d_w = Convert.ToInt32(c_h * aspect - c_w);
|
||||||
int d_h = Convert.ToInt32(c_w / aspect - c_h);
|
int d_h = Convert.ToInt32(c_w / aspect - c_h);
|
||||||
int[] d_corners = { d_w, d_h, -d_w, -d_h };
|
int[] d_corners = { d_w, d_h, -d_w, -d_h };
|
||||||
int[] corners = { rc.Left, rc.Top, rc.Right, rc.Bottom };
|
int[] corners = { rc.Left, rc.Top, rc.Right, rc.Bottom };
|
||||||
int corner = NativeHelp.GetResizeBorder(m.WParam.ToInt32());
|
int corner = NativeHelp.GetResizeBorder(m.WParam.ToInt32());
|
||||||
|
|
||||||
if (corner >= 0)
|
if (corner >= 0)
|
||||||
corners[corner] -= d_corners[corner];
|
corners[corner] -= d_corners[corner];
|
||||||
|
|
||||||
Marshal.StructureToPtr<Native.RECT>(new Native.RECT(corners[0], corners[1], corners[2], corners[3]), m.LParam, false);
|
Marshal.StructureToPtr<WinAPI.RECT>(new WinAPI.RECT(corners[0], corners[1], corners[2], corners[3]), m.LParam, false);
|
||||||
m.Result = new IntPtr(1);
|
m.Result = new IntPtr(1);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
case 0x004A: // WM_COPYDATA
|
case 0x004A: // WM_COPYDATA
|
||||||
var copyData = (Native.COPYDATASTRUCT)m.GetLParam(typeof(Native.COPYDATASTRUCT));
|
|
||||||
string[] files = copyData.lpData.Split('\n');
|
|
||||||
string mode = files[0];
|
|
||||||
files = files.Skip(1).ToArray();
|
|
||||||
|
|
||||||
switch (mode)
|
|
||||||
{
|
{
|
||||||
case "single":
|
var copyData = (WinAPI.COPYDATASTRUCT)m.GetLParam(typeof(WinAPI.COPYDATASTRUCT));
|
||||||
mp.Load(files, true, Control.ModifierKeys.HasFlag(Keys.Control));
|
string[] files = copyData.lpData.Split('\n');
|
||||||
break;
|
string mode = files[0];
|
||||||
case "queue":
|
files = files.Skip(1).ToArray();
|
||||||
foreach (string file in files)
|
|
||||||
mp.commandv("loadfile", file, "append");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
Activate();
|
switch (mode)
|
||||||
|
{
|
||||||
|
case "single":
|
||||||
|
mp.LoadFiles(files, true, Control.ModifierKeys.HasFlag(Keys.Control));
|
||||||
|
break;
|
||||||
|
case "queue":
|
||||||
|
foreach (string file in files)
|
||||||
|
mp.commandv("loadfile", file, "append");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
Activate();
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -544,19 +606,19 @@ namespace mpvnet
|
|||||||
|
|
||||||
void CursorTimer_Tick(object sender, EventArgs e)
|
void CursorTimer_Tick(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
if (CursorHelp.IsPosDifferent(LastCursorPosChanged))
|
if (CursorHelp.IsPosDifferent(LastCursorPosition))
|
||||||
{
|
{
|
||||||
LastCursorPosChanged = Control.MousePosition;
|
LastCursorPosition = Control.MousePosition;
|
||||||
LastCursorChangedTickCount = Environment.TickCount;
|
LastCursorChanged = Environment.TickCount;
|
||||||
}
|
}
|
||||||
else if (Environment.TickCount - LastCursorChangedTickCount > 1500 &&
|
else if (Environment.TickCount - LastCursorChanged > 1500 &&
|
||||||
!IsMouseInOSC() && ClientRectangle.Contains(PointToClient(MousePosition)) &&
|
!IsMouseInOSC() && ClientRectangle.Contains(PointToClient(MousePosition)) &&
|
||||||
Form.ActiveForm == this && !ContextMenu.Visible)
|
Form.ActiveForm == this && !ContextMenu.Visible)
|
||||||
|
|
||||||
CursorHelp.Hide();
|
CursorHelp.Hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ProgressTimer_Tick(object sender, EventArgs e) => UpdateProgressBar();
|
void ProgressTimer_Tick(object sender, EventArgs e) => UpdateProgressBar();
|
||||||
|
|
||||||
void UpdateProgressBar()
|
void UpdateProgressBar()
|
||||||
{
|
{
|
||||||
@@ -583,6 +645,38 @@ namespace mpvnet
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PropChangeWindowMaximized()
|
||||||
|
{
|
||||||
|
if (!WasShown())
|
||||||
|
return;
|
||||||
|
|
||||||
|
BeginInvoke(new Action(() =>
|
||||||
|
{
|
||||||
|
mp.WindowMaximized = mp.get_property_bool("window-maximized");
|
||||||
|
|
||||||
|
if (mp.WindowMaximized && WindowState != FormWindowState.Maximized)
|
||||||
|
WindowState = FormWindowState.Maximized;
|
||||||
|
else if (!mp.WindowMaximized && WindowState == FormWindowState.Maximized)
|
||||||
|
WindowState = FormWindowState.Normal;
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
void PropChangeWindowMinimized()
|
||||||
|
{
|
||||||
|
if (!WasShown())
|
||||||
|
return;
|
||||||
|
|
||||||
|
BeginInvoke(new Action(() =>
|
||||||
|
{
|
||||||
|
mp.WindowMinimized = mp.get_property_bool("window-minimized");
|
||||||
|
|
||||||
|
if (mp.WindowMinimized && WindowState != FormWindowState.Minimized)
|
||||||
|
WindowState = FormWindowState.Minimized;
|
||||||
|
else if (!mp.WindowMinimized && WindowState == FormWindowState.Minimized)
|
||||||
|
WindowState = FormWindowState.Normal;
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
void PropChangeBorder(bool enabled) {
|
void PropChangeBorder(bool enabled) {
|
||||||
mp.Border = enabled;
|
mp.Border = enabled;
|
||||||
|
|
||||||
@@ -616,6 +710,7 @@ namespace mpvnet
|
|||||||
if (mp.GPUAPI != "vulkan")
|
if (mp.GPUAPI != "vulkan")
|
||||||
mp.VideoSizeAutoResetEvent.WaitOne(App.StartThreshold);
|
mp.VideoSizeAutoResetEvent.WaitOne(App.StartThreshold);
|
||||||
|
|
||||||
|
LastCycleFullscreen = Environment.TickCount;
|
||||||
SetFormPosAndSize();
|
SetFormPosAndSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -628,18 +723,26 @@ namespace mpvnet
|
|||||||
|
|
||||||
ToolStripRendererEx.ForegroundColor = Theme.Current.GetWinFormsColor("menu-foreground");
|
ToolStripRendererEx.ForegroundColor = Theme.Current.GetWinFormsColor("menu-foreground");
|
||||||
ToolStripRendererEx.BackgroundColor = Theme.Current.GetWinFormsColor("menu-background");
|
ToolStripRendererEx.BackgroundColor = Theme.Current.GetWinFormsColor("menu-background");
|
||||||
ToolStripRendererEx.SelectionColor = Theme.Current.GetWinFormsColor("menu-highlight");
|
ToolStripRendererEx.SelectionColor = Theme.Current.GetWinFormsColor("menu-highlight");
|
||||||
ToolStripRendererEx.BorderColor = Theme.Current.GetWinFormsColor("menu-border");
|
ToolStripRendererEx.BorderColor = Theme.Current.GetWinFormsColor("menu-border");
|
||||||
ToolStripRendererEx.CheckedColor = Theme.Current.GetWinFormsColor("menu-checked");
|
ToolStripRendererEx.CheckedColor = Theme.Current.GetWinFormsColor("menu-checked");
|
||||||
|
|
||||||
BuildMenu();
|
BuildMenu();
|
||||||
ContextMenuStrip = ContextMenu;
|
ContextMenuStrip = ContextMenu;
|
||||||
WPF.WPF.Init();
|
WPF.WPF.Init();
|
||||||
System.Windows.Application.Current.ShutdownMode = System.Windows.ShutdownMode.OnExplicitShutdown;
|
System.Windows.Application.Current.ShutdownMode = System.Windows.ShutdownMode.OnExplicitShutdown;
|
||||||
Cursor.Position = new Point(Cursor.Position.X + 1, Cursor.Position.Y);
|
Cursor.Position = new Point(Cursor.Position.X + 1, Cursor.Position.Y);
|
||||||
WasShown = true;
|
UpdateCheck.DailyCheck();
|
||||||
mp.LoadScripts();
|
mp.LoadScripts();
|
||||||
Task.Run(() => App.Extension = new Extension());
|
Task.Run(() => App.Extension = new Extension());
|
||||||
|
ShownTickCount = Environment.TickCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnActivated(EventArgs e)
|
||||||
|
{
|
||||||
|
base.OnActivated(e);
|
||||||
|
Message m = new Message() { Msg = 0x0202 }; // WM_LBUTTONUP
|
||||||
|
WinAPI.SendMessage(MainForm.Instance.Handle, m.Msg, m.WParam, m.LParam);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnResize(EventArgs e)
|
protected override void OnResize(EventArgs e)
|
||||||
@@ -648,25 +751,49 @@ namespace mpvnet
|
|||||||
|
|
||||||
if (mp.IsLogoVisible)
|
if (mp.IsLogoVisible)
|
||||||
mp.ShowLogo();
|
mp.ShowLogo();
|
||||||
|
|
||||||
|
if (FormBorderStyle != FormBorderStyle.None)
|
||||||
|
{
|
||||||
|
if (WindowState == FormWindowState.Maximized)
|
||||||
|
WasMaximized = true;
|
||||||
|
else if (WindowState == FormWindowState.Normal)
|
||||||
|
WasMaximized = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (WasShown())
|
||||||
|
{
|
||||||
|
if (WindowState == FormWindowState.Minimized)
|
||||||
|
{
|
||||||
|
mp.set_property_string("window-minimized", "yes");
|
||||||
|
}
|
||||||
|
else if (WindowState == FormWindowState.Normal)
|
||||||
|
{
|
||||||
|
mp.set_property_string("window-maximized", "no");
|
||||||
|
mp.set_property_string("window-minimized", "no");
|
||||||
|
}
|
||||||
|
else if (WindowState == FormWindowState.Maximized)
|
||||||
|
{
|
||||||
|
mp.set_property_string("window-maximized", "yes");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnFormClosing(FormClosingEventArgs e)
|
protected override void OnFormClosing(FormClosingEventArgs e)
|
||||||
{
|
{
|
||||||
base.OnFormClosing(e);
|
base.OnFormClosing(e);
|
||||||
|
SaveWindowProperties();
|
||||||
if (WindowState == FormWindowState.Normal)
|
RegistryHelp.SetValue(App.RegPath, "Recent", RecentFiles.ToArray());
|
||||||
{
|
|
||||||
RegHelp.SetObject(App.RegPath, "PosX", Left + Width / 2);
|
|
||||||
RegHelp.SetObject(App.RegPath, "PosY", Top + Height / 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
RegHelp.SetObject(App.RegPath, "Recent", RecentFiles.ToArray());
|
|
||||||
|
|
||||||
if (mp.IsQuitNeeded)
|
if (mp.IsQuitNeeded)
|
||||||
mp.commandv("quit");
|
mp.commandv("quit");
|
||||||
|
|
||||||
if (!mp.ShutdownAutoResetEvent.WaitOne(10000))
|
if (!mp.ShutdownAutoResetEvent.WaitOne(10000))
|
||||||
Msg.ShowError("Shutdown thread failed to complete within 10 seconds.");
|
Msg.ShowError("Shutdown thread failed to complete within 10 seconds.");
|
||||||
|
|
||||||
|
try { // PowerShell 5.1 might not be available
|
||||||
|
foreach (PowerShell ps in PowerShell.Instances)
|
||||||
|
ps.Runspace.Dispose();
|
||||||
|
} catch {}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnMouseDown(MouseEventArgs e)
|
protected override void OnMouseDown(MouseEventArgs e)
|
||||||
@@ -674,12 +801,11 @@ namespace mpvnet
|
|||||||
base.OnMouseDown(e);
|
base.OnMouseDown(e);
|
||||||
|
|
||||||
if (WindowState == FormWindowState.Normal &&
|
if (WindowState == FormWindowState.Normal &&
|
||||||
e.Button == MouseButtons.Left &&
|
e.Button == MouseButtons.Left && !IsMouseInOSC())
|
||||||
e.Y < ClientSize.Height * 0.9)
|
|
||||||
{
|
{
|
||||||
var HTCAPTION = new IntPtr(2);
|
var HTCAPTION = new IntPtr(2);
|
||||||
Native.ReleaseCapture();
|
WinAPI.ReleaseCapture();
|
||||||
Native.PostMessage(Handle, 0xA1 /* WM_NCLBUTTONDOWN */, HTCAPTION, IntPtr.Zero);
|
WinAPI.PostMessage(Handle, 0xA1 /* WM_NCLBUTTONDOWN */, HTCAPTION, IntPtr.Zero);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Width - e.Location.X < 10 && e.Location.Y < 10)
|
if (Width - e.Location.X < 10 && e.Location.Y < 10)
|
||||||
@@ -699,10 +825,10 @@ namespace mpvnet
|
|||||||
base.OnDragDrop(e);
|
base.OnDragDrop(e);
|
||||||
|
|
||||||
if (e.Data.GetDataPresent(DataFormats.FileDrop))
|
if (e.Data.GetDataPresent(DataFormats.FileDrop))
|
||||||
mp.Load(e.Data.GetData(DataFormats.FileDrop) as String[], true, Control.ModifierKeys.HasFlag(Keys.Control));
|
mp.LoadFiles(e.Data.GetData(DataFormats.FileDrop) as String[], true, Control.ModifierKeys.HasFlag(Keys.Control));
|
||||||
|
|
||||||
if (e.Data.GetDataPresent(DataFormats.Text))
|
if (e.Data.GetDataPresent(DataFormats.Text))
|
||||||
mp.Load(new[] { e.Data.GetData(DataFormats.Text).ToString() }, true, Control.ModifierKeys.HasFlag(Keys.Control));
|
mp.LoadFiles(new[] { e.Data.GetData(DataFormats.Text).ToString() }, true, Control.ModifierKeys.HasFlag(Keys.Control));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnLostFocus(EventArgs e)
|
protected override void OnLostFocus(EventArgs e)
|
||||||
|
|||||||
@@ -39,7 +39,7 @@
|
|||||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||||
<DebugType>full</DebugType>
|
<DebugType>full</DebugType>
|
||||||
<PlatformTarget>x86</PlatformTarget>
|
<PlatformTarget>x86</PlatformTarget>
|
||||||
<GenerateSerializationAssemblies>On</GenerateSerializationAssemblies>
|
<GenerateSerializationAssemblies>Auto</GenerateSerializationAssemblies>
|
||||||
<LangVersion>7.3</LangVersion>
|
<LangVersion>7.3</LangVersion>
|
||||||
<ErrorReport>prompt</ErrorReport>
|
<ErrorReport>prompt</ErrorReport>
|
||||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||||
@@ -52,6 +52,7 @@
|
|||||||
<PlatformTarget>x86</PlatformTarget>
|
<PlatformTarget>x86</PlatformTarget>
|
||||||
<ErrorReport>prompt</ErrorReport>
|
<ErrorReport>prompt</ErrorReport>
|
||||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||||
|
<GenerateSerializationAssemblies>Auto</GenerateSerializationAssemblies>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
|
||||||
<DebugSymbols>true</DebugSymbols>
|
<DebugSymbols>true</DebugSymbols>
|
||||||
@@ -59,7 +60,7 @@
|
|||||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||||
<DebugType>full</DebugType>
|
<DebugType>full</DebugType>
|
||||||
<PlatformTarget>x64</PlatformTarget>
|
<PlatformTarget>x64</PlatformTarget>
|
||||||
<GenerateSerializationAssemblies>On</GenerateSerializationAssemblies>
|
<GenerateSerializationAssemblies>Auto</GenerateSerializationAssemblies>
|
||||||
<LangVersion>7.3</LangVersion>
|
<LangVersion>7.3</LangVersion>
|
||||||
<ErrorReport>prompt</ErrorReport>
|
<ErrorReport>prompt</ErrorReport>
|
||||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||||
@@ -72,6 +73,7 @@
|
|||||||
<PlatformTarget>x64</PlatformTarget>
|
<PlatformTarget>x64</PlatformTarget>
|
||||||
<ErrorReport>prompt</ErrorReport>
|
<ErrorReport>prompt</ErrorReport>
|
||||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||||
|
<GenerateSerializationAssemblies>Auto</GenerateSerializationAssemblies>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Reference Include="IKVM.Reflection, Version=7.2.4630.5, Culture=neutral, PublicKeyToken=13235d27fcbfff58, processorArchitecture=MSIL">
|
<Reference Include="IKVM.Reflection, Version=7.2.4630.5, Culture=neutral, PublicKeyToken=13235d27fcbfff58, processorArchitecture=MSIL">
|
||||||
@@ -108,6 +110,7 @@
|
|||||||
<Reference Include="System.Management.Automation, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
<Reference Include="System.Management.Automation, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||||
<HintPath>..\packages\Microsoft.PowerShell.5.ReferenceAssemblies.1.1.0\lib\net4\System.Management.Automation.dll</HintPath>
|
<HintPath>..\packages\Microsoft.PowerShell.5.ReferenceAssemblies.1.1.0\lib\net4\System.Management.Automation.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
|
<Reference Include="System.Net.Http" />
|
||||||
<Reference Include="System.Windows.Forms" />
|
<Reference Include="System.Windows.Forms" />
|
||||||
<Reference Include="System.Xaml" />
|
<Reference Include="System.Xaml" />
|
||||||
<Reference Include="System.Xml" />
|
<Reference Include="System.Xml" />
|
||||||
@@ -115,8 +118,16 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="Misc\App.cs" />
|
<Compile Include="Misc\App.cs" />
|
||||||
|
<Compile Include="Misc\NewLine.cs" />
|
||||||
<Compile Include="Misc\Extension.cs" />
|
<Compile Include="Misc\Extension.cs" />
|
||||||
|
<Content Include="..\License.txt">
|
||||||
|
<Link>License.txt</Link>
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
</Content>
|
||||||
<Content Include="Resources\theme.txt" />
|
<Content Include="Resources\theme.txt" />
|
||||||
|
<None Include="Update.ps1">
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
<Page Include="WPF\SearchTextBoxUserControl.xaml">
|
<Page Include="WPF\SearchTextBoxUserControl.xaml">
|
||||||
<Generator>MSBuild:Compile</Generator>
|
<Generator>MSBuild:Compile</Generator>
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
@@ -142,7 +153,10 @@
|
|||||||
<Generator>MSBuild:Compile</Generator>
|
<Generator>MSBuild:Compile</Generator>
|
||||||
</Page>
|
</Page>
|
||||||
<Compile Include="Misc\Help.cs" />
|
<Compile Include="Misc\Help.cs" />
|
||||||
|
<Compile Include="Misc\UpdateCheck.cs" />
|
||||||
|
<Compile Include="Misc\RegistryHelp.cs" />
|
||||||
<Compile Include="Misc\Theme.cs" />
|
<Compile Include="Misc\Theme.cs" />
|
||||||
|
<Compile Include="Scripting\PowerShell.cs" />
|
||||||
<Compile Include="WPF\SearchTextBoxUserControl.xaml.cs">
|
<Compile Include="WPF\SearchTextBoxUserControl.xaml.cs">
|
||||||
<DependentUpon>SearchTextBoxUserControl.xaml</DependentUpon>
|
<DependentUpon>SearchTextBoxUserControl.xaml</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
@@ -160,13 +174,12 @@
|
|||||||
<Compile Include="WinForms\Menu.cs">
|
<Compile Include="WinForms\Menu.cs">
|
||||||
<SubType>Component</SubType>
|
<SubType>Component</SubType>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="Scripting\PowerShellScript.cs" />
|
|
||||||
<Compile Include="Properties\Resources.Designer.cs">
|
<Compile Include="Properties\Resources.Designer.cs">
|
||||||
<AutoGen>True</AutoGen>
|
<AutoGen>True</AutoGen>
|
||||||
<DesignTime>True</DesignTime>
|
<DesignTime>True</DesignTime>
|
||||||
<DependentUpon>Resources.resx</DependentUpon>
|
<DependentUpon>Resources.resx</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="Scripting\PythonScript.cs" />
|
<Compile Include="Scripting\IronPython.cs" />
|
||||||
<Compile Include="mpv\libmpv.cs" />
|
<Compile Include="mpv\libmpv.cs" />
|
||||||
<Compile Include="WinForms\MainForm.cs">
|
<Compile Include="WinForms\MainForm.cs">
|
||||||
<SubType>Form</SubType>
|
<SubType>Form</SubType>
|
||||||
@@ -215,15 +228,12 @@
|
|||||||
</EmbeddedResource>
|
</EmbeddedResource>
|
||||||
<None Include="..\Changelog.md">
|
<None Include="..\Changelog.md">
|
||||||
<Link>Changelog.md</Link>
|
<Link>Changelog.md</Link>
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
|
||||||
</None>
|
</None>
|
||||||
<None Include="..\Manual.md">
|
<None Include="..\Manual.md">
|
||||||
<Link>Manual.md</Link>
|
<Link>Manual.md</Link>
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
|
||||||
</None>
|
</None>
|
||||||
<None Include="..\README.md">
|
<None Include="..\README.md">
|
||||||
<Link>README.md</Link>
|
<Link>README.md</Link>
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
|
||||||
</None>
|
</None>
|
||||||
<None Include="app.manifest" />
|
<None Include="app.manifest" />
|
||||||
<None Include="packages.config" />
|
<None Include="packages.config" />
|
||||||
@@ -236,13 +246,9 @@
|
|||||||
<DependentUpon>Settings.settings</DependentUpon>
|
<DependentUpon>Settings.settings</DependentUpon>
|
||||||
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Content Include="..\LICENSE.txt">
|
|
||||||
<Link>LICENSE.txt</Link>
|
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
|
||||||
</Content>
|
|
||||||
<Content Include="mpvnet.ico" />
|
<Content Include="mpvnet.ico" />
|
||||||
<Content Include="Resources\mpvConf.txt" />
|
<Content Include="Resources\mpv.conf.txt" />
|
||||||
<Content Include="Resources\confToml.txt" />
|
<Content Include="Resources\editor.toml.txt" />
|
||||||
<None Include="Resources\mpvnet.ico" />
|
<None Include="Resources\mpvnet.ico" />
|
||||||
<None Include="Resources\mpvnet.png" />
|
<None Include="Resources\mpvnet.png" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
@@ -250,7 +256,7 @@
|
|||||||
<None Include="App.config" />
|
<None Include="App.config" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Content Include="Resources\inputConf.txt" />
|
<Content Include="Resources\input.conf.txt" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Page Include="DynamicGUI\OptionSettingControl.xaml">
|
<Page Include="DynamicGUI\OptionSettingControl.xaml">
|
||||||
|
|||||||
@@ -1,187 +1,234 @@
|
|||||||
using System;
|
|
||||||
|
using System;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
namespace mpvnet
|
public class libmpv
|
||||||
{
|
{
|
||||||
public class libmpv
|
[DllImport("mpv-1.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
public static extern IntPtr mpv_create();
|
||||||
|
|
||||||
|
[DllImport("mpv-1.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
public static extern mpv_error mpv_initialize(IntPtr mpvHandle);
|
||||||
|
|
||||||
|
[DllImport("mpv-1.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
public static extern mpv_error mpv_command(IntPtr mpvHandle, IntPtr strings);
|
||||||
|
|
||||||
|
[DllImport("mpv-1.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
public static extern mpv_error mpv_command_string(IntPtr mpvHandle, [MarshalAs(UnmanagedType.LPUTF8Str)] string command);
|
||||||
|
|
||||||
|
[DllImport("mpv-1.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
public static extern IntPtr mpv_error_string(mpv_error error);
|
||||||
|
|
||||||
|
[DllImport("mpv-1.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
public static extern int mpv_terminate_destroy(IntPtr mpvHandle);
|
||||||
|
|
||||||
|
[DllImport("mpv-1.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
public static extern mpv_error mpv_request_log_messages(IntPtr mpvHandle, [MarshalAs(UnmanagedType.LPUTF8Str)] string min_level);
|
||||||
|
|
||||||
|
[DllImport("mpv-1.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
public static extern int mpv_set_option(IntPtr mpvHandle, byte[] name, mpv_format format, ref long data);
|
||||||
|
|
||||||
|
[DllImport("mpv-1.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
public static extern int mpv_set_option_string(IntPtr mpvHandle, byte[] name, byte[] value);
|
||||||
|
|
||||||
|
[DllImport("mpv-1.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
public static extern mpv_error mpv_get_property(IntPtr mpvHandle, byte[] name, mpv_format format, out IntPtr data);
|
||||||
|
|
||||||
|
[DllImport("mpv-1.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
public static extern mpv_error mpv_get_property(IntPtr mpvHandle, byte[] name, mpv_format format, out double data);
|
||||||
|
|
||||||
|
[DllImport("mpv-1.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
public static extern mpv_error mpv_set_property(IntPtr mpvHandle, byte[] name, mpv_format format, ref byte[] data);
|
||||||
|
|
||||||
|
[DllImport("mpv-1.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
public static extern mpv_error mpv_set_property(IntPtr mpvHandle, byte[] name, mpv_format format, ref Int64 data);
|
||||||
|
|
||||||
|
[DllImport("mpv-1.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
public static extern mpv_error mpv_observe_property(IntPtr mpvHandle, UInt64 reply_userdata, [MarshalAs(UnmanagedType.LPUTF8Str)] string name, mpv_format format);
|
||||||
|
|
||||||
|
[DllImport("mpv-1.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
public static extern int mpv_unobserve_property(IntPtr mpvHandle, UInt64 registered_reply_userdata);
|
||||||
|
|
||||||
|
[DllImport("mpv-1.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
public static extern void mpv_free(IntPtr data);
|
||||||
|
|
||||||
|
[DllImport("mpv-1.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
public static extern IntPtr mpv_wait_event(IntPtr mpvHandle, double timeout);
|
||||||
|
|
||||||
|
public enum mpv_error
|
||||||
{
|
{
|
||||||
[DllImport("mpv-1.dll", CallingConvention = CallingConvention.Cdecl)]
|
MPV_ERROR_SUCCESS = 0,
|
||||||
public static extern IntPtr mpv_create();
|
MPV_ERROR_EVENT_QUEUE_FULL = -1,
|
||||||
|
MPV_ERROR_NOMEM = -2,
|
||||||
[DllImport("mpv-1.dll", CallingConvention = CallingConvention.Cdecl)]
|
MPV_ERROR_UNINITIALIZED = -3,
|
||||||
public static extern int mpv_initialize(IntPtr mpvHandle);
|
MPV_ERROR_INVALID_PARAMETER = -4,
|
||||||
|
MPV_ERROR_OPTION_NOT_FOUND = -5,
|
||||||
[DllImport("mpv-1.dll", CallingConvention = CallingConvention.Cdecl)]
|
MPV_ERROR_OPTION_FORMAT = -6,
|
||||||
public static extern int mpv_command(IntPtr mpvHandle, IntPtr strings);
|
MPV_ERROR_OPTION_ERROR = -7,
|
||||||
|
MPV_ERROR_PROPERTY_NOT_FOUND = -8,
|
||||||
[DllImport("mpv-1.dll", CallingConvention = CallingConvention.Cdecl)]
|
MPV_ERROR_PROPERTY_FORMAT = -9,
|
||||||
public static extern int mpv_command_string(IntPtr mpvHandle, [MarshalAs(UnmanagedType.LPUTF8Str)] string command);
|
MPV_ERROR_PROPERTY_UNAVAILABLE = -10,
|
||||||
|
MPV_ERROR_PROPERTY_ERROR = -11,
|
||||||
[DllImport("mpv-1.dll", CallingConvention = CallingConvention.Cdecl)]
|
MPV_ERROR_COMMAND = -12,
|
||||||
public static extern int mpv_terminate_destroy(IntPtr mpvHandle);
|
MPV_ERROR_LOADING_FAILED = -13,
|
||||||
|
MPV_ERROR_AO_INIT_FAILED = -14,
|
||||||
[DllImport("mpv-1.dll", CallingConvention = CallingConvention.Cdecl)]
|
MPV_ERROR_VO_INIT_FAILED = -15,
|
||||||
public static extern int mpv_set_option(IntPtr mpvHandle, byte[] name, mpv_format format, ref long data);
|
MPV_ERROR_NOTHING_TO_PLAY = -16,
|
||||||
|
MPV_ERROR_UNKNOWN_FORMAT = -17,
|
||||||
[DllImport("mpv-1.dll", CallingConvention = CallingConvention.Cdecl)]
|
MPV_ERROR_UNSUPPORTED = -18,
|
||||||
public static extern int mpv_set_option_string(IntPtr mpvHandle, byte[] name, byte[] value);
|
MPV_ERROR_NOT_IMPLEMENTED = -19,
|
||||||
|
MPV_ERROR_GENERIC = -20
|
||||||
[DllImport("mpv-1.dll", CallingConvention = CallingConvention.Cdecl)]
|
|
||||||
public static extern int mpv_get_property(IntPtr mpvHandle, byte[] name, mpv_format format, out IntPtr data);
|
|
||||||
|
|
||||||
[DllImport("mpv-1.dll", CallingConvention = CallingConvention.Cdecl)]
|
|
||||||
public static extern int mpv_get_property(IntPtr mpvHandle, byte[] name, mpv_format format, ref double data);
|
|
||||||
|
|
||||||
[DllImport("mpv-1.dll", CallingConvention = CallingConvention.Cdecl)]
|
|
||||||
public static extern int mpv_set_property(IntPtr mpvHandle, byte[] name, mpv_format format, ref byte[] data);
|
|
||||||
|
|
||||||
[DllImport("mpv-1.dll", CallingConvention = CallingConvention.Cdecl)]
|
|
||||||
public static extern int mpv_set_property(IntPtr mpvHandle, byte[] name, mpv_format format, ref Int64 data);
|
|
||||||
|
|
||||||
[DllImport("mpv-1.dll", CallingConvention = CallingConvention.Cdecl)]
|
|
||||||
public static extern int mpv_observe_property(
|
|
||||||
IntPtr mpvHandle,
|
|
||||||
UInt64 reply_userdata,
|
|
||||||
[MarshalAs(UnmanagedType.LPUTF8Str)] string name,
|
|
||||||
mpv_format format);
|
|
||||||
|
|
||||||
[DllImport("mpv-1.dll", CallingConvention = CallingConvention.Cdecl)]
|
|
||||||
public static extern int mpv_unobserve_property(IntPtr mpvHandle, UInt64 registered_reply_userdata);
|
|
||||||
|
|
||||||
[DllImport("mpv-1.dll", CallingConvention = CallingConvention.Cdecl)]
|
|
||||||
public static extern void mpv_free(IntPtr data);
|
|
||||||
|
|
||||||
[DllImport("mpv-1.dll", CallingConvention = CallingConvention.Cdecl)]
|
|
||||||
public static extern IntPtr mpv_wait_event(IntPtr mpvHandle, double timeout);
|
|
||||||
|
|
||||||
public enum mpv_error
|
|
||||||
{
|
|
||||||
MPV_ERROR_SUCCESS = 0,
|
|
||||||
MPV_ERROR_EVENT_QUEUE_FULL = -1,
|
|
||||||
MPV_ERROR_NOMEM = -2,
|
|
||||||
MPV_ERROR_UNINITIALIZED = -3,
|
|
||||||
MPV_ERROR_INVALID_PARAMETER = -4,
|
|
||||||
MPV_ERROR_OPTION_NOT_FOUND = -5,
|
|
||||||
MPV_ERROR_OPTION_FORMAT = -6,
|
|
||||||
MPV_ERROR_OPTION_ERROR = -7,
|
|
||||||
MPV_ERROR_PROPERTY_NOT_FOUND = -8,
|
|
||||||
MPV_ERROR_PROPERTY_FORMAT = -9,
|
|
||||||
MPV_ERROR_PROPERTY_UNAVAILABLE = -10,
|
|
||||||
MPV_ERROR_PROPERTY_ERROR = -11,
|
|
||||||
MPV_ERROR_COMMAND = -12,
|
|
||||||
MPV_ERROR_LOADING_FAILED = -13,
|
|
||||||
MPV_ERROR_AO_INIT_FAILED = -14,
|
|
||||||
MPV_ERROR_VO_INIT_FAILED = -15,
|
|
||||||
MPV_ERROR_NOTHING_TO_PLAY = -16,
|
|
||||||
MPV_ERROR_UNKNOWN_FORMAT = -17,
|
|
||||||
MPV_ERROR_UNSUPPORTED = -18,
|
|
||||||
MPV_ERROR_NOT_IMPLEMENTED = -19,
|
|
||||||
MPV_ERROR_GENERIC = -20
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum mpv_event_id
|
|
||||||
{
|
|
||||||
MPV_EVENT_NONE = 0,
|
|
||||||
MPV_EVENT_SHUTDOWN = 1,
|
|
||||||
MPV_EVENT_LOG_MESSAGE = 2,
|
|
||||||
MPV_EVENT_GET_PROPERTY_REPLY = 3,
|
|
||||||
MPV_EVENT_SET_PROPERTY_REPLY = 4,
|
|
||||||
MPV_EVENT_COMMAND_REPLY = 5,
|
|
||||||
MPV_EVENT_START_FILE = 6,
|
|
||||||
MPV_EVENT_END_FILE = 7,
|
|
||||||
MPV_EVENT_FILE_LOADED = 8,
|
|
||||||
MPV_EVENT_TRACKS_CHANGED = 9,
|
|
||||||
MPV_EVENT_TRACK_SWITCHED = 10,
|
|
||||||
MPV_EVENT_IDLE = 11,
|
|
||||||
MPV_EVENT_PAUSE = 12,
|
|
||||||
MPV_EVENT_UNPAUSE = 13,
|
|
||||||
MPV_EVENT_TICK = 14,
|
|
||||||
MPV_EVENT_SCRIPT_INPUT_DISPATCH = 15,
|
|
||||||
MPV_EVENT_CLIENT_MESSAGE = 16,
|
|
||||||
MPV_EVENT_VIDEO_RECONFIG = 17,
|
|
||||||
MPV_EVENT_AUDIO_RECONFIG = 18,
|
|
||||||
MPV_EVENT_METADATA_UPDATE = 19,
|
|
||||||
MPV_EVENT_SEEK = 20,
|
|
||||||
MPV_EVENT_PLAYBACK_RESTART = 21,
|
|
||||||
MPV_EVENT_PROPERTY_CHANGE = 22,
|
|
||||||
MPV_EVENT_CHAPTER_CHANGE = 23,
|
|
||||||
MPV_EVENT_QUEUE_OVERFLOW = 24,
|
|
||||||
MPV_EVENT_HOOK = 25
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum mpv_format
|
|
||||||
{
|
|
||||||
MPV_FORMAT_NONE = 0,
|
|
||||||
MPV_FORMAT_STRING = 1,
|
|
||||||
MPV_FORMAT_OSD_STRING = 2,
|
|
||||||
MPV_FORMAT_FLAG = 3,
|
|
||||||
MPV_FORMAT_INT64 = 4,
|
|
||||||
MPV_FORMAT_DOUBLE = 5,
|
|
||||||
MPV_FORMAT_NODE = 6,
|
|
||||||
MPV_FORMAT_NODE_ARRAY = 7,
|
|
||||||
MPV_FORMAT_NODE_MAP = 8,
|
|
||||||
MPV_FORMAT_BYTE_ARRAY = 9
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum mpv_log_level
|
|
||||||
{
|
|
||||||
MPV_LOG_LEVEL_NONE = 0,
|
|
||||||
MPV_LOG_LEVEL_FATAL = 10,
|
|
||||||
MPV_LOG_LEVEL_ERROR = 20,
|
|
||||||
MPV_LOG_LEVEL_WARN = 30,
|
|
||||||
MPV_LOG_LEVEL_INFO = 40,
|
|
||||||
MPV_LOG_LEVEL_V = 50,
|
|
||||||
MPV_LOG_LEVEL_DEBUG = 60,
|
|
||||||
MPV_LOG_LEVEL_TRACE = 70,
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum mpv_end_file_reason
|
|
||||||
{
|
|
||||||
MPV_END_FILE_REASON_EOF = 0,
|
|
||||||
MPV_END_FILE_REASON_STOP = 2,
|
|
||||||
MPV_END_FILE_REASON_QUIT = 3,
|
|
||||||
MPV_END_FILE_REASON_ERROR = 4,
|
|
||||||
MPV_END_FILE_REASON_REDIRECT = 5
|
|
||||||
}
|
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential)]
|
|
||||||
public struct mpv_event_log_message
|
|
||||||
{
|
|
||||||
public string prefix;
|
|
||||||
public string level;
|
|
||||||
public string text;
|
|
||||||
public mpv_log_level log_level;
|
|
||||||
}
|
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential)]
|
|
||||||
public struct mpv_event
|
|
||||||
{
|
|
||||||
public mpv_event_id event_id;
|
|
||||||
public int error;
|
|
||||||
public UInt64 reply_userdata;
|
|
||||||
public IntPtr data;
|
|
||||||
}
|
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential)]
|
|
||||||
public struct mpv_event_client_message
|
|
||||||
{
|
|
||||||
public int num_args;
|
|
||||||
public IntPtr args;
|
|
||||||
}
|
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential)]
|
|
||||||
public struct mpv_event_property
|
|
||||||
{
|
|
||||||
public string name;
|
|
||||||
public mpv_format format;
|
|
||||||
public IntPtr data;
|
|
||||||
}
|
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential)]
|
|
||||||
public struct mpv_event_end_file
|
|
||||||
{
|
|
||||||
public int reason;
|
|
||||||
public int error;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public enum mpv_event_id
|
||||||
|
{
|
||||||
|
MPV_EVENT_NONE = 0,
|
||||||
|
MPV_EVENT_SHUTDOWN = 1,
|
||||||
|
MPV_EVENT_LOG_MESSAGE = 2,
|
||||||
|
MPV_EVENT_GET_PROPERTY_REPLY = 3,
|
||||||
|
MPV_EVENT_SET_PROPERTY_REPLY = 4,
|
||||||
|
MPV_EVENT_COMMAND_REPLY = 5,
|
||||||
|
MPV_EVENT_START_FILE = 6,
|
||||||
|
MPV_EVENT_END_FILE = 7,
|
||||||
|
MPV_EVENT_FILE_LOADED = 8,
|
||||||
|
MPV_EVENT_TRACKS_CHANGED = 9,
|
||||||
|
MPV_EVENT_TRACK_SWITCHED = 10,
|
||||||
|
MPV_EVENT_IDLE = 11,
|
||||||
|
MPV_EVENT_PAUSE = 12,
|
||||||
|
MPV_EVENT_UNPAUSE = 13,
|
||||||
|
MPV_EVENT_TICK = 14,
|
||||||
|
MPV_EVENT_SCRIPT_INPUT_DISPATCH = 15,
|
||||||
|
MPV_EVENT_CLIENT_MESSAGE = 16,
|
||||||
|
MPV_EVENT_VIDEO_RECONFIG = 17,
|
||||||
|
MPV_EVENT_AUDIO_RECONFIG = 18,
|
||||||
|
MPV_EVENT_METADATA_UPDATE = 19,
|
||||||
|
MPV_EVENT_SEEK = 20,
|
||||||
|
MPV_EVENT_PLAYBACK_RESTART = 21,
|
||||||
|
MPV_EVENT_PROPERTY_CHANGE = 22,
|
||||||
|
MPV_EVENT_CHAPTER_CHANGE = 23,
|
||||||
|
MPV_EVENT_QUEUE_OVERFLOW = 24,
|
||||||
|
MPV_EVENT_HOOK = 25
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum mpv_format
|
||||||
|
{
|
||||||
|
MPV_FORMAT_NONE = 0,
|
||||||
|
MPV_FORMAT_STRING = 1,
|
||||||
|
MPV_FORMAT_OSD_STRING = 2,
|
||||||
|
MPV_FORMAT_FLAG = 3,
|
||||||
|
MPV_FORMAT_INT64 = 4,
|
||||||
|
MPV_FORMAT_DOUBLE = 5,
|
||||||
|
MPV_FORMAT_NODE = 6,
|
||||||
|
MPV_FORMAT_NODE_ARRAY = 7,
|
||||||
|
MPV_FORMAT_NODE_MAP = 8,
|
||||||
|
MPV_FORMAT_BYTE_ARRAY = 9
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum mpv_log_level
|
||||||
|
{
|
||||||
|
MPV_LOG_LEVEL_NONE = 0,
|
||||||
|
MPV_LOG_LEVEL_FATAL = 10,
|
||||||
|
MPV_LOG_LEVEL_ERROR = 20,
|
||||||
|
MPV_LOG_LEVEL_WARN = 30,
|
||||||
|
MPV_LOG_LEVEL_INFO = 40,
|
||||||
|
MPV_LOG_LEVEL_V = 50,
|
||||||
|
MPV_LOG_LEVEL_DEBUG = 60,
|
||||||
|
MPV_LOG_LEVEL_TRACE = 70,
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum mpv_end_file_reason
|
||||||
|
{
|
||||||
|
MPV_END_FILE_REASON_EOF = 0,
|
||||||
|
MPV_END_FILE_REASON_STOP = 2,
|
||||||
|
MPV_END_FILE_REASON_QUIT = 3,
|
||||||
|
MPV_END_FILE_REASON_ERROR = 4,
|
||||||
|
MPV_END_FILE_REASON_REDIRECT = 5
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
public struct mpv_event_log_message
|
||||||
|
{
|
||||||
|
public string prefix;
|
||||||
|
public string level;
|
||||||
|
public string text;
|
||||||
|
public mpv_log_level log_level;
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
public struct mpv_event
|
||||||
|
{
|
||||||
|
public mpv_event_id event_id;
|
||||||
|
public int error;
|
||||||
|
public UInt64 reply_userdata;
|
||||||
|
public IntPtr data;
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
public struct mpv_event_client_message
|
||||||
|
{
|
||||||
|
public int num_args;
|
||||||
|
public IntPtr args;
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
public struct mpv_event_property
|
||||||
|
{
|
||||||
|
public string name;
|
||||||
|
public mpv_format format;
|
||||||
|
public IntPtr data;
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
public struct mpv_event_end_file
|
||||||
|
{
|
||||||
|
public int reason;
|
||||||
|
public int error;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IntPtr AllocateUtf8ArrayWithSentinel(string[] arr, out IntPtr[] byteArrayPointers)
|
||||||
|
{
|
||||||
|
int numberOfStrings = arr.Length + 1; // add extra element for extra null pointer last (sentinel)
|
||||||
|
byteArrayPointers = new IntPtr[numberOfStrings];
|
||||||
|
IntPtr rootPointer = Marshal.AllocCoTaskMem(IntPtr.Size * numberOfStrings);
|
||||||
|
|
||||||
|
for (int index = 0; index < arr.Length; index++)
|
||||||
|
{
|
||||||
|
var bytes = GetUtf8Bytes(arr[index]);
|
||||||
|
IntPtr unmanagedPointer = Marshal.AllocHGlobal(bytes.Length);
|
||||||
|
Marshal.Copy(bytes, 0, unmanagedPointer, bytes.Length);
|
||||||
|
byteArrayPointers[index] = unmanagedPointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
Marshal.Copy(byteArrayPointers, 0, rootPointer, numberOfStrings);
|
||||||
|
return rootPointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string[] ConvertFromUtf8Strings(IntPtr utf8StringArray, int stringCount)
|
||||||
|
{
|
||||||
|
IntPtr[] intPtrArray = new IntPtr[stringCount];
|
||||||
|
string[] stringArray = new string[stringCount];
|
||||||
|
Marshal.Copy(utf8StringArray, intPtrArray, 0, stringCount);
|
||||||
|
|
||||||
|
for (int i = 0; i < stringCount; i++)
|
||||||
|
stringArray[i] = ConvertFromUtf8(intPtrArray[i]);
|
||||||
|
|
||||||
|
return stringArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string ConvertFromUtf8(IntPtr nativeUtf8)
|
||||||
|
{
|
||||||
|
int len = 0;
|
||||||
|
|
||||||
|
while (Marshal.ReadByte(nativeUtf8, len) != 0)
|
||||||
|
++len;
|
||||||
|
|
||||||
|
byte[] buffer = new byte[len];
|
||||||
|
Marshal.Copy(nativeUtf8, buffer, 0, buffer.Length);
|
||||||
|
return Encoding.UTF8.GetString(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string GetError(mpv_error err) => ConvertFromUtf8(mpv_error_string(err));
|
||||||
|
|
||||||
|
public static byte[] GetUtf8Bytes(string s) => Encoding.UTF8.GetBytes(s + "\0");
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
@@ -8,15 +9,17 @@ using System.IO;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Text;
|
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
|
|
||||||
|
using ScriptHost;
|
||||||
|
|
||||||
using WinForms = System.Windows.Forms;
|
using WinForms = System.Windows.Forms;
|
||||||
|
|
||||||
using static mpvnet.libmpv;
|
using static libmpv;
|
||||||
using static Native;
|
using static WinAPI;
|
||||||
|
using static NewLine;
|
||||||
|
|
||||||
namespace mpvnet
|
namespace mpvnet
|
||||||
{
|
{
|
||||||
@@ -28,8 +31,8 @@ namespace mpvnet
|
|||||||
// Lua/JS event libmpv event
|
// Lua/JS event libmpv event
|
||||||
|
|
||||||
// MPV_EVENT_NONE
|
// MPV_EVENT_NONE
|
||||||
|
public static event Action <mpv_log_level, string>LogMessage; // log-message MPV_EVENT_LOG_MESSAGE
|
||||||
public static event Action Shutdown; // shutdown MPV_EVENT_SHUTDOWN
|
public static event Action Shutdown; // shutdown MPV_EVENT_SHUTDOWN
|
||||||
public static event Action LogMessage; // log-message MPV_EVENT_LOG_MESSAGE
|
|
||||||
public static event Action GetPropertyReply; // get-property-reply MPV_EVENT_GET_PROPERTY_REPLY
|
public static event Action GetPropertyReply; // get-property-reply MPV_EVENT_GET_PROPERTY_REPLY
|
||||||
public static event Action SetPropertyReply; // set-property-reply MPV_EVENT_SET_PROPERTY_REPLY
|
public static event Action SetPropertyReply; // set-property-reply MPV_EVENT_SET_PROPERTY_REPLY
|
||||||
public static event Action CommandReply; // command-reply MPV_EVENT_COMMAND_REPLY
|
public static event Action CommandReply; // command-reply MPV_EVENT_COMMAND_REPLY
|
||||||
@@ -41,7 +44,6 @@ namespace mpvnet
|
|||||||
public static event Action Idle; // idle MPV_EVENT_IDLE
|
public static event Action Idle; // idle MPV_EVENT_IDLE
|
||||||
public static event Action Pause; // MPV_EVENT_PAUSE
|
public static event Action Pause; // MPV_EVENT_PAUSE
|
||||||
public static event Action Unpause; // MPV_EVENT_UNPAUSE
|
public static event Action Unpause; // MPV_EVENT_UNPAUSE
|
||||||
public static event Action Tick; // tick MPV_EVENT_TICK
|
|
||||||
public static event Action ScriptInputDispatch; // MPV_EVENT_SCRIPT_INPUT_DISPATCH
|
public static event Action ScriptInputDispatch; // MPV_EVENT_SCRIPT_INPUT_DISPATCH
|
||||||
public static event Action<string[]> ClientMessage; // client-message MPV_EVENT_CLIENT_MESSAGE
|
public static event Action<string[]> ClientMessage; // client-message MPV_EVENT_CLIENT_MESSAGE
|
||||||
public static event Action VideoReconfig; // video-reconfig MPV_EVENT_VIDEO_RECONFIG
|
public static event Action VideoReconfig; // video-reconfig MPV_EVENT_VIDEO_RECONFIG
|
||||||
@@ -56,10 +58,12 @@ namespace mpvnet
|
|||||||
|
|
||||||
public static event Action Initialized;
|
public static event Action Initialized;
|
||||||
|
|
||||||
public static List<KeyValuePair<string, Action<bool>>> BoolPropChangeActions { get; set; } = new List<KeyValuePair<string, Action<bool>>>();
|
public static List<KeyValuePair<string, Action>> PropChangeActions { get; set; } = new List<KeyValuePair<string, Action>>();
|
||||||
public static List<KeyValuePair<string, Action<int>>> IntPropChangeActions { get; set; } = new List<KeyValuePair<string, Action<int>>>();
|
public static List<KeyValuePair<string, Action<bool>>> BoolPropChangeActions { get; set; } = new List<KeyValuePair<string, Action<bool>>>();
|
||||||
|
public static List<KeyValuePair<string, Action<int>>> IntPropChangeActions { get; set; } = new List<KeyValuePair<string, Action<int>>>();
|
||||||
public static List<KeyValuePair<string, Action<double>>> DoublePropChangeActions { get; set; } = new List<KeyValuePair<string, Action<double>>>();
|
public static List<KeyValuePair<string, Action<double>>> DoublePropChangeActions { get; set; } = new List<KeyValuePair<string, Action<double>>>();
|
||||||
public static List<KeyValuePair<string, Action<string>>> StringPropChangeActions { get; set; } = new List<KeyValuePair<string, Action<string>>>();
|
public static List<KeyValuePair<string, Action<string>>> StringPropChangeActions { get; set; } = new List<KeyValuePair<string, Action<string>>>();
|
||||||
|
|
||||||
public static List<MediaTrack> MediaTracks { get; set; } = new List<MediaTrack>();
|
public static List<MediaTrack> MediaTracks { get; set; } = new List<MediaTrack>();
|
||||||
public static List<KeyValuePair<string, double>> Chapters { get; set; } = new List<KeyValuePair<string, double>>();
|
public static List<KeyValuePair<string, double>> Chapters { get; set; } = new List<KeyValuePair<string, double>>();
|
||||||
public static IntPtr Handle { get; set; }
|
public static IntPtr Handle { get; set; }
|
||||||
@@ -67,8 +71,8 @@ namespace mpvnet
|
|||||||
public static List<PythonScript> PythonScripts { get; set; } = new List<PythonScript>();
|
public static List<PythonScript> PythonScripts { get; set; } = new List<PythonScript>();
|
||||||
public static Size VideoSize { get; set; }
|
public static Size VideoSize { get; set; }
|
||||||
public static TimeSpan Duration;
|
public static TimeSpan Duration;
|
||||||
public static AutoResetEvent ShutdownAutoResetEvent { get; set; } = new AutoResetEvent(false);
|
public static AutoResetEvent ShutdownAutoResetEvent { get; } = new AutoResetEvent(false);
|
||||||
public static AutoResetEvent VideoSizeAutoResetEvent { get; set; } = new AutoResetEvent(false);
|
public static AutoResetEvent VideoSizeAutoResetEvent { get; } = new AutoResetEvent(false);
|
||||||
|
|
||||||
public static string InputConfPath { get => ConfigFolder + "input.conf"; }
|
public static string InputConfPath { get => ConfigFolder + "input.conf"; }
|
||||||
public static string ConfPath { get => ConfigFolder + "mpv.conf"; }
|
public static string ConfPath { get => ConfigFolder + "mpv.conf"; }
|
||||||
@@ -77,23 +81,30 @@ namespace mpvnet
|
|||||||
public static string Vid { get; set; } = "";
|
public static string Vid { get; set; } = "";
|
||||||
public static string GPUAPI { get; set; } = "auto";
|
public static string GPUAPI { get; set; } = "auto";
|
||||||
|
|
||||||
|
public static bool WasInitialSizeSet;
|
||||||
|
public static bool Border { get; set; } = true;
|
||||||
|
public static bool Fullscreen { get; set; }
|
||||||
public static bool IsLogoVisible { set; get; }
|
public static bool IsLogoVisible { set; get; }
|
||||||
public static bool IsQuitNeeded { set; get; } = true;
|
public static bool IsQuitNeeded { set; get; } = true;
|
||||||
public static bool Fullscreen { get; set; }
|
|
||||||
public static bool Border { get; set; } = true;
|
|
||||||
public static bool TaskbarProgress { get; set; } = true;
|
public static bool TaskbarProgress { get; set; } = true;
|
||||||
|
public static bool WindowMaximized { get; set; }
|
||||||
|
public static bool WindowMinimized { get; set; }
|
||||||
|
|
||||||
public static int Screen { get; set; } = -1;
|
public static int Screen { get; set; } = -1;
|
||||||
public static int Edition { get; set; }
|
public static int Edition { get; set; }
|
||||||
|
|
||||||
public static float Autofit { get; set; } = 0.5f;
|
public static float Autofit { get; set; } = 0.6f;
|
||||||
public static float AutofitSmaller { get; set; } = 0.4f;
|
public static float AutofitSmaller { get; set; } = 0.3f;
|
||||||
public static float AutofitLarger { get; set; } = 0.75f;
|
public static float AutofitLarger { get; set; } = 0.8f;
|
||||||
|
|
||||||
public static void Init()
|
public static void Init()
|
||||||
{
|
{
|
||||||
LoadLibrary("mpv-1.dll");
|
|
||||||
Handle = mpv_create();
|
Handle = mpv_create();
|
||||||
|
|
||||||
|
if (Handle == IntPtr.Zero)
|
||||||
|
throw new Exception("error mpv_create");
|
||||||
|
|
||||||
|
mpv_request_log_messages(Handle, "info");
|
||||||
Task.Run(() => EventLoop());
|
Task.Run(() => EventLoop());
|
||||||
|
|
||||||
if (App.IsStartedFromTerminal)
|
if (App.IsStartedFromTerminal)
|
||||||
@@ -111,7 +122,11 @@ namespace mpvnet
|
|||||||
set_property_string("config", "yes");
|
set_property_string("config", "yes");
|
||||||
|
|
||||||
ProcessCommandLine(true);
|
ProcessCommandLine(true);
|
||||||
mpv_initialize(Handle);
|
mpv_error err = mpv_initialize(Handle);
|
||||||
|
|
||||||
|
if (err < 0)
|
||||||
|
throw new Exception("mpv_initialize error\n\n" + GetError(err));
|
||||||
|
|
||||||
Initialized?.Invoke();
|
Initialized?.Invoke();
|
||||||
LoadMpvScripts();
|
LoadMpvScripts();
|
||||||
}
|
}
|
||||||
@@ -139,10 +154,15 @@ namespace mpvnet
|
|||||||
case "fs":
|
case "fs":
|
||||||
case "fullscreen": Fullscreen = value == "yes"; break;
|
case "fullscreen": Fullscreen = value == "yes"; break;
|
||||||
case "border": Border = value == "yes"; break;
|
case "border": Border = value == "yes"; break;
|
||||||
|
case "window-maximized": WindowMaximized = value == "yes"; break;
|
||||||
|
case "window-minimized": WindowMinimized = value == "yes"; break;
|
||||||
case "taskbar-progress": TaskbarProgress = value == "yes"; break;
|
case "taskbar-progress": TaskbarProgress = value == "yes"; break;
|
||||||
case "screen": Screen = Convert.ToInt32(value); break;
|
case "screen": Screen = Convert.ToInt32(value); break;
|
||||||
case "gpu-api": GPUAPI = value; break;
|
case "gpu-api": GPUAPI = value; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (AutofitLarger > 1)
|
||||||
|
AutofitLarger = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static string _ConfigFolder;
|
static string _ConfigFolder;
|
||||||
@@ -151,24 +171,23 @@ namespace mpvnet
|
|||||||
get {
|
get {
|
||||||
if (_ConfigFolder == null)
|
if (_ConfigFolder == null)
|
||||||
{
|
{
|
||||||
string portableFolder = Folder.Startup + "portable_config\\";
|
string portableFolder = Folder.Startup + @"portable_config\";
|
||||||
_ConfigFolder = portableFolder;
|
_ConfigFolder = portableFolder;
|
||||||
|
|
||||||
if (!Directory.Exists(_ConfigFolder))
|
if (!Directory.Exists(_ConfigFolder))
|
||||||
_ConfigFolder = RegHelp.GetString(App.RegPath, "ConfigFolder");
|
_ConfigFolder = RegistryHelp.GetString(App.RegPath, "ConfigFolder");
|
||||||
|
|
||||||
if (!Directory.Exists(_ConfigFolder))
|
if (!Directory.Exists(_ConfigFolder))
|
||||||
{
|
{
|
||||||
string appdataFolder = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\mpv.net\\";
|
string appdataFolder = Environment.GetFolderPath(
|
||||||
string appdataFolderMpv = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\mpv\\";
|
Environment.SpecialFolder.ApplicationData) + @"\mpv.net\";
|
||||||
|
|
||||||
using (TaskDialog<string> td = new TaskDialog<string>())
|
using (TaskDialog<string> td = new TaskDialog<string>())
|
||||||
{
|
{
|
||||||
td.MainInstruction = "Choose a settings folder.";
|
td.MainInstruction = "Choose a settings folder.";
|
||||||
td.AddCommandLink(@"AppData\Roaming\mpv.net", appdataFolder, appdataFolder);
|
td.AddCommand(@"AppData\Roaming\mpv.net", appdataFolder, appdataFolder);
|
||||||
td.AddCommandLink(@"AppData\Roaming\mpv", appdataFolderMpv, appdataFolderMpv);
|
td.AddCommand(@"<startup>\portable_config", portableFolder, portableFolder);
|
||||||
td.AddCommandLink("<startup>\\portable_config", portableFolder, portableFolder);
|
td.AddCommand("Choose custom folder", "custom");
|
||||||
td.AddCommandLink("Choose custom folder", "custom");
|
|
||||||
_ConfigFolder = td.Show();
|
_ConfigFolder = td.Show();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -185,7 +204,7 @@ namespace mpvnet
|
|||||||
d.Description = "Choose a folder.";
|
d.Description = "Choose a folder.";
|
||||||
|
|
||||||
if (d.ShowDialog() == WinForms.DialogResult.OK)
|
if (d.ShowDialog() == WinForms.DialogResult.OK)
|
||||||
_ConfigFolder = d.SelectedPath + "\\";
|
_ConfigFolder = d.SelectedPath + @"\";
|
||||||
else
|
else
|
||||||
_ConfigFolder = appdataFolder;
|
_ConfigFolder = appdataFolder;
|
||||||
}
|
}
|
||||||
@@ -202,13 +221,23 @@ namespace mpvnet
|
|||||||
Directory.CreateDirectory(_ConfigFolder);
|
Directory.CreateDirectory(_ConfigFolder);
|
||||||
|
|
||||||
if (!_ConfigFolder.Contains("portable_config"))
|
if (!_ConfigFolder.Contains("portable_config"))
|
||||||
RegHelp.SetObject(App.RegPath, "ConfigFolder", _ConfigFolder);
|
RegistryHelp.SetValue(App.RegPath, "ConfigFolder", _ConfigFolder);
|
||||||
|
|
||||||
if (!File.Exists(_ConfigFolder + "input.conf"))
|
if (!File.Exists(_ConfigFolder + "input.conf"))
|
||||||
File.WriteAllText(_ConfigFolder + "input.conf", Properties.Resources.inputConf);
|
File.WriteAllText(_ConfigFolder + "input.conf", Properties.Resources.input_conf);
|
||||||
|
|
||||||
if (!File.Exists(_ConfigFolder + "mpv.conf"))
|
if (!File.Exists(_ConfigFolder + "mpv.conf"))
|
||||||
File.WriteAllText(_ConfigFolder + "mpv.conf", Properties.Resources.mpvConf);
|
{
|
||||||
|
string conf = Properties.Resources.mpv_conf;
|
||||||
|
Graphics gx = Graphics.FromHwnd(IntPtr.Zero);
|
||||||
|
float scale = GetDeviceCaps(gx.GetHdc(), 88 /*LOGPIXELSX*/) / 96.0f;
|
||||||
|
|
||||||
|
if (scale != 1)
|
||||||
|
conf = conf.Replace("console-scale=1", "console-scale=" + scale);
|
||||||
|
|
||||||
|
gx.Dispose();
|
||||||
|
File.WriteAllText(_ConfigFolder + "mpv.conf", conf);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return _ConfigFolder;
|
return _ConfigFolder;
|
||||||
@@ -231,6 +260,7 @@ namespace mpvnet
|
|||||||
foreach (var i in _Conf)
|
foreach (var i in _Conf)
|
||||||
ProcessProperty(i.Key, i.Value);
|
ProcessProperty(i.Key, i.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
return _Conf;
|
return _Conf;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -238,41 +268,55 @@ namespace mpvnet
|
|||||||
public static void LoadMpvScripts()
|
public static void LoadMpvScripts()
|
||||||
{
|
{
|
||||||
if (Directory.Exists(Folder.Startup + "Scripts"))
|
if (Directory.Exists(Folder.Startup + "Scripts"))
|
||||||
{
|
foreach (string path in Directory.GetFiles(Folder.Startup + "Scripts"))
|
||||||
string[] startupScripts = Directory.GetFiles(Folder.Startup + "Scripts");
|
|
||||||
|
|
||||||
foreach (string path in startupScripts)
|
|
||||||
if ((path.EndsWith(".lua") || path.EndsWith(".js")) && KnownScripts.Contains(Path.GetFileName(path)))
|
if ((path.EndsWith(".lua") || path.EndsWith(".js")) && KnownScripts.Contains(Path.GetFileName(path)))
|
||||||
commandv("load-script", $"{path}");
|
commandv("load-script", $"{path}");
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string[] KnownScripts { get; } = { "osc-visibility.js", "show-playlist.js", "seek-show-position.py", "repl.lua" };
|
public static string[] KnownScripts { get; } = { "show-playlist.js"};
|
||||||
|
|
||||||
public static void LoadScripts()
|
public static void LoadScripts()
|
||||||
{
|
{
|
||||||
if (Directory.Exists(Folder.Startup + "Scripts"))
|
if (Directory.Exists(Folder.Startup + "Scripts"))
|
||||||
{
|
{
|
||||||
foreach (string scriptPath in Directory.GetFiles(Folder.Startup + "Scripts"))
|
foreach (string file in Directory.GetFiles(Folder.Startup + "Scripts"))
|
||||||
{
|
{
|
||||||
if (KnownScripts.Contains(Path.GetFileName(scriptPath)))
|
if (KnownScripts.Contains(Path.GetFileName(file)))
|
||||||
{
|
{
|
||||||
if (scriptPath.EndsWith(".py"))
|
if (file.EndsWith(".py"))
|
||||||
Task.Run(() => PythonScripts.Add(new PythonScript(scriptPath)));
|
App.RunAction(() => PythonScripts.Add(new PythonScript(file)));
|
||||||
else if (scriptPath.EndsWith(".ps1"))
|
else if (file.EndsWith(".ps1"))
|
||||||
Task.Run(() => PowerShellScript.Init(scriptPath));
|
App.RunAction(() => InvokePowerShellScript(file));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
Msg.ShowError("Failed to load script", scriptPath + "\n\nOnly scripts that ship with mpv.net are allowed in <startup>\\scripts\n\nUser scripts have to use <config folder>\\scripts\n\nNever copy or install a new mpv.net version over a old mpv.net version.");
|
ConsoleHelp.WriteError("Failed to load script:" + BR + file + BR +
|
||||||
|
"Only scripts that ship with mpv.net are allowed in <startup>\\scripts." + BR +
|
||||||
|
"Never copy or install a new mpv.net version on top of a old mpv.net version.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Directory.Exists(ConfigFolder + "scripts"))
|
if (Directory.Exists(ConfigFolder + "scripts-py"))
|
||||||
foreach (string scriptPath in Directory.GetFiles(ConfigFolder + "scripts"))
|
foreach (string scriptPath in Directory.GetFiles(ConfigFolder + "scripts-py", "*.py"))
|
||||||
if (scriptPath.EndsWith(".py"))
|
App.RunAction(() => PythonScripts.Add(new PythonScript(scriptPath)));
|
||||||
Task.Run(() => PythonScripts.Add(new PythonScript(scriptPath)));
|
|
||||||
else if (scriptPath.EndsWith(".ps1"))
|
if (Directory.Exists(ConfigFolder + "scripts-ps"))
|
||||||
Task.Run(() => PowerShellScript.Init(scriptPath));
|
foreach (string file in Directory.GetFiles(ConfigFolder + "scripts-ps", "*.ps1"))
|
||||||
|
App.RunAction(() => InvokePowerShellScript(file));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void InvokePowerShellScript(string file)
|
||||||
|
{
|
||||||
|
PowerShell ps = new PowerShell();
|
||||||
|
ps.Scripts.Add("Using namespace mpvnet" + BR +
|
||||||
|
"[Reflection.Assembly]::LoadWithPartialName('mpvnet')" + BR);
|
||||||
|
ps.Scripts.Add(File.ReadAllText(file));
|
||||||
|
ps.Module = Path.GetFileName(file);
|
||||||
|
ps.Print = true;
|
||||||
|
|
||||||
|
lock (PowerShell.Instances)
|
||||||
|
PowerShell.Instances.Add(ps);
|
||||||
|
|
||||||
|
ps.Invoke();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void EventLoop()
|
public static void EventLoop()
|
||||||
@@ -285,7 +329,7 @@ namespace mpvnet
|
|||||||
if (WindowHandle == IntPtr.Zero)
|
if (WindowHandle == IntPtr.Zero)
|
||||||
WindowHandle = FindWindowEx(MainForm.Hwnd, IntPtr.Zero, "mpv", null);
|
WindowHandle = FindWindowEx(MainForm.Hwnd, IntPtr.Zero, "mpv", null);
|
||||||
|
|
||||||
// Debug.WriteLine(evt.event_id.ToString());
|
//Debug.WriteLine(evt.event_id.ToString());
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -298,7 +342,10 @@ namespace mpvnet
|
|||||||
ShutdownAutoResetEvent.Set();
|
ShutdownAutoResetEvent.Set();
|
||||||
return;
|
return;
|
||||||
case mpv_event_id.MPV_EVENT_LOG_MESSAGE:
|
case mpv_event_id.MPV_EVENT_LOG_MESSAGE:
|
||||||
LogMessage?.Invoke();
|
{
|
||||||
|
var data = (mpv_event_log_message)Marshal.PtrToStructure(evt.data, typeof(mpv_event_log_message));
|
||||||
|
LogMessage?.Invoke(data.log_level, $"[{data.prefix}] {data.text}");
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case mpv_event_id.MPV_EVENT_GET_PROPERTY_REPLY:
|
case mpv_event_id.MPV_EVENT_GET_PROPERTY_REPLY:
|
||||||
GetPropertyReply?.Invoke();
|
GetPropertyReply?.Invoke();
|
||||||
@@ -313,28 +360,41 @@ namespace mpvnet
|
|||||||
StartFile?.Invoke();
|
StartFile?.Invoke();
|
||||||
break;
|
break;
|
||||||
case mpv_event_id.MPV_EVENT_END_FILE:
|
case mpv_event_id.MPV_EVENT_END_FILE:
|
||||||
var end_fileData = (mpv_event_end_file)Marshal.PtrToStructure(evt.data, typeof(mpv_event_end_file));
|
{
|
||||||
EndFileEventMode reason = (EndFileEventMode)end_fileData.reason;
|
var data = (mpv_event_end_file)Marshal.PtrToStructure(evt.data, typeof(mpv_event_end_file));
|
||||||
EndFile?.Invoke(reason);
|
EndFileEventMode reason = (EndFileEventMode)data.reason;
|
||||||
|
EndFile?.Invoke(reason);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case mpv_event_id.MPV_EVENT_FILE_LOADED:
|
case mpv_event_id.MPV_EVENT_FILE_LOADED:
|
||||||
HideLogo();
|
|
||||||
Duration = TimeSpan.FromSeconds(get_property_number("duration"));
|
|
||||||
Size vidSize = new Size(get_property_int("width"), get_property_int("height"));
|
|
||||||
if (vidSize.Width == 0 || vidSize.Height == 0)
|
|
||||||
vidSize = new Size(1, 1);
|
|
||||||
if (VideoSize != vidSize)
|
|
||||||
{
|
{
|
||||||
VideoSize = vidSize;
|
HideLogo();
|
||||||
VideoSizeChanged?.Invoke();
|
Duration = TimeSpan.FromSeconds(get_property_number("duration"));
|
||||||
|
|
||||||
|
if (App.StartSize == "video")
|
||||||
|
mp.WasInitialSizeSet = false;
|
||||||
|
|
||||||
|
Size size = new Size(get_property_int("width"), get_property_int("height"));
|
||||||
|
|
||||||
|
if (size.Width == 0 || size.Height == 0)
|
||||||
|
size = new Size(1, 1);
|
||||||
|
|
||||||
|
if (VideoSize != size)
|
||||||
|
{
|
||||||
|
VideoSize = size;
|
||||||
|
VideoSizeChanged?.Invoke();
|
||||||
|
}
|
||||||
|
|
||||||
|
VideoSizeAutoResetEvent.Set();
|
||||||
|
Task.Run(new Action(() => ReadMetaData()));
|
||||||
|
string path = mp.get_property_string("path");
|
||||||
|
|
||||||
|
if (path.Contains("://"))
|
||||||
|
path = mp.get_property_string("media-title");
|
||||||
|
|
||||||
|
WriteHistory(path);
|
||||||
|
FileLoaded?.Invoke();
|
||||||
}
|
}
|
||||||
VideoSizeAutoResetEvent.Set();
|
|
||||||
Task.Run(new Action(() => ReadMetaData()));
|
|
||||||
string path = mp.get_property_string("path");
|
|
||||||
if (path.Contains("://"))
|
|
||||||
path = mp.get_property_string("media-title");
|
|
||||||
WriteHistory(path);
|
|
||||||
FileLoaded?.Invoke();
|
|
||||||
break;
|
break;
|
||||||
case mpv_event_id.MPV_EVENT_TRACKS_CHANGED:
|
case mpv_event_id.MPV_EVENT_TRACKS_CHANGED:
|
||||||
TracksChanged?.Invoke();
|
TracksChanged?.Invoke();
|
||||||
@@ -352,22 +412,31 @@ namespace mpvnet
|
|||||||
case mpv_event_id.MPV_EVENT_UNPAUSE:
|
case mpv_event_id.MPV_EVENT_UNPAUSE:
|
||||||
Unpause?.Invoke();
|
Unpause?.Invoke();
|
||||||
break;
|
break;
|
||||||
case mpv_event_id.MPV_EVENT_TICK:
|
|
||||||
Tick?.Invoke();
|
|
||||||
break;
|
|
||||||
case mpv_event_id.MPV_EVENT_SCRIPT_INPUT_DISPATCH:
|
case mpv_event_id.MPV_EVENT_SCRIPT_INPUT_DISPATCH:
|
||||||
ScriptInputDispatch?.Invoke();
|
ScriptInputDispatch?.Invoke();
|
||||||
break;
|
break;
|
||||||
case mpv_event_id.MPV_EVENT_CLIENT_MESSAGE:
|
case mpv_event_id.MPV_EVENT_CLIENT_MESSAGE:
|
||||||
var client_messageData = (mpv_event_client_message)Marshal.PtrToStructure(evt.data, typeof(mpv_event_client_message));
|
{
|
||||||
string[] args = NativeUtf8StrArray2ManagedStrArray(client_messageData.args, client_messageData.num_args);
|
var data = (mpv_event_client_message)Marshal.PtrToStructure(evt.data, typeof(mpv_event_client_message));
|
||||||
if (args.Length > 1 && args[0] == "mpv.net")
|
string[] args = ConvertFromUtf8Strings(data.args, data.num_args);
|
||||||
Command.Execute(args[1], args.Skip(2).ToArray());
|
|
||||||
else if (args.Length > 0)
|
if (args.Length > 1 && args[0] == "mpv.net")
|
||||||
ClientMessage?.Invoke(args);
|
Command.Execute(args[1], args.Skip(2).ToArray());
|
||||||
|
else if (args.Length > 0)
|
||||||
|
ClientMessage?.Invoke(args);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case mpv_event_id.MPV_EVENT_VIDEO_RECONFIG:
|
case mpv_event_id.MPV_EVENT_VIDEO_RECONFIG:
|
||||||
VideoReconfig?.Invoke();
|
{
|
||||||
|
VideoReconfig?.Invoke();
|
||||||
|
Size size = new Size(get_property_int("dwidth"), get_property_int("dheight"));
|
||||||
|
|
||||||
|
if (size.Width != 0 && size.Height != 0 && VideoSize != size)
|
||||||
|
{
|
||||||
|
VideoSize = size;
|
||||||
|
VideoSizeChanged?.Invoke();
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case mpv_event_id.MPV_EVENT_AUDIO_RECONFIG:
|
case mpv_event_id.MPV_EVENT_AUDIO_RECONFIG:
|
||||||
AudioReconfig?.Invoke();
|
AudioReconfig?.Invoke();
|
||||||
@@ -379,35 +448,45 @@ namespace mpvnet
|
|||||||
Seek?.Invoke();
|
Seek?.Invoke();
|
||||||
break;
|
break;
|
||||||
case mpv_event_id.MPV_EVENT_PROPERTY_CHANGE:
|
case mpv_event_id.MPV_EVENT_PROPERTY_CHANGE:
|
||||||
var propData = (mpv_event_property)Marshal.PtrToStructure(evt.data, typeof(mpv_event_property));
|
{
|
||||||
|
var data = (mpv_event_property)Marshal.PtrToStructure(evt.data, typeof(mpv_event_property));
|
||||||
|
//Debug.WriteLine(data.name);
|
||||||
|
|
||||||
if (propData.format == mpv_format.MPV_FORMAT_FLAG)
|
if (data.format == mpv_format.MPV_FORMAT_FLAG)
|
||||||
{
|
{
|
||||||
lock (BoolPropChangeActions)
|
lock (BoolPropChangeActions)
|
||||||
foreach (var i in BoolPropChangeActions)
|
foreach (var i in BoolPropChangeActions)
|
||||||
if (i.Key== propData.name)
|
if (i.Key== data.name)
|
||||||
i.Value.Invoke(Marshal.PtrToStructure<int>(propData.data) == 1);
|
i.Value.Invoke(Marshal.PtrToStructure<int>(data.data) == 1);
|
||||||
}
|
}
|
||||||
else if (propData.format == mpv_format.MPV_FORMAT_STRING)
|
else if (data.format == mpv_format.MPV_FORMAT_STRING)
|
||||||
{
|
{
|
||||||
lock (StringPropChangeActions)
|
lock (StringPropChangeActions)
|
||||||
foreach (var i in StringPropChangeActions)
|
foreach (var i in StringPropChangeActions)
|
||||||
if (i.Key == propData.name)
|
if (i.Key == data.name)
|
||||||
i.Value.Invoke(StringFromNativeUtf8(Marshal.PtrToStructure<IntPtr>(propData.data)));
|
i.Value.Invoke(ConvertFromUtf8(Marshal.PtrToStructure<IntPtr>(data.data)));
|
||||||
}
|
}
|
||||||
else if(propData.format == mpv_format.MPV_FORMAT_INT64)
|
else if(data.format == mpv_format.MPV_FORMAT_INT64)
|
||||||
{
|
{
|
||||||
lock (IntPropChangeActions)
|
lock (IntPropChangeActions)
|
||||||
foreach (var i in IntPropChangeActions)
|
foreach (var i in IntPropChangeActions)
|
||||||
if (i.Key == propData.name)
|
if (i.Key == data.name)
|
||||||
i.Value.Invoke(Marshal.PtrToStructure<int>(propData.data));
|
i.Value.Invoke(Marshal.PtrToStructure<int>(data.data));
|
||||||
}
|
}
|
||||||
else if (propData.format == mpv_format.MPV_FORMAT_DOUBLE)
|
else if (data.format == mpv_format.MPV_FORMAT_NONE)
|
||||||
{
|
{
|
||||||
lock (DoublePropChangeActions)
|
lock (PropChangeActions)
|
||||||
foreach (var i in DoublePropChangeActions)
|
foreach (var i in PropChangeActions)
|
||||||
if (i.Key == propData.name)
|
if (i.Key == data.name)
|
||||||
i.Value.Invoke(Marshal.PtrToStructure<double>(propData.data));
|
i.Value.Invoke();
|
||||||
|
}
|
||||||
|
else if (data.format == mpv_format.MPV_FORMAT_DOUBLE)
|
||||||
|
{
|
||||||
|
lock (DoublePropChangeActions)
|
||||||
|
foreach (var i in DoublePropChangeActions)
|
||||||
|
if (i.Key == data.name)
|
||||||
|
i.Value.Invoke(Marshal.PtrToStructure<double>(data.data));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case mpv_event_id.MPV_EVENT_PLAYBACK_RESTART:
|
case mpv_event_id.MPV_EVENT_PLAYBACK_RESTART:
|
||||||
@@ -477,92 +556,109 @@ namespace mpvnet
|
|||||||
|
|
||||||
public static void commandv(params string[] args)
|
public static void commandv(params string[] args)
|
||||||
{
|
{
|
||||||
if (Handle == IntPtr.Zero) return;
|
IntPtr mainPtr = AllocateUtf8ArrayWithSentinel(args, out IntPtr[] byteArrayPointers);
|
||||||
IntPtr mainPtr = AllocateUtf8IntPtrArrayWithSentinel(args, out IntPtr[] byteArrayPointers);
|
mpv_error err = mpv_command(Handle, mainPtr);
|
||||||
int err = mpv_command(Handle, mainPtr);
|
|
||||||
if (err < 0) throw new Exception($"{(mpv_error)err}");
|
foreach (IntPtr ptr in byteArrayPointers)
|
||||||
foreach (var ptr in byteArrayPointers)
|
|
||||||
Marshal.FreeHGlobal(ptr);
|
Marshal.FreeHGlobal(ptr);
|
||||||
|
|
||||||
Marshal.FreeHGlobal(mainPtr);
|
Marshal.FreeHGlobal(mainPtr);
|
||||||
|
|
||||||
|
if (err < 0)
|
||||||
|
HandleError(err, true, "error executing command:", string.Join("\n", args));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void command(string command, bool throwException = false)
|
public static void command(string command, bool throwException = false)
|
||||||
{
|
{
|
||||||
if (Handle == IntPtr.Zero) return;
|
mpv_error err = mpv_command_string(Handle, command);
|
||||||
int err = mpv_command_string(Handle, command);
|
|
||||||
if (err < 0 && throwException) throw new Exception($"{(mpv_error)err}\n\n" + command);
|
if (err < 0)
|
||||||
|
HandleError(err, throwException, "error executing command:", command);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void set_property_string(string name, string value, bool throwOnException = false)
|
public static void set_property_int(string name, int value, bool throwException = false)
|
||||||
|
{
|
||||||
|
Int64 val = value;
|
||||||
|
mpv_error err = mpv_set_property(Handle, GetUtf8Bytes(name), mpv_format.MPV_FORMAT_INT64, ref val);
|
||||||
|
|
||||||
|
if (err < 0)
|
||||||
|
HandleError(err, throwException, $"error setting property: {name} = {value}");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void set_property_bool(string name, bool value, bool throwException = false)
|
||||||
|
{
|
||||||
|
Int64 val = (value) ? 1 : 0;
|
||||||
|
mpv_error err = mpv_set_property(Handle, GetUtf8Bytes(name), mpv_format.MPV_FORMAT_FLAG, ref val);
|
||||||
|
|
||||||
|
if (err < 0)
|
||||||
|
HandleError(err, throwException, $"error setting property: {name} = {value}");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void set_property_string(string name, string value, bool throwException = false)
|
||||||
{
|
{
|
||||||
byte[] bytes = GetUtf8Bytes(value);
|
byte[] bytes = GetUtf8Bytes(value);
|
||||||
int err = mpv_set_property(Handle, GetUtf8Bytes(name), mpv_format.MPV_FORMAT_STRING, ref bytes);
|
mpv_error err = mpv_set_property(Handle, GetUtf8Bytes(name), mpv_format.MPV_FORMAT_STRING, ref bytes);
|
||||||
if (err < 0 && throwOnException) throw new Exception($"{name}: {(mpv_error)err}");
|
|
||||||
|
if (err < 0)
|
||||||
|
HandleError(err, throwException, $"error setting property: {name} = " + value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string get_property_string(string name, bool throwOnException = false)
|
public static string get_property_string(string name, bool throwException = false)
|
||||||
{
|
{
|
||||||
try
|
mpv_error err = mpv_get_property(Handle, GetUtf8Bytes(name),
|
||||||
|
mpv_format.MPV_FORMAT_STRING, out IntPtr lpBuffer);
|
||||||
|
|
||||||
|
if (err == 0)
|
||||||
{
|
{
|
||||||
int err = mpv_get_property(Handle, GetUtf8Bytes(name), mpv_format.MPV_FORMAT_STRING, out IntPtr lpBuffer);
|
string ret = ConvertFromUtf8(lpBuffer);
|
||||||
|
|
||||||
if (err < 0)
|
|
||||||
{
|
|
||||||
if (throwOnException) throw new Exception($"{name}: {(mpv_error)err}");
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
string ret = StringFromNativeUtf8(lpBuffer);
|
|
||||||
mpv_free(lpBuffer);
|
mpv_free(lpBuffer);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
|
||||||
{
|
HandleError(err, throwException, $"error getting property: {name}");
|
||||||
if (throwOnException) throw e;
|
return "";
|
||||||
return "";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int get_property_int(string name, bool throwOnException = false)
|
public static int get_property_int(string name, bool throwException = false)
|
||||||
{
|
{
|
||||||
int err = mpv_get_property(Handle, GetUtf8Bytes(name), mpv_format.MPV_FORMAT_INT64, out IntPtr lpBuffer);
|
mpv_error err = mpv_get_property(Handle, GetUtf8Bytes(name),
|
||||||
|
mpv_format.MPV_FORMAT_INT64, out IntPtr lpBuffer);
|
||||||
|
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
{
|
HandleError(err, throwException, $"error getting property: {name}");
|
||||||
if (throwOnException) throw new Exception($"{name}: {(mpv_error)err}");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return lpBuffer.ToInt32();
|
return lpBuffer.ToInt32();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static double get_property_number(string name, bool throwOnException = false)
|
public static bool get_property_bool(string name, bool throwException = false)
|
||||||
{
|
{
|
||||||
double val = 0;
|
mpv_error err = mpv_get_property(Handle, GetUtf8Bytes(name),
|
||||||
int err = mpv_get_property(Handle, GetUtf8Bytes(name), mpv_format.MPV_FORMAT_DOUBLE, ref val);
|
mpv_format.MPV_FORMAT_FLAG, out IntPtr lpBuffer);
|
||||||
|
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
{
|
HandleError(err, throwException, $"error getting property: {name}");
|
||||||
if (throwOnException) throw new Exception($"{name}: {(mpv_error)err}");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return val;
|
return lpBuffer.ToInt32() != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void set_property_int(string name, int value, bool throwOnException = false)
|
public static double get_property_number(string name, bool throwException = false)
|
||||||
{
|
{
|
||||||
Int64 val = value;
|
mpv_error err = mpv_get_property(Handle, GetUtf8Bytes(name),
|
||||||
int err = mpv_set_property(Handle, GetUtf8Bytes(name), mpv_format.MPV_FORMAT_INT64, ref val);
|
mpv_format.MPV_FORMAT_DOUBLE, out double value);
|
||||||
if (err < 0 && throwOnException) throw new Exception($"{name}: {(mpv_error)err}");
|
|
||||||
|
if (err < 0)
|
||||||
|
HandleError(err, throwException, $"error getting property: {name}");
|
||||||
|
|
||||||
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void observe_property_int(string name, Action<int> action)
|
public static void observe_property_int(string name, Action<int> action)
|
||||||
{
|
{
|
||||||
int err = mpv_observe_property(Handle, (ulong)action.GetHashCode(), name, mpv_format.MPV_FORMAT_INT64);
|
mpv_error err = mpv_observe_property(Handle, (ulong)action.GetHashCode(),
|
||||||
|
name, mpv_format.MPV_FORMAT_INT64);
|
||||||
|
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
throw new Exception($"{name}: {(mpv_error)err}");
|
HandleError(err, true, $"error observing property: {name}");
|
||||||
else
|
else
|
||||||
lock (IntPropChangeActions)
|
lock (IntPropChangeActions)
|
||||||
IntPropChangeActions.Add(new KeyValuePair<string, Action<int>>(name, action));
|
IntPropChangeActions.Add(new KeyValuePair<string, Action<int>>(name, action));
|
||||||
@@ -570,10 +666,11 @@ namespace mpvnet
|
|||||||
|
|
||||||
public static void observe_property_double(string name, Action<double> action)
|
public static void observe_property_double(string name, Action<double> action)
|
||||||
{
|
{
|
||||||
int err = mpv_observe_property(Handle, (ulong)action.GetHashCode(), name, mpv_format.MPV_FORMAT_DOUBLE);
|
mpv_error err = mpv_observe_property(Handle, (ulong)action.GetHashCode(),
|
||||||
|
name, mpv_format.MPV_FORMAT_DOUBLE);
|
||||||
|
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
throw new Exception($"{name}: {(mpv_error)err}");
|
HandleError(err, true, $"error observing property: {name}");
|
||||||
else
|
else
|
||||||
lock (DoublePropChangeActions)
|
lock (DoublePropChangeActions)
|
||||||
DoublePropChangeActions.Add(new KeyValuePair<string, Action<double>>(name, action));
|
DoublePropChangeActions.Add(new KeyValuePair<string, Action<double>>(name, action));
|
||||||
@@ -581,10 +678,11 @@ namespace mpvnet
|
|||||||
|
|
||||||
public static void observe_property_bool(string name, Action<bool> action)
|
public static void observe_property_bool(string name, Action<bool> action)
|
||||||
{
|
{
|
||||||
int err = mpv_observe_property(Handle, (ulong)action.GetHashCode(), name, mpv_format.MPV_FORMAT_FLAG);
|
mpv_error err = mpv_observe_property(Handle, (ulong)action.GetHashCode(),
|
||||||
|
name, mpv_format.MPV_FORMAT_FLAG);
|
||||||
|
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
throw new Exception($"{name}: {(mpv_error)err}");
|
HandleError(err, true, $"error observing property: {name}");
|
||||||
else
|
else
|
||||||
lock (BoolPropChangeActions)
|
lock (BoolPropChangeActions)
|
||||||
BoolPropChangeActions.Add(new KeyValuePair<string, Action<bool>>(name, action));
|
BoolPropChangeActions.Add(new KeyValuePair<string, Action<bool>>(name, action));
|
||||||
@@ -592,57 +690,94 @@ namespace mpvnet
|
|||||||
|
|
||||||
public static void observe_property_string(string name, Action<string> action)
|
public static void observe_property_string(string name, Action<string> action)
|
||||||
{
|
{
|
||||||
int err = mpv_observe_property(Handle, (ulong)action.GetHashCode(), name, mpv_format.MPV_FORMAT_STRING);
|
mpv_error err = mpv_observe_property(Handle, (ulong)action.GetHashCode(),
|
||||||
|
name, mpv_format.MPV_FORMAT_STRING);
|
||||||
|
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
throw new Exception($"{name}: {(mpv_error)err}");
|
HandleError(err, true, $"error observing property: {name}");
|
||||||
else
|
else
|
||||||
lock (StringPropChangeActions)
|
lock (StringPropChangeActions)
|
||||||
StringPropChangeActions.Add(new KeyValuePair<string, Action<string>>(name, action));
|
StringPropChangeActions.Add(new KeyValuePair<string, Action<string>>(name, action));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void observe_property(string name, Action action)
|
||||||
|
{
|
||||||
|
mpv_error err = mpv_observe_property(Handle, (ulong)action.GetHashCode(),
|
||||||
|
name, mpv_format.MPV_FORMAT_NONE);
|
||||||
|
|
||||||
|
if (err < 0)
|
||||||
|
HandleError(err, true, $"error observing property: {name}");
|
||||||
|
else
|
||||||
|
lock (PropChangeActions)
|
||||||
|
PropChangeActions.Add(new KeyValuePair<string, Action>(name, action));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void HandleError(mpv_error err, bool throwException, params string[] messages)
|
||||||
|
{
|
||||||
|
if (throwException)
|
||||||
|
{
|
||||||
|
foreach (string msg in messages)
|
||||||
|
ConsoleHelp.WriteError(msg, "mpv.net");
|
||||||
|
|
||||||
|
ConsoleHelp.WriteError(GetError(err), "mpv.net");
|
||||||
|
throw new Exception(string.Join(BR2, messages) + BR2 + GetError(err));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static void ProcessCommandLine(bool preInit)
|
public static void ProcessCommandLine(bool preInit)
|
||||||
{
|
{
|
||||||
var args = Environment.GetCommandLineArgs().Skip(1);
|
var args = Environment.GetCommandLineArgs().Skip(1);
|
||||||
|
|
||||||
//Msg.Show(string.Join("\n", args));
|
string[] preInitProperties = { "input-terminal", "terminal", "input-file", "config",
|
||||||
|
"config-dir", "input-conf", "load-scripts", "scripts", "player-operation-mode" };
|
||||||
string[] preInitProperties = { "input-terminal", "terminal", "input-file", "config", "config-dir", "input-conf", "load-scripts", "scripts", "player-operation-mode" };
|
|
||||||
|
|
||||||
foreach (string i in args)
|
foreach (string i in args)
|
||||||
{
|
{
|
||||||
string arg = i;
|
string arg = i;
|
||||||
|
|
||||||
if (arg.StartsWith("--"))
|
if (arg.StartsWith("-"))
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (!arg.Contains("=")) arg += "=yes";
|
if (!arg.StartsWith("--"))
|
||||||
|
arg = "-" + arg;
|
||||||
|
|
||||||
|
if (!arg.Contains("="))
|
||||||
|
{
|
||||||
|
if (arg.Contains("--no-"))
|
||||||
|
{
|
||||||
|
arg = arg.Replace("--no-", "--");
|
||||||
|
arg += "=no";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
arg += "=yes";
|
||||||
|
}
|
||||||
|
|
||||||
string left = arg.Substring(2, arg.IndexOf("=") - 2);
|
string left = arg.Substring(2, arg.IndexOf("=") - 2);
|
||||||
string right = arg.Substring(left.Length + 3);
|
string right = arg.Substring(left.Length + 3);
|
||||||
|
|
||||||
if (left == "script") left = "scripts";
|
if (left == "script")
|
||||||
|
left = "scripts";
|
||||||
|
|
||||||
if (preInit && preInitProperties.Contains(left))
|
if (preInit && preInitProperties.Contains(left))
|
||||||
{
|
{
|
||||||
mp.ProcessProperty(left, right);
|
mp.ProcessProperty(left, right);
|
||||||
|
|
||||||
if (!App.ProcessProperty(left, right))
|
if (!App.ProcessProperty(left, right))
|
||||||
set_property_string(left, right, true);
|
set_property_string(left, right, true);
|
||||||
}
|
}
|
||||||
else if (!preInit && !preInitProperties.Contains(left))
|
else if (!preInit && !preInitProperties.Contains(left))
|
||||||
{
|
{
|
||||||
if (!PrintCommandLineArgument(arg))
|
mp.ProcessProperty(left, right);
|
||||||
{
|
|
||||||
mp.ProcessProperty(left, right);
|
if (!App.ProcessProperty(left, right))
|
||||||
if (!App.ProcessProperty(left, right))
|
set_property_string(left, right, true);
|
||||||
set_property_string(left, right, true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Msg.ShowException(e);
|
if (!App.IsStartedFromTerminal)
|
||||||
|
Msg.ShowException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -660,7 +795,7 @@ namespace mpvnet
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Load(files.ToArray(), !App.Queue, Control.ModifierKeys.HasFlag(Keys.Control) || App.Queue);
|
LoadFiles(files.ToArray(), !App.Queue, Control.ModifierKeys.HasFlag(Keys.Control) || App.Queue);
|
||||||
|
|
||||||
if (files.Count == 0 || files[0].Contains("://"))
|
if (files.Count == 0 || files[0].Contains("://"))
|
||||||
{
|
{
|
||||||
@@ -670,23 +805,9 @@ namespace mpvnet
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool PrintCommandLineArgument(string argument)
|
|
||||||
{
|
|
||||||
switch (argument)
|
|
||||||
{
|
|
||||||
case "--list-properties=yes":
|
|
||||||
var list = get_property_string("property-list").Split(',').ToList();
|
|
||||||
list.Sort();
|
|
||||||
Console.WriteLine(string.Join("\r\n", list.ToArray()));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static DateTime LastLoad;
|
public static DateTime LastLoad;
|
||||||
|
|
||||||
public static void Load(string[] files, bool loadFolder, bool append)
|
public static void LoadFiles(string[] files, bool loadFolder, bool append)
|
||||||
{
|
{
|
||||||
if (files is null || files.Length == 0)
|
if (files is null || files.Length == 0)
|
||||||
return;
|
return;
|
||||||
@@ -699,13 +820,17 @@ namespace mpvnet
|
|||||||
LastLoad = DateTime.Now;
|
LastLoad = DateTime.Now;
|
||||||
|
|
||||||
for (int i = 0; i < files.Length; i++)
|
for (int i = 0; i < files.Length; i++)
|
||||||
if (App.SubtitleTypes.Contains(files[i].ShortExt()))
|
{
|
||||||
commandv("sub-add", files[i]);
|
string file = files[i];
|
||||||
|
|
||||||
|
if (App.SubtitleTypes.Contains(file.ShortExt()))
|
||||||
|
commandv("sub-add", file);
|
||||||
else
|
else
|
||||||
if (i == 0 && !append)
|
if (i == 0 && !append)
|
||||||
commandv("loadfile", files[i]);
|
commandv("loadfile", file);
|
||||||
else
|
else
|
||||||
commandv("loadfile", files[i], "append");
|
commandv("loadfile", file, "append");
|
||||||
|
}
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(get_property_string("path")))
|
if (string.IsNullOrEmpty(get_property_string("path")))
|
||||||
set_property_int("playlist-pos", 0);
|
set_property_int("playlist-pos", 0);
|
||||||
@@ -743,47 +868,6 @@ namespace mpvnet
|
|||||||
commandv("playlist-move", "0", (index + 1).ToString());
|
commandv("playlist-move", "0", (index + 1).ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IntPtr AllocateUtf8IntPtrArrayWithSentinel(string[] arr, out IntPtr[] byteArrayPointers)
|
|
||||||
{
|
|
||||||
int numberOfStrings = arr.Length + 1; // add extra element for extra null pointer last (sentinel)
|
|
||||||
byteArrayPointers = new IntPtr[numberOfStrings];
|
|
||||||
IntPtr rootPointer = Marshal.AllocCoTaskMem(IntPtr.Size * numberOfStrings);
|
|
||||||
|
|
||||||
for (int index = 0; index < arr.Length; index++)
|
|
||||||
{
|
|
||||||
var bytes = GetUtf8Bytes(arr[index]);
|
|
||||||
IntPtr unmanagedPointer = Marshal.AllocHGlobal(bytes.Length);
|
|
||||||
Marshal.Copy(bytes, 0, unmanagedPointer, bytes.Length);
|
|
||||||
byteArrayPointers[index] = unmanagedPointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
Marshal.Copy(byteArrayPointers, 0, rootPointer, numberOfStrings);
|
|
||||||
return rootPointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string[] NativeUtf8StrArray2ManagedStrArray(IntPtr unmanagedStringArray, int StringCount)
|
|
||||||
{
|
|
||||||
IntPtr[] intPtrArray = new IntPtr[StringCount];
|
|
||||||
string[] stringArray = new string[StringCount];
|
|
||||||
Marshal.Copy(unmanagedStringArray, intPtrArray, 0, StringCount);
|
|
||||||
|
|
||||||
for (int i = 0; i < StringCount; i++)
|
|
||||||
stringArray[i] = StringFromNativeUtf8(intPtrArray[i]);
|
|
||||||
|
|
||||||
return stringArray;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string StringFromNativeUtf8(IntPtr nativeUtf8)
|
|
||||||
{
|
|
||||||
int len = 0;
|
|
||||||
while (Marshal.ReadByte(nativeUtf8, len) != 0) ++len;
|
|
||||||
byte[] buffer = new byte[len];
|
|
||||||
Marshal.Copy(nativeUtf8, buffer, 0, buffer.Length);
|
|
||||||
return Encoding.UTF8.GetString(buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static byte[] GetUtf8Bytes(string s) => Encoding.UTF8.GetBytes(s + "\0");
|
|
||||||
|
|
||||||
static string LastHistoryPath;
|
static string LastHistoryPath;
|
||||||
static DateTime LastHistoryStartDateTime;
|
static DateTime LastHistoryStartDateTime;
|
||||||
|
|
||||||
@@ -794,9 +878,9 @@ namespace mpvnet
|
|||||||
|
|
||||||
int totalMinutes = Convert.ToInt32((DateTime.Now - LastHistoryStartDateTime).TotalMinutes);
|
int totalMinutes = Convert.ToInt32((DateTime.Now - LastHistoryStartDateTime).TotalMinutes);
|
||||||
|
|
||||||
if (PathHelp.GetBaseName(LastHistoryPath) != "" && totalMinutes > 1)
|
if (LastHistoryPath != null && totalMinutes > 1)
|
||||||
File.AppendAllText(ConfigFolder + "history.txt", DateTime.Now.ToString().Substring(0, 16) +
|
File.AppendAllText(ConfigFolder + "history.txt", DateTime.Now.ToString().Substring(0, 16) +
|
||||||
" " + totalMinutes.ToString().PadLeft(3) + " " + PathHelp.GetBaseName(LastHistoryPath) + "\r\n");
|
" " + totalMinutes.ToString().PadLeft(3) + " " + LastHistoryPath + "\r\n");
|
||||||
|
|
||||||
LastHistoryPath = path;
|
LastHistoryPath = path;
|
||||||
LastHistoryStartDateTime = DateTime.Now;
|
LastHistoryStartDateTime = DateTime.Now;
|
||||||
|
|||||||
37
scripts/examples/dynamic-context-menu-items.cs
Normal file
37
scripts/examples/dynamic-context-menu-items.cs
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
|
||||||
|
// This script creates context menu items dynamically.
|
||||||
|
|
||||||
|
using mpvnet;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
class Script
|
||||||
|
{
|
||||||
|
MainForm MainForm;
|
||||||
|
|
||||||
|
public Script()
|
||||||
|
{
|
||||||
|
MainForm = mpvnet.MainForm.Instance;
|
||||||
|
MainForm.ContextMenu.Opening += ContextMenu_Opening;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ContextMenu_Opening(object sender, CancelEventArgs e)
|
||||||
|
{
|
||||||
|
// edit input.conf and add 'Edition' menu item there
|
||||||
|
MenuItem menuItem = MainForm.FindMenuItem("Edition");
|
||||||
|
|
||||||
|
if (menuItem == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
menuItem.DropDownItems.Clear();
|
||||||
|
var editionTracks = mp.MediaTracks.Where(track => track.Type == "e");
|
||||||
|
|
||||||
|
foreach (MediaTrack track in editionTracks)
|
||||||
|
{
|
||||||
|
MenuItem mi = new MenuItem(track.Text);
|
||||||
|
mi.Action = () => { mp.commandv("set", "edition", track.ID.ToString()); };
|
||||||
|
mi.Checked = mp.Edition == track.ID;
|
||||||
|
menuItem.DropDownItems.Add(mi);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
28
scripts/examples/key-binding.cs
Normal file
28
scripts/examples/key-binding.cs
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
|
||||||
|
// This script adds a key binding.
|
||||||
|
|
||||||
|
using System.Reflection;
|
||||||
|
|
||||||
|
using mpvnet;
|
||||||
|
|
||||||
|
class Script
|
||||||
|
{
|
||||||
|
public Script()
|
||||||
|
{
|
||||||
|
string content = "ctrl+w script-message my-message-1 my-argument-1";
|
||||||
|
string sectionName = Assembly.GetExecutingAssembly().GetName().Name;
|
||||||
|
mp.commandv("define-section", sectionName, content, "force");
|
||||||
|
mp.commandv("enable-section", sectionName);
|
||||||
|
mp.ClientMessage += ClientMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClientMessage(string[] args)
|
||||||
|
{
|
||||||
|
switch (args[0])
|
||||||
|
{
|
||||||
|
case "my-message-1":
|
||||||
|
Msg.Show(args[1]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
4
scripts/examples/message-box.ps1
Normal file
4
scripts/examples/message-box.ps1
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
|
||||||
|
// This script shows a message box using the Msg class of mpv.net.
|
||||||
|
|
||||||
|
[Msg]::Show("Hello World")
|
||||||
18
scripts/examples/observe-property-and-draw-text.cs
Normal file
18
scripts/examples/observe-property-and-draw-text.cs
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
|
||||||
|
// This script observes the fullscreen property and
|
||||||
|
// draws text on screen when the property changes.
|
||||||
|
|
||||||
|
using mpvnet;
|
||||||
|
|
||||||
|
class Script
|
||||||
|
{
|
||||||
|
public Script()
|
||||||
|
{
|
||||||
|
mp.observe_property_bool("fullscreen", FullscreenChange);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FullscreenChange(bool value)
|
||||||
|
{
|
||||||
|
mp.commandv("show-text", "fullscreen: " + value);
|
||||||
|
}
|
||||||
|
}
|
||||||
25
scripts/examples/open-file-dialog.ps1
Normal file
25
scripts/examples/open-file-dialog.ps1
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
|
||||||
|
# Shows the Open File dialog to open a file without loading its folder into the playlist.
|
||||||
|
|
||||||
|
# In input.conf add: <key> script-message load-without-folder
|
||||||
|
|
||||||
|
$job = Register-ObjectEvent -InputObject ([mpvnet.mp]) -EventName ClientMessage -Action {
|
||||||
|
|
||||||
|
# exit if message does not equal 'load-without-folder'
|
||||||
|
if ($args.Length -ne 1 -or $args[0] -ne 'load-without-folder')
|
||||||
|
{
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
|
||||||
|
$dialog = New-Object Windows.Forms.OpenFileDialog
|
||||||
|
|
||||||
|
if ($dialog.ShowDialog() -ne "OK") {
|
||||||
|
$dialog.Dispose()
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
|
||||||
|
[mp]::Load($dialog.FileNames, $false, $false);
|
||||||
|
$dialog.Dispose()
|
||||||
|
}
|
||||||
|
|
||||||
|
$ScriptHost.RedirectEventJobStreams($job)
|
||||||
43
scripts/examples/pause-when-minimize.cs
Normal file
43
scripts/examples/pause-when-minimize.cs
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
|
||||||
|
// Pauses playback when window is minimized and resumes afterwards.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
|
||||||
|
using mpvnet;
|
||||||
|
|
||||||
|
class Script
|
||||||
|
{
|
||||||
|
MainForm Form;
|
||||||
|
|
||||||
|
bool WasPlaying;
|
||||||
|
bool WasPaused;
|
||||||
|
|
||||||
|
public Script()
|
||||||
|
{
|
||||||
|
Form = MainForm.Instance;
|
||||||
|
Form.Resize += Form_Resize;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Form_Resize(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (Form.WindowState == FormWindowState.Minimized)
|
||||||
|
{
|
||||||
|
WasPlaying = !mp.get_property_bool("pause");
|
||||||
|
|
||||||
|
if (WasPlaying)
|
||||||
|
{
|
||||||
|
mp.set_property_bool("pause", true, true);
|
||||||
|
WasPaused = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (WasPaused)
|
||||||
|
{
|
||||||
|
mp.set_property_bool("pause", false, true);
|
||||||
|
WasPaused = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
25
scripts/examples/pause-when-minimize.lua
Normal file
25
scripts/examples/pause-when-minimize.lua
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
|
||||||
|
-- https://github.com/mpv-player/mpv/blob/master/TOOLS/lua/pause-when-minimize.lua
|
||||||
|
|
||||||
|
-- This script pauses playback when minimizing the window, and resumes playback
|
||||||
|
-- if it's brought back again. If the player was already paused when minimizing,
|
||||||
|
-- then try not to mess with the pause state.
|
||||||
|
|
||||||
|
local did_minimize = false
|
||||||
|
|
||||||
|
mp.observe_property("window-minimized", "bool", function(name, value)
|
||||||
|
local pause = mp.get_property_bool("pause")
|
||||||
|
|
||||||
|
if value == true then
|
||||||
|
if pause == false then
|
||||||
|
mp.set_property_bool("pause", true)
|
||||||
|
did_minimize = true
|
||||||
|
end
|
||||||
|
elseif value == false then
|
||||||
|
if did_minimize and (pause == true) then
|
||||||
|
mp.set_property_bool("pause", false)
|
||||||
|
end
|
||||||
|
|
||||||
|
did_minimize = false
|
||||||
|
end
|
||||||
|
end)
|
||||||
35
scripts/examples/seek-show-position.js
Normal file
35
scripts/examples/seek-show-position.js
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
|
||||||
|
// When seeking displays position and duration like so: 70:00 / 80:00
|
||||||
|
// Which is different from most players which use: 01:10:00 / 01:20:00
|
||||||
|
// In input.conf set the input command prefix no-osd infront of the seek command.
|
||||||
|
|
||||||
|
function add_zero(val)
|
||||||
|
{
|
||||||
|
val = Math.round(val);
|
||||||
|
return val > 9 ? "" + val : "0" + val;
|
||||||
|
}
|
||||||
|
|
||||||
|
function format(val)
|
||||||
|
{
|
||||||
|
var sec = Math.round(val);
|
||||||
|
|
||||||
|
if (sec < 0)
|
||||||
|
sec = 0;
|
||||||
|
|
||||||
|
pos_min_floor = Math.floor(sec / 60);
|
||||||
|
sec_rest = sec - pos_min_floor * 60;
|
||||||
|
return add_zero(pos_min_floor) + ":" + add_zero(sec_rest);
|
||||||
|
}
|
||||||
|
|
||||||
|
function on_seek(_)
|
||||||
|
{
|
||||||
|
pos = mp.get_property_number("time-pos");
|
||||||
|
dur = mp.get_property_number("duration");
|
||||||
|
|
||||||
|
if (pos > dur)
|
||||||
|
pos = dur;
|
||||||
|
|
||||||
|
mp.commandv("show-text", format(pos) + " / " + format(dur));
|
||||||
|
}
|
||||||
|
|
||||||
|
mp.register_event("seek", on_seek);
|
||||||
8
scripts/examples/seek.ps1
Normal file
8
scripts/examples/seek.ps1
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
|
||||||
|
# Display position in window title bar when seeking
|
||||||
|
|
||||||
|
$job = Register-ObjectEvent -InputObject ([mpvnet.mp]) -EventName Seek -Action {
|
||||||
|
[MainForm]::Instance.Text = [mp]::get_property_number("time-pos")
|
||||||
|
}
|
||||||
|
|
||||||
|
$ScriptHost.RedirectEventJobStreams($job)
|
||||||
27
scripts/examples/show-playlist.js
Normal file
27
scripts/examples/show-playlist.js
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
|
||||||
|
// This script shows the playlist.
|
||||||
|
|
||||||
|
function showPlaylist()
|
||||||
|
{
|
||||||
|
|
||||||
|
// set font size
|
||||||
|
mp.set_property_number("osd-font-size", 40);
|
||||||
|
|
||||||
|
// show playlist for 5 seconds
|
||||||
|
mp.command("show-text ${playlist} 5000");
|
||||||
|
|
||||||
|
// restore original font size in 6 seconds
|
||||||
|
setTimeout(resetFontSize, 6000);
|
||||||
|
}
|
||||||
|
|
||||||
|
// restore original font size
|
||||||
|
function resetFontSize()
|
||||||
|
{
|
||||||
|
mp.set_property_number("osd-font-size", size);
|
||||||
|
}
|
||||||
|
|
||||||
|
// save original font size
|
||||||
|
var size = mp.get_property_number("osd-font-size");
|
||||||
|
|
||||||
|
// input.conf: key script-binding show-playlist
|
||||||
|
mp.add_key_binding(null, "show-playlist", showPlaylist);
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
|
||||||
#define MyAppName "mpv.net"
|
#define MyAppName "mpv.net"
|
||||||
#define MyAppExeName "mpvnet.exe"
|
#define MyAppExeName "mpvnet.exe"
|
||||||
|
|
||||||
@@ -18,9 +19,11 @@ AppId={{9AA2B100-BEF3-44D0-B819-D8FC3C4D557D}}
|
|||||||
AppName={#MyAppName}
|
AppName={#MyAppName}
|
||||||
AppVersion={#MyAppVersion}
|
AppVersion={#MyAppVersion}
|
||||||
AppPublisher=Frank Skare (stax76)
|
AppPublisher=Frank Skare (stax76)
|
||||||
|
|
||||||
#if arch == "x64"
|
#if arch == "x64"
|
||||||
ArchitecturesInstallIn64BitMode=x64
|
ArchitecturesInstallIn64BitMode=x64
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Compression=lzma2
|
Compression=lzma2
|
||||||
DefaultDirName={commonpf}\{#MyAppName}
|
DefaultDirName={commonpf}\{#MyAppName}
|
||||||
OutputBaseFilename=mpv.net-setup-{#arch}-{#MyAppVersion}
|
OutputBaseFilename=mpv.net-setup-{#arch}-{#MyAppVersion}
|
||||||
@@ -34,7 +37,7 @@ Name: "{group}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"
|
|||||||
|
|
||||||
[Files]
|
[Files]
|
||||||
Source: "{#MyAppSourceDir}\{#MyAppExeName}"; DestDir: "{app}"; Flags: ignoreversion
|
Source: "{#MyAppSourceDir}\{#MyAppExeName}"; DestDir: "{app}"; Flags: ignoreversion
|
||||||
Source: "{#MyAppSourceDir}\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs; Excludes: "System.Management.Automation.xml"
|
Source: "{#MyAppSourceDir}\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs;
|
||||||
|
|
||||||
[Run]
|
[Run]
|
||||||
Filename: "{app}\{#MyAppExeName}"; Description: "Associate video file extensions?"; Flags: postinstall unchecked runascurrentuser runhidden nowait; Parameters: "--reg-file-assoc video"
|
Filename: "{app}\{#MyAppExeName}"; Description: "Associate video file extensions?"; Flags: postinstall unchecked runascurrentuser runhidden nowait; Parameters: "--reg-file-assoc video"
|
||||||
|
|||||||
Reference in New Issue
Block a user