It is currently October 19th, 2020, 9:14 pm

Rain Video

Post your work-in-progress and completed skins to share and discuss.
User avatar
Yincognito
Posts: 2760
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

Re: Rain Video

Post by Yincognito »

balala wrote: September 19th, 2020, 10:04 amNot sure, how?

How do you set and use the "Default Video Size"? This seems to be a default setting, but can you change the resolution and play the video with a different resolution than the default one, but not on full screen?
From the right click context menu of the skin, before actually playing a video. And yes, it is possible, once you set the resolution.
User avatar
Yincognito
Posts: 2760
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

Re: Rain Video

Post by Yincognito »

eclectic-tech wrote: September 19th, 2020, 1:53 am Yes, the FFPlay window is positioned at #CurrentConfigX#/#CurrentConfigY#.
I use the Process plugin to disable Draggable and RightMouseUpAction while the FFPlay process is active. This was designed to prevent moving the skin window or changing any custom skin actions while the third party window is active; I am trying to minimize any changes to the skin while a video is active because they really have no relationship once the video start.

The action you described is how I intended the skin to be used:
1) Select your desired resolution from the custom skin action
2) Position the skin where you want it
NOTE: the black outline is your guide in positioning for all resolutions except 'Default Video Size'
When using 'Default Video Size', the video will start at the skin 0,0 but may be off screen if you set the skin too far down the screen or too far right
3) The only simple mouse action available while a video is playing is 'LeftMouseUpAction' to toggle the 'Help Info'; all other mouse and key actions are used to control FFPlay
NOTE: It is possible to override my disabled actions, but I wanted to limit skin actions since video controls also use the mouse and keyboard, and as you noticed, it is possible to move the skin but the third party video will not be affected until the video is replayed.

This is a 'work-in-progress' and changes and suggestions are welcomed.
Yeah, I thought I could make the position and size of the video subject to modification in (near) realtime, by restarting ffplay.exe and using the -ss <time> parameter to "resume" the video from where it was on the previous execution, but the parameter is less precise than its equivalent in ffmpeg.exe, which means seeking will only be done on the basis of keyframes and such. My idea was to simulate a near realtime change of position or dimensions by re-executing ffplay.exe with the desired coordinate parameters ... but from the last played position. It could be done, but the fact that seeking goes to the keyframe won't make it as "seamless" as envisioned.

My opinion is that it would be best to allow a title for the ffplay.exe window so that the video window can be moved by the user. The skin itself would be able to move as well, and then it's up to the user to align them properly when playing (though they would be properly aligned initially). Right now, while the settings have the reasons you described, it's a bit uncomfortable that you can't move things when playing. I mean, as far as I see one wouldn't be able to reasonably align the skin and the video window while playing without preventing a legit action of the user (like moving things on the screen), so it might just be easier and more natural to leave them independent of each other in terms of coordinates. Just saying... :confused:

You don't have to do this though, I just started tweaking your skin a bit, let's see what can be improved (if any, that is)...

EDIT: Disregard what I just said, it's better to leave as it is.
User avatar
balala
Rainmeter Sage
Posts: 11575
Joined: October 11th, 2010, 6:27 pm
Location: Gheorgheni, Romania

Re: Rain Video

Post by balala »

Yincognito wrote: September 19th, 2020, 10:11 am From the right click context menu of the skin, before actually playing a video.
Alright, got it. It's great! Very useful skin, indeed.
User avatar
Yincognito
Posts: 2760
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

Re: Rain Video

Post by Yincognito »

eclectic-tech wrote: September 19th, 2020, 1:53 amThis is a 'work-in-progress' and changes and suggestions are welcomed.
Ok, here are my (optional) changes and (useful, I think) suggestions...

Variables.inc (placed in @Resources):

Code: Select all

[Variables]
File=""
Width=640
Height=360
Volume=50
RainVideo.ini:

Code: Select all

[Variables]
@IncludeVariables=#@#Variables.inc

[Metadata]
Name=RainVideo
Author=Eclectic Tech
Information=Play videos. Selectable frame size and positioning when no video is playing. Controls: quit, pause, step frame, fullscreen, volume up/down, mute when video has focus (left-click video first).
License=CC3-BY-SA-NC
Version=1.2020.09.19

[Rainmeter]
Update=1000
DynamicWindowSize=1
AccurateText=1

;OnRefreshAction=[!Draggable 1]

ContextTitle=Default Video Size
ContextAction=[!SetVariable Width 640][!SetVariable Height 34][!UpdateMeasure *][!UpdateMeter *][!Redraw]
ContextTitle2=320X180 Size
ContextAction2=[!SetVariable Width 320][!SetVariable Height 180][!UpdateMeasure *][!UpdateMeter *][!Redraw]
ContextTitle3=480X270 Size
ContextAction3=[!SetVariable Width 480][!SetVariable Height 270][!UpdateMeasure *][!UpdateMeter *][!Redraw]
ContextTitle4=640X360 Size
ContextAction4=[!SetVariable Width 640][!SetVariable Height 360][!UpdateMeasure *][!UpdateMeter *][!Redraw]
ContextTitle5=960X540 Size
ContextAction5=[!SetVariable Width 960][!SetVariable Height 540][!UpdateMeasure *][!UpdateMeter *][!Redraw]

---Measures---

[VideoSize]
Measure=String
String="-x #Width# -y #Height#"
UpdateDivider=-1
OnUpdateAction=[!WriteKeyValue Variables Width #Width# "#@#Variables.inc"][!WriteKeyValue Variables Height #Height# "#@#Variables.inc"]
RegExpSubstitute=1
Substitute="^-x 640 -y 34$":""
DynamicVariables=1

[MeasurePlaying]
Measure=Process
ProcessName=ffplay.exe
IfCondition=(MeasurePlaying=1)
IfTrueAction=[!Draggable 0][!DisableMouseAction Rainmeter RightMouseUpAction]
IfFalseAction=[!Draggable 1][!EnableMouseAction Rainmeter RightMouseUpAction][!HideMeter MeterControls][!Redraw]

[MeasureChoose]
Measure=Plugin
Plugin=FileChoose
GetTarget=1
CopyLink=1
LinkCache=#@#videos/
ReturnValue=WholePath
Command1=[!SetVariable File """$Path$"""][!WriteKeyValue Variables File """$Path$""" "#@#Variables.inc"]

[MeasurePlay]
Measure=Plugin
Plugin=RunCommand
Parameter=ffplay -left #CURRENTCONFIGX# -top #CURRENTCONFIGY# [VideoSize] -noborder -volume #Volume# -i "#File#" -hide_banner -autoexit >output.log 2>&1
OutputType=ANSI
State=Hide
StartInFolder=#@#ffmpeg
DynamicVariables=1

[MeasureLog]
Measure=Plugin
Plugin=RunCommand
Program=powershell
Parameter=-command Get-Content -Path .\output.log
OutputType=ANSI
State=Hide
StartInFolder=#@#ffmpeg
RegExpSubstitute=1
Substitute="(?siU)^.*Duration: (.*),.*bitrate: (.*)\R(.*)(?:\R\N* A-V:\N*)*?(?:\R\h+(\N*) A-V:\N* aq=(\N*) vq=(\N*) sq=(\N*) f=(\N*?)).*$":"DURATION = \1 | AVERAGE BITRATE: \2 | STREAMS: \3 | ELAPSED: \4 | AUDIO BITRATE: \5 | VIDEO BITRATE: \6 | SUBSTITLES: \7 | FPS: \8"
FinishAction=[!Log [MeasureLog]]
DynamicVariables=1

---Styles---

[StyleText]
FontWeight=700
FontSize=11
FontColor=255,255,255,255
SolidColor=0,0,0,255
Padding=5,5,5,5
AntiAlias=1

---Meters---

[MeterUpperLeftCorner]
Meter=Shape
X=0
Y=0
Shape=Rectangle 1,1,(#Width#-2),(#Height#-2) | StrokeWidth (-2*([MeasurePlaying]>0?0:[MeasurePlaying])) | Stroke Color 0,0,0 | Fill Color 0,0,0,0
DynamicVariables=1

[MeterControlToggle]
Meter=String
MeterStyle=StyleText
X=(#Width#+2)
Y=4r
Text=:=
LeftMouseUpAction=[!ToggleMeter MeterControls][!Redraw][!CommandMeasure MeasureLog "Run"]
ToolTipText=Toggle Help
DynamicVariables=1

[MeterControls]
Meter=String
MeterStyle=StyleText
X=r
Y=2R
W=136
Text="LMouse Video First#CRLF#KEY : ACTION#CRLF# \ \ \ \ \ \ \ \ / / / / / / / /#CRLF#p : Pause#CRLF#s : Step Frame#CRLF#f : FullScreen#CRLF#0 : Volume Up#CRLF#9 : Volume Dn#CRLF#m : Mute#CRLF#Seek: RMouse#CRLF#Arrows : +/- 10 Sec#CRLF#w : Waveforms#CRLF#q : Quit"
Hidden=([MeasurePlaying]=-1)?
DynamicVariables=1

[MeterPlay]
Meter=String
MeterStyle=StyleText
X=(#Width#-4)
Y=([MeterControlToggle:Y])
StringAlign=Right
Text=Play
LeftMouseUpAction=[!CommandMeasure MeasurePlay "Run"]
Hidden=([MeasurePlaying]=1)?
DynamicVariables=1

[MeterChooseFile]
Meter=String
MeterStyle=StyleText
X=4
Y=r
Text=Choose File
LeftMouseUpAction=[!CommandMeasure MeasureChoose "ChooseFile 1"]
Hidden=([MeasurePlaying]=1)?
DynamicVariables=1
What the above code does differently compared to the original is:
- moves the variables in a Variables.inc file, to avoid the skin file constantly being overwritten and have those popups in Notepad++
- gets rid of the !Refresh bangs and uses instead !SetVariable bangs and simple !WriteKeyValue bangs
- no need to write the Parameter option from [MeasurePlay] over and over again, the [VideoSize] measure builds the dimensions string for you
- added a volume setting in the ffplay.exe command, initially set to 50%, but adjustable from Variables.inc
- added a redirection (2>&1) from STDERR to STDOUT in the ffplay.exe command, since the app writes to STDERR while RunCommand deals with STDOUT
- added a log output to an output.log file in the FFmpeg folder
- added the possibility of getting the video stats from output.log through PowerShell in order to be displayed in the skin if desired

The main addition is of course the ability of getting the so called "realtime" (not exactly realtime, will get to this in a moment) video stats like duration, avg. bitrate, streams info, elapsed time, audio and video bitrate and subtitles and something labeled "f" (not sure what was that, so I just labeled it FPS, although it might be something entirely different LOL). These things are for now displayed in the Rainmeter Log whenever the user clicks on the := control toggle, simply because I didn't know where to place them in the skin - it will be your decision how often (once every X seconds), in which way (automatically or manually) and where to put them, eclectic-tech. They are extracted by [MeasureLog], by the way.

Now about the issue of getting these stats in realtime: although all 3 FFmpeg executables (ffprobe.exe, ffplay.exe and ffmpeg.exe) do output realtime stats on STDERR and you get to see these when running these in a cmd.exe window, one can't get these in realtime in Rainmeter because of either one or both the below reasons:
- the RunCommand plugin only gets the "final" output of a command, and not the "while working" output
- although the log can be written to a log file in realtime by ffplay.exe, "standard" Windows calls refuse to read from a file that's currently being written to
Therefore, pretty much the only choice that doesn't involve installing other 3rd party apps (like the implementation of the TAIL command from Unix to Windows) is to use the Get-Content command in PowerShell to periodically get the last bits of information that were written to the aforementioned log file. Apparently this command can read from a file that is currently being written, but due to the fact that PowerShell is slower than cmd.exe, one cannot abuse calls to it - probably some seconds between calls is appropriate.

Again, feel free to use (or not) these changes and / or additions however you like, or make any kind of adjustments you deem necessary. I intentionally let this somewhat "unfinished" in terms of things like placement in order to give you the freedom to decide yourself on the matter.

P.S. Bear in mind that although the video Duration is in HH:MM:SS format, the Elapsed time in the video is actually the number of seconds that were played up until the current moment. I believe an Uptime measure will come handy here to convert those seconds in an HH:MM:SS format.
User avatar
Yincognito
Posts: 2760
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

Re: Rain Video

Post by Yincognito »

eclectic-tech wrote: September 18th, 2020, 7:38 pmI think that your attempt to integrate using a Bitmap meter is a very resourceful idea. I am able to see what you have accomplished so far in extracting frame images, but feel it is going to present a lot of issues when dealing with longer video clips and then having to integrate and sync the audio. That is a "rabbit hole' I do not want to go down.
[...]
I look forward to seeing any further development of your Bitmap approach and will be glad offer suggestions.
I just added the audio in my version - with 0 synchronization issues while playing, at least from what I tested ... but for now there are very very short moments of silence when going from one buffer image to the other, probably because the operation of playing the frames in the Bitmap meter is not exactly the 1 second of the audio .WAV that is captured. Also, it seems that I miss something somewhere, because after a while a ffmpeg.exe process gets "stuck" running, although this didn't happen when playing only the video part.

In other words, this is correctable, but I'm not sure yet just how much. Here is the current code (not perfect and not finished) just to see how it works:

Code: Select all

[Variables]

; Update Rate = should be set to something close to (1000/FPS), where FPS = the clip's frames per second
Update=33
; Clip Name = the name of the clip; it should be located in the @Resources folder of the skin
Clip="input.mkv"
; Time Span = the total duration of the clip, in seconds; should be set according to the clip
Span=3600
; From Time = where does the playing begin, in seconds; doesn't need setting it, as it's automatically incremented while playing
From=0
; Play Time = how much does the playing last, in seconds; doesn't need setting it, as it's automatically added to From Time while playing
Time=1
; Bitmap Step = by how much the measure value used by the Bitmap meter increments; no need to adjust, as 1 means frame by frame
Step=1
; Tile Count = how many frames or tiles are in Play Time seconds; should be set to (Time*FPS), or simply the FPS value if Time equals 1 second
Tile=24
; Video Width = the width that a clip frame is displayed at, in pixels; also equal to the width of the playing "box" area in the skin
W=480
; Video Height = the height that a clip frame is displayed at, in pixels; also equal to the height of the playing "box" area in the skin
H=270

Extracted=0
RBuffer=0
WBuffer=1
SW=2
Buttons=2
Padding=10
ShadowOffset=5
ShadowBlur=7
GlowColor=0,255,0,255

[Rainmeter]
Update=#Update#
DynamicWindowSize=1
AccurateText=1

---Measures---

[Delete]
Measure=Plugin
Plugin=RunCommand
Parameter=del *.bmp *.wav
StartInFolder=#@#
State=Hide
OutputType=ANSI
FinishAction=[!Delay 0][!Refresh]

[Extract]
Measure=Plugin
Plugin=RunCommand
Parameter=ffmpeg -ss #From# -t #Time# -i "#Clip#" -vf scale=#W#:#H#,tile=#Tile#x1 "output#WBuffer#.bmp" "output#WBuffer#.wav" -y -hide_banner -loglevel fatal -nostats
StartInFolder=#@#
State=Hide
OutputType=ANSI
FinishAction=[!SetVariable Extracted 1][!EnableMeasure Frame]
DynamicVariables=1

[Frame]
Disabled=1
Measure=Loop
StartValue=0
EndValue=#Tile#
Increment=#Step#
LoopCount=1
IfCondition=(Frame=[Frame:MinValue]) && ((#From#+#Time#)<#Span#)
IfTrueAction=[Play "#@#output#WBuffer#.wav"][!SetVariable Extracted 0][!SetVariable From (#From#+#Time#)][!SetVariable RBuffer #WBuffer#][!SetVariable WBuffer #RBuffer#][!UpdateMeasure Extract][!CommandMeasure Extract "Run"]
IfCondition2=(Frame=[Frame:MaxValue]) && (#Extracted#=1) && ((#From#+#Time#)<#Span#)
IfTrueAction2=[!CommandMeasure Frame "Reset"][!UpdateMeasure Frame]
IfCondition3=(Frame=[Frame:MaxValue]) && (#Extracted#=1) && ((#From#+#Time#)>=#Span#)
IfTrueAction3=[!CommandMeasure Extract "Kill"][!CommandMeasure Delete "Run"]
IfConditionMode=1
DynamicVariables=1

---Styles---

[TextStyle]
X=#Padding#R
Y=0r
H=([Stop:W]*2.5)
FontFace=Tahoma
FontSize=20
FontColor=255,255,255,255
StringEffect=Shadow
FontEffectColor=0,0,0,255
AntiAlias=1
MouseOverAction=[!SetOption #CURRENTSECTION# MeterStyle "TextStyle | OverStyle"][!UpdateMeter #CURRENTSECTION#][!Redraw]
MouseLeaveAction=[!SetOption #CURRENTSECTION# MeterStyle "TextStyle | LeaveStyle"][!UpdateMeter #CURRENTSECTION#][!Redraw]

[OverStyle]
InlineSetting=Shadow | (-#ShadowOffset#) | (-#ShadowOffset#) | (#ShadowBlur#) | #GlowColor#
InlineSetting2=Shadow | (-#ShadowOffset#) | (#ShadowOffset#) | (#ShadowBlur#) | #GlowColor#
InlineSetting3=Shadow | (#ShadowOffset#) | (-#ShadowOffset#) | (#ShadowBlur#) | #GlowColor#
InlineSetting4=Shadow | (#ShadowOffset#) | (#ShadowOffset#) | (#ShadowBlur#) | #GlowColor#

[LeaveStyle]

---Meters---

[Border]
Meter=Shape
Shape=Rectangle (#SW#/2),(#SW#/2),(#W#+#SW#),(#H#+#SW#) | Fill Color 0,0,0,64 | StrokeWidth #SW# | Stroke Color 255,255,255,255
UpdateDivider=-1

[Video]
Meter=Bitmap
X=#SW#r
Y=#SW#r
BitmapImage="#@#output#RBuffer#.bmp"
BitmapFrames=#Tile#
MeasureName=Frame
DynamicVariables=1

[Stop]
Meter=String
MeterStyle=TextStyle | LeaveStyle
X=(#W#/2-([Stop:W]*#Buttons#+#Padding#*(#Buttons#-1))/2)r
Y=(#SW#*2+#H#)r
Text="◼"
LeftMouseUpAction=[!CommandMeasure Extract "Kill"][PlayStop][!CommandMeasure Delete "Run"]
UpdateDivider=-1
DynamicVariables=1

[Play]
Meter=String
MeterStyle=TextStyle | LeaveStyle
Text="⯈"
LeftMouseUpAction=[!CommandMeasure Extract "Run"]
UpdateDivider=-1
DynamicVariables=1
The audio playing is done using simple [Play] bangs on the 2 WAV files (one for read, one for write, alternating) created by the ffmpeg.exe command. Also, this code automatically deletes the BMP and WAV files created by the skin when the Stop "button" is clicked or when the playing ended, to create the appearance of no video loaded. If it doesn't delete the files the first time (it does rarely happen), pressing it again - optionally followed by refreshing the skin - will do it.

Added some comments to make it easier to understand which is which in the Variables section. Most of those variables will get to be calculated automatically once I grab the needed clip info using ffprobe.exe, before actually playing the clip, but for now some of them will have to be set manually. No point working for these minor things until the functionality as a whole is perfected.
User avatar
eclectic-tech
Rainmeter Sage
Posts: 4142
Joined: April 12th, 2012, 9:40 pm
Location: Cedar Point, Ohio, USA

Re: Rain Video

Post by eclectic-tech »

@Yincognito Thanks for the suggestions. I did incorporate your log creation but also experienced being unable to utilize it in real-time for the reason you mentioned. My thought was to start ffplay, start the powershell to create a log, end that ffplay, then use webparser of the log to capture duration time and default sizes. I achieved this using a third party 'sendkey' program to kill ffplay, but it is not as clean as I would like. I tried several other methods, but decided for now not to try to pull data in realtime. I do look forward to trying out your latest code with sound when I get some time, and see how it is progressing... :thumbup:

On a different note, I made a few changes to my original code:
added a 'Repeat' option
display the current filename; it could be 'pretty-fide', but for now it is the entire path
Context menu now shows current size and repeat option
Replaced LeftMouseUpAction with MouseOver/MouseLeave to activate the help toggle; the video retains focus this way

Here are a few screenshots
rainvideo2-1.jpg
rainvideo2-2.jpg
rainvideo2-3.jpg
For now, I think this is as far as I can push interfacing video in a Rainmeter skin.
This code requires FFmpeg program (in particular ffplay.exe) in "@Resources\ffmpeg" folder to work.

RainVideo V 1.2020.09.21

See first post for latest code
You do not have the required permissions to view the files attached to this post.
User avatar
Yincognito
Posts: 2760
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

Re: Rain Video

Post by Yincognito »

eclectic-tech wrote: September 21st, 2020, 11:55 pm @Yincognito Thanks for the suggestions. I did incorporate your log creation but also experienced being unable to utilize it in real-time for the reason you mentioned. My thought was to start ffplay, start the powershell to create a log, end that ffplay, then use webparser of the log to capture duration time and default sizes. I achieved this using a third party 'sendkey' program to kill ffplay, but it is not as clean as I would like. I tried several other methods, but decided for now not to try to pull data in realtime. I do look forward to trying out your latest code with sound when I get some time, and see how it is progressing... :thumbup:
Some things that should be mentioned:

- if you're talking about getting the video info before you play the video, you can use ffprobe.exe for that
- if you're talking about getting that info while you play the video, you don't have to end ffplay.exe; that executable, given the appropriate parameters, will continuously output the video stats, so no need to start and stop it over and over; actually, it's about running powershell (and the command I mentioned above) over and over, not ffplay.exe ... although, if I think about it, it may be possible to keep a powershell window open but hidden (maybe executing simply "powershell.exe" in a RunCommand measure achieves that and doesn't automatically close powershell) and then once every second, run the mentioned -command Get-Content -Path .\output.log command in that opened but hidden powershell window, so that only the command gets executed every second and not a new powershell instance every freaking time, which would be overkill. Again, I don't even know if this works, but just exploring the possibilities...

Yep, each method we use for this comes up with its own challenges, advantages and drawbacks. I for one like such challenges ... not so much the drawbacks though. :lol: Will check your updated code tomorrow.

P.S. The PowerShell command I used in the code and mentioned above actually has the ability of taking just the last N lines written in the log file, so the regex to extract the needed data from the file contents could be avoided, see more about it here. As I said, it's not about spawning ffplay.exe once every second, it's about avoiding to spawn powershell.exe every second and instead spawn just the said command (if possible, i.e. in a supposedly existing powershell hidden window).
User avatar
balala
Rainmeter Sage
Posts: 11575
Joined: October 11th, 2010, 6:27 pm
Location: Gheorgheni, Romania

Re: Rain Video

Post by balala »

eclectic-tech wrote: September 21st, 2020, 11:55 pm For now, I think this is as far as I can push interfacing video in a Rainmeter skin.
In addition would be nice to add Play / Stop / Pause (if possible) buttons to the skin, to can easier interact with it.
The Browse tool (the FileChoose plugin) is an extremely interesting plugin, which deserves all the attention. Didn't know about it until now, but it definitely is an interesting tool, even if I didn't study it so far. But I definitely will have to.
User avatar
Yincognito
Posts: 2760
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

Re: Rain Video

Post by Yincognito »

balala wrote: September 22nd, 2020, 12:20 pmThe Browse tool (the FileChoose plugin) is an extremely interesting plugin, which deserves all the attention. Didn't know about it until now, but it definitely is an interesting tool, even if I didn't study it so far. But I definitely will have to.
Agreed, me too - had no idea this plugin existed.
balala wrote: September 22nd, 2020, 12:20 pmIn addition would be nice to add Play / Stop / Pause (if possible) buttons to the skin, to can easier interact with it.
I thought about that before posting the suggestions for eclectic-tech, actually. Unfortunately this is probably going to be a bit complicated by the fact that ffplay.exe doesn't have any command line parameter that you can use to play / stop / pause, so these things would most likely have to be done by creating some AutoHotKey scripts / executables, since as far as I know (unless I'm mistaken) Rainmeter can't "simulate" a keypress due to "security" concerns...
User avatar
eclectic-tech
Rainmeter Sage
Posts: 4142
Joined: April 12th, 2012, 9:40 pm
Location: Cedar Point, Ohio, USA

Re: Rain Video

Post by eclectic-tech »

Updated Rain Video to V 1.2020.09.25

CHANGES
Added New action buttons (action when button is hovered by mouse)
Button visibility can be toggled so only the video shows
Video window can be moved while video is playing (it will remain 'unlinked' to skin position) See next change...
Added 'MiddleMouseUpAction' to refresh positioning (Do this after moving the skin window; this will realign the video window with the skin)
Added 'Refresh Position' to Context Menu
Added 'Repeat' toggle button

First post updated with preview images, links, and code