Jump to content

AutoIt 4K MPV Player


Go to solution Solved by CYCho,

Recommended Posts

Posted

Hi, it works ok so far ...

The _PlayListCreate() function should be called after the check for the libmpv-2.dll

for my local copy of the script i made this change:

If $hMPV_DLL = -1 Then
;MsgBox features: Title=Yes, Text=Yes, Buttons=Yes, No, Default Button=Second, Icon=Critical, Modality=Task Modal, Miscellaneous=Top-most attribute
$iMsgBoxAnswer = MsgBox(270596,"Error","libmpv-2.dll file cannot be loaded." & @CRLF & "Do you want to open the link to the download" & @CRLF &"page in your web browser ?"  & @CRLF &  "Download and extract the .dll from" & @crlf & "mpv-dev-x86_64-20260307-git-f9190e5.7z" & @crlf & "and copy it into the script folder" & @CRLF & "then restart this app")
    if $iMsgBoxAnswer = 6 then ;ok
        ShellExecute ("https://github.com/shinchiro/mpv-winbuild-cmake/releases")
    EndIf
    Exit
EndIf

to make it easier to get the dll file.

Some of my script sourcecode

Posted (edited)

MPV basically fills the GUI in full. The aspect ratio can be kept or ignored with one line of code:

_mpv_set_property_string($pHandle, "keepaspect", "yes") : keeps aspect ratio and fills the empty spaces with black background (Default)
_mpv_set_property_string($pHandle, "keepaspect", "no") : ignores the aspect ratio and fills the GUI with image

In my example, these options can be toggled with Ctrl+Alt+a hotkey.

Edit: This feature can now be set in the beginning of the program. Hotkey was eliminated.

Edited by CYCho
Posted (edited)

I noticed that, if the video was hidden in the background for about 30 minutes and brought back to foreground, the image was frozen, though the audio was alive all the time. Through googling, I learned that the Windows power management sometimes freezes the GPU renderer while the audio, which is controlled by CPU, continues to work. So I made a small adlib function which fires every 10 minutes and, sofar, it seems to work.

Func _RefreshVideo()    ; Adlib to update the renderer with a harmless "seek" function every 10 minutes
    _mpv_command($pHandle, "seek", 0, "relative")
EndFunc

The file in the first post was updated.

Edit: The above workaround was not enough in both action and frequency. It still resulted in random freezes of video. Hopefully the following code would solve the problem.
 

Func _RefreshVideo()    ; Adlib to give a heartbeat to the renderer every 5 minutes
    ; Check if the center of the video window is not visible on the screen
    ; Position of video window ($aPos) is updated by WM_WINDOWPOSCHANGED in real time
    Local $tPoint = _WinAPI_CreatePoint($aPos[0]+$aPos[2]/2, $aPos[1]+$aPos[3]/2)
    Local $hTopWnd = _WinAPI_WindowFromPoint($tPoint)
    If $hTopWnd = $hVideoGUI Then Return    ; Return if visible

    _mpv_command($pHandle, "add", "ao-volume", "-" & $iVolume)
    _mpv_command($pHandle, "seek", 1, "relative")
    Sleep(10)
   _mpv_command($pHandle, "seek", -1, "relative")
   _mpv_command($pHandle, "add", "ao-volume", $iVolume)
EndFunc     ; _RefreshVideo

The revised code is in the first post above.

Edited by CYCho
Posted (edited)
3 hours ago, bladem2003 said:

For me, minimized for 45 minutes and didn't freeze.

Thanks for your attention. It seems the freezing can be a random behaviour mainly depending on the computer and file specs. I have a 10-year old computer and I would think I should make it work at least on my computer. MPV offers so many options and I'm sure we can fix it. One problem is that one round of test takes at least an hour.

Edited by CYCho
  • Solution
Posted (edited)

Through tests with many different options set, I could shorten the "seek" time to 0.5 seconds, which is so small that we don't need to worry about the audio interruption. It would be greatly appreciated if you could let me know if there were a less intrusive way to get the desired result.
 

Func _RefreshVideo()    ; Adlib to give a heartbeat to the video renderer every 5 minutes
    ; Check if the center of the video window is visible on the screen
    ; Position of video window ($aPos) is updated by WM_WINDOWPOSCHANGED in real time
    Local $tPoint = _WinAPI_CreatePoint($aPos[0]+$aPos[2]/2, $aPos[1]+$aPos[3]/2)
    Local $hTopWnd = _WinAPI_WindowFromPoint($tPoint)
    If $hTopWnd = $hVideoGUI Then Return    ; Return if visible

    _mpv_command($pHandle, "seek", 0.05, "relative")
    _mpv_command($pHandle, "seek", -0.05, "relative")
    ; Please let me know if anyone knows of a less intrusive way to keep the video renderer alive
EndFunc     ; _RefreshVideo

I also found that some of the options I set for video performance prevented low-spec computers from playing even a low-resolution video. So I added a function to check if the computer has GPU card with 2GB or more of RAM, and provided different sets of options depending on the result.
 

Local $sSpec = _GetVideoCardSpec()
If $sSpec = "low" Then
  _mpv_set_option_string($pHandle, "profile", "fast")
  _mpv_set_option_string($pHandle, "vo", "direct3d")
  _mpv_set_option_string($pHandle, "dither", "no")
  _mpv_set_option_string($pHandle, "framedrop", "vo")
Else
  _mpv_set_option_string($pHandle, "profile", "gpu-hq")
  _mpv_set_option_string($pHandle, "vo", "gpu")
EndIf

This way, I could play low-resolution videos with a 10 year old laptop without a GPU. It could even play a 4K video, but the video rendering quality was not satisfactory.

The updated code is uploaded in the first post above.

Edited by CYCho
Posted (edited)

Three features were added in the latest file (AutoIt_4K_MPV_Player(20260327).au3):

1. Playback speed can now be adjusted in 0.1x increment by Ctrl+Alt+[ or Ctrl+Alt+] hotleys. It can be reset to default 1.0x by Ctrl+Alt+{backspace] hotkey.
2. The video can be paused/resumed by a single click on the image.
3. The full screen mode can be turned on/off by doubleclicking on the image or pressing F11 key. The full screen mode can be turned off also by pressing Esc key.

Edited by CYCho
Posted (edited)

A small improvement suggestion.

Put wait for the file to load into a while loop with a maximum timeout of, say, 10 seconds. Files loaded from the internet or local network often take longer than 200ms.

_mpv_get_property($pHandle, "idle-active")` returns "no" if mpv is still loading and "yes" if it's in idle mode. This could be used to handle loading errors.

 

 

Func _PlayFile()    ; Invoked by the main loop when the player is in idle state
    _mpv_set_property($pHandle, "speed", 1.0, "double")
    _mpv_command($pHandle, "loadfile", $sFolder & $aPlaylist[$iIndex])
    ;Sleep(100) ; <-- This is not needed

    ;----------------------------------------------------------------------------------------------------------------------------------------------
    Local $TimerWaitStart = TimerInit()
    While 1
        If TimerDiff($TimerWaitStart) > 10000 Then ExitLoop  ; wait 10 sec max to load. internet streams often take longer to load than 200ms
        If _mpv_get_property($pHandle, "idle-active") = "yes" Then ExitLoop  ; if no file loaded = error
        $iAspect = Number(_mpv_get_property($pHandle, "video-params/aspect"))
        If $iAspect > 0 Then ExitLoop
        Sleep(50)
    WEnd
    ;-----------------------------------------------------------------------------------------------------------------------------------------------


    If $iAspect > 0 Then
;~      If $sKeepAspect = "yes" Then
;~          _mpv_set_property($pHandle, "keepaspect", "yes", "string")
;~      Else
;~          _mpv_set_property($pHandle, "keepaspect", "no", "string")
;~      EndIf
        $iVideoWidth = _mpv_get_property($pHandle, "width", "double")
        $iVideoHeight = _mpv_get_property($pHandle, "height", "double")
        $iVideoWidth = Int($iClientWidth * 2 / 3)
        $iVideoHeight = Int($iVideoWidth / $iAspect)
        If $iVideoHeight > $iClientHeight - $iTitleHeight Then
            $iVideoHeight = $iClientHeight - $iTitleHeight
            $iVideoWidth = Int($iVideoHeight * $iAspect)
        EndIf
        Local $x = ($iClientWidth - $iVideoWidth - $iBorderWidth * 2) / 2, $y = ($iClientHeight - $iVideoHeight - $iTitleHeight - $iBorderWidth) / 2
        Local $w = $iVideoWidth + $iBorderWidth * 2, $h = $iVideoHeight + $iTitleHeight + $iBorderWidth
        WinMove($hVideoGUI, "", $x, $y, $w, $h)
        GUISetState(@SW_SHOW, $hVideoGUI)
        GUIDelete($hVCGui)
        _VCCreate()
        ;       _VCResize()
    Else
        MsgBox(1, "Error", $aPlaylist[$iIndex] & @CRLF & "This file cannot be loaded.")
        _Exit()
    EndIf

    $iMediaLength = Int(_mpv_get_property($pHandle, "duration"))
    GUICtrlSetData($idLength2, _SecondsToTime($iMediaLength))
    AdlibRegister("_VCShow")
    AdlibRegister("_Progress")
    AdlibRegister("_HotkeySet", 990)
    AdlibRegister("_VideoRefresh", 300000)
    WinSetTitle($hVideoGUI, "", "AutoIt 4K MPV Player - " & $aPlaylist[$iIndex])
EndFunc   ;==>_PlayFile

 

Edited by bladem2003

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...