Jump to content

zPlayer - My own little audio/video player


CYCho
 Share

Go to solution Solved by TheXman,

Recommended Posts

I have uploaded the latest version of WINMM.DLL-based media player in my first post and I think I personally prefer this one to zPlayer. It is really simple but has most of the functions zPlayer has. At least this one is better than zPlayer in transition of video when moving to a new file or toggling between pause and play. Any suggestion for improvement would be most welcome.

Link to comment
Share on other sites

It seems that I cannot turn a video window to fullscreen mode in winmm.dll. The best I can do is to maximize the video with WinSetState($hVideo, "", @SW_MAXIMIZE), command. This fills up the entire client area of the Windows, with the task bar and title bar still showing. Moreover, the source aspect ratio is ignored in the maximized state. Any suggestion on how to get a proper fullscreen mode would be greatly appreciated.

Edited by CYCho
Link to comment
Share on other sites

7 hours ago, ioa747 said:

check if this help

Thanks for your attention. I applied your code snippet to my project, but it didn't do the trick. The problem is the video window is created by winmm.dll, not by me, and GUI... commands do not seem to have any effect on a third-party window. WinMove() command is effective on the video window, but there is no Win... command to change the style of a third-party window. I tried to direct the video to my own GUI, but then, the video could not be stretched.

Thanks again!

Link to comment
Share on other sites

  • Solution
21 hours ago, CYCho said:

It seems that I cannot turn a video window to fullscreen mode in winmm.dll....Any suggestion on how to get a proper fullscreen mode would be greatly appreciated.

I'm not sure if this is still an issue for you, but if it is, then I have found that the following works for me on Windows 7 & 10.  I haven't tested it on any other OS versions.

As you can see on the MCI Play command page, you can use the "fullscreen" flag to play compressed video in fullscreen mode.  When I added the flag to the "play" command, my video was played in fullscreen and stretched to the appropriate dimensions.

I just changed the line that initiates the playing of the video from ...

mciSendString("play myMedia")

TO

mciSendString("play myMedia fullscreen")

Hopefully, it works for you too. 

 

P.S.

To toggle between fullscreen and normal, you should be able to just reissue the play command with appropriate "from" position, with or without the "fullscreen" flag, as needed.

 

Edited by TheXman
Link to comment
Share on other sites

6 hours ago, TheXman said:

you can use the "fullscreen" flag to play compressed video in fullscreen mode

Thanks for your response. I feel like I'm a blind man touching an elephant. I read about fullscreen mode and I tried and failed. I didn't understand what the compressed video meant. I even "compressed" an mp4 file at a website from 3324KB to 1732KB, but it didn't work. I use about 20 different video files to test my project in mp4, webm and flv formats, Big_Buck_Bunny.webM being my favorite. Upon reading your suggestion, I just tested the code with an mp4 file I never used before, and it did play in fullscreen mode. I tested some of my other files including mkv and avi files and they also played in full screen mode. I have been testing with wrong files all the time. The problem is I still don't know how to differentiate a "compressed" file from non-compressed. I hope I can differentiate them by a file property value.

I will consider my problem solved, though. Thanks again.

Edited by CYCho
Link to comment
Share on other sites

On 4/15/2023 at 2:06 PM, CYCho said:

I hope I can differentiate them by a file property value.

I could not find any file property value significantly different between the files that stretch to fullscreen well and the files that randomly fail to stretch.  For those that fail, I had to issue "fullscreen" command more than once to make it fullscreen. I have uploaded the latest version of winmm.dll-based media player in the first post.

Edit: I must say it was a discovery. Some video files don't play in fullscreen mode from the start even though I send "play myMedia fullscreen". After many trials and errors I found the following code doing the trick. The fullscreen command should be preceded by a normal play command. Unless I add "from 0" in the fullscreen command, a file will always be played from about 15 seconds from the starting position. I don't know why, but this code works.

I uploadded the latest version of my WINMM.DLL Media Player as an independent example code.
 

mciSendString("play myMedia")
mciSendString("play myMedia fullscreen from 0")

 

Edited by CYCho
Link to comment
Share on other sites

I uploaded version 5.0.0.0 of zPlayer in the download section of this forum.

I went back to WMPlayer.OCX embedded in IE. I compared 3 different options for playing digital media files which I could use for my media player. The first option was Windows Media Player(WMP) embedded in IE, which was used in versions 2 and 3 of zPlayer. The 2nd option was WMP object linked with ObjCreateInterface function to enable resizing of video without an IE. This option seemed attractive when there were fears of IE being dropped from Windows anytime soon. I adopted this option in version 4 of zPlayer. The 3rd option was winmm.dll, a Windows multimedia library for general programming purpose. I made a bare-bone media player with this method and uploaded it in AutoIt Example Scripts forum. All 3 options showed very similar funtionalities for playback of audio files, but they were significantly different from each other in playback of video files, especially as regards to resizing and fullscreen mode, and the first option, IE-embedded WMP, was by far the best option. Compared to the first option, the 2nd option showed unsatifactory performance in transition of video frames between pause and play. The 3rd option showed poor perforamnce in transition to fullscreen mode. And the fullscreen mode did not have a built-in video control and did not allow me to overlay my own video control on the screen. In the meantime I upgraded my OS to Windows 11 and, unlike my worries, I had no problem in running IE-embedded WMP object and it became clear that Windows will support IE untill the end of 2029. So I decided to go back to IE-embedded WMP. By the end of 2029, I hope a new method will be available which is comparable to, or better than, IE-embedded WMP.

Link to comment
Share on other sites

  • 2 months later...

The latest version did away with IE_embedded WMP and used winmm.dll instead.  Winmm.dll allows much more flexibility in resizing the video, including maximizing and stretching to fullscreen. Please visit here for the latest version.

Edited by CYCho
Link to comment
Share on other sites

  • 3 weeks later...

I found that the lengths of some media files varied depending on which method I used to get them. In my zPlayer I use 2 methods: Shell.Aplication object and "status MyMedia length" command string with winmm.dll. I would accept a difference of a couple of seconds, but not several tens of seconds. Sometimes, one was more than two times of the other. Almost always, winmm.dll method produced longer length than shell application method and the length obtained by winmm.dll method was wrong.  I don't know where this difference comes from, but my understanding is that these files have meta data messed up somewhere. Always I could eliminate the difference by replacing the media file with a new one. If you want to check if your files are OK, you can use the following code:
 

#include <File.au3>
#include <Array.au3>

$sFileTypes = "*.mp3;*.wma;*.asf;*.ogg;*.ape;*.flac;*.mp4;*.wmv;*.avi;*.mkv;*.flv;*.webM"
$sFolder = "D:\Video"
$aFiles = _FileListToArrayRec($sFolder, $sFileTypes, 1, 1, 1, 1)
;   _ArrayDisplay($aFiles)

$hDLL = DllOpen("winmm.dll")
$oShellApp = ObjCreate("Shell.Application")
$iGetDetailsOf = 27 ; 27 is for Windows 10 and 11. Other OS versions may have different column number.

For $i = 1 To $aFiles[0]
    $sFile = $sFolder & "\" & $aFiles[$i]

    $sFileName = StringMid($sFile, StringInStr($sFile, "\", 0, -1)+1)
    $sDir = StringLeft($sFile, StringInStr($sFile, "\", 0, -1))
    $oDir = $oShellApp.NameSpace($sDir)
    $oFile = $oDir.Parsename($sFileName)
    $Length1 = $oDir.GetDetailsOf($oFile, $iGetDetailsOf)
    $Length1 = StringLeft($Length1,2)*3600+StringMid($Length1, 4, 2)*60+StringRight($Length1,2)

    mciSendString("open """ & $sFile & """ alias myMedia1 type MPEGVideo")
    mciSendString("set myMedia1 time format milliseconds")
    $Length2 = mciSendString("status myMedia1 length")
    mciSendString("close myMedia1")
    $Length2 = Int($Length2/1000)

    If Abs($Length1-$Length2) >= 5 Then
        ConsoleWrite($sFile & @TAB & $Length1 & @TAB & $Length2 & @CRLF)
;       FileDelete($sFile)
    EndIf
Next
DllClose($hDLL)

Func mciSendString($string)
    Local $aRet = DllCall($hDLL, "int", "mciSendStringW", "wstr", $string, "wstr", "", "int", 65534, "hwnd", 0)
    If Not @error Then Return $aRet[2]
EndFunc

 

Link to comment
Share on other sites

  • 2 weeks later...

Multi-File Repeat Function

One of my favorite music folders holds 539 classical titles. While listening to this folder, sometimes I feel like repeating several files, Beethoven's Symphony 9, movements 1 to 4, for example. zPlayer Version 6.0.0.7 makes this possible. One of the challenges I encountered in this version was coloring the selected items in the playlist.

The easiest way was using GUICtrlSetColor() or GUICtrlSetBkColor() function, but they had flickering problem: a colored playlist would randomly flicker, whch was pretty much annoying. I wanted to realize the function wihtout using a UDF which is not a part of standard AutoIt installation. So GUIListViewEx.au3 was out of my consideration. Then I found a solution here, @LarsJ's, so called, virtual listview. It perfectly fit my requirement and it worked great. Loading speed was far faster than _GUICtrlListView_AddArray() and flickering diappeared.

Please take a look at what I have done in zPlayer Version 6.0.0.7.

Note: Virtual listview was not that simple. I had to make several changes to my code to work correctly with virtual listview, and I assigned a new version number of 6.0.0.8. - September 12, 2023

Edited by CYCho
Link to comment
Share on other sites

  • 2 weeks later...

What happens when I choose a folder that contains media files not only in the folder itself but also in its subfolders? In the past, zPlayer had no option but to include all files from both the main and subfolders. However, with version 6.0.0.9, it informs me about the number of files present and provides an option to either include or exclude files from the subfolders. Also implemented in version 6.0.0.9 is the display of current file name in the tooltip of zPlayer icon on Windows taskbar. To ensure this feature works properly, all additional GUIs had to be created as a child of the main GUI. This change had an unexpected advantage: all open GUIs can be hidden or displayed by just one click on the icon in the taskbar.

Link to comment
Share on other sites

Up untill recently I didn't worry about zPlayer.exe being incorrectly detected as a malware, because it never happened during the last couple of years. But just recently I found that versin 10.0.9 and 1.0.1.0 were falsely flagged by Windows Defender.

I found the reason and changed the code.  Version 6.0.1.1 is not flagged by Windows Defender with latest update. Please see here for details.

Edited by CYCho
Link to comment
Share on other sites

  • 2 weeks later...

According to my limited experience under Win 11, winmm.dll can intrinsically play back mp3, wma, wav, asf, avi and wmv files, and additional codecs are required to play back other popular file types such as flac, ogg, mp4, mkv, flv and webm.

Edited by CYCho
Link to comment
Share on other sites

  • 1 month later...

When all the GUI's are hidden or minimized, how can I see the file name of the media currently playing? If I put the file name in the title of main GUI, I can see it by moving the mouse to zPlayer icon in the Windows Taskbar. If properly set in the Windows Settings, the taskbar icon will show the title in a tooltip. In order not to innundate the GUI's visible tititle box, I put @CRLF betwwen the default title("zPlayer by C. Y. Cho") and the filename.
 

zPlayer6-Taskbar.png

Edited by CYCho
Link to comment
Share on other sites

  • 1 month later...
Posted (edited)

I aksed this question to Windows Copilot:

I use GetDetailsOf() method of Shell.Application to obtain  file properties. It usually takes less than 1.5 seconds to get all the properties for most of file types including mkv. But a 2-hour long mp4 file takes around 25 seconds, which is way too long compared to other file types. What is the reason behind this long time? Is there a faster way to handle an mp4 file?

Copilot answered:

The GetDetailsOf() method of Shell.Application is a COM interface that is part of the Windows Shell1. It retrieves the details of shell items, which includes file properties2. The time it takes to retrieve these properties can vary depending on the file type and the amount of metadata associated with it.

MP4 files, in particular, can contain a large amount of metadata, including video and audio stream information, subtitles, and even chapter markers. This metadata is embedded within the file itself, and extracting it can be a time-consuming process, especially for larger files. This could explain why GetDetailsOf() takes longer to retrieve properties for MP4 files compared to other file types.

As for a faster way to handle MP4 files, you might consider using a dedicated media handling library or tool. For example, MediaTab is a third-party application that exposes all possible details about media files in their Properties3. Another option is to use a scripting language like Python with a library such as MKVtoolnix and Kid3-cli, which can handle metadata more efficiently4. These tools are designed to handle media files and may offer better performance compared to the general-purpose GetDetailsOf() method. Please note that these are third-party tools, and you should review their documentation and ensure they meet your needs before using them.

Any suggestion to solve this problem without a 3rd party library?

Edited by CYCho
Link to comment
Share on other sites

2 hours ago, argumentum said:

can you copy just the first X bytes to a temp file and read that ?. If is just header/metadata, it should be enough, I guess ?

A good idea, but with a little twist. I had to save the metadata in a file with .mkv extension, otherwise it took about the same time as the original file. So what I suspect is all that matters with speed of GetDetailsOf() may be the file extensions.  If I change the extension of original mp4 file to mkv, the problem is solved. And it even plays well under WMP, VLC and my zPlayer, even though I hesitate to do that.
 

#include <Array.au3>
#include <File.au3>

$hh = TimerInit()

$sFile = "E:\Movies\Die Hard 1990 1080p.mp4"
$hFile = FileOpen($sFile, 16)
$sHeader = FileRead($hFile, 3000000)
FileClose($hFile)
$sPath = @ScriptDir & "\Temp.mkv"
$hFile = FileOpen($sPath, 2+16)
FileWrite($hFile, $sHeader)
FileClose($hFile)

;~ $sPath = "E:\Movies\Die Hard 1988.1080p.BluRay.x264-ELK.mkv"

$aFileInfo = ""
_FileProperties()

ConsoleWrite(TimerDiff($hh) & @CRLF)

_ArrayDisplay($aFileInfo)


Func _FileProperties()
    $oShellApp = ObjCreate("shell.application")
    Local $sFileName, $sDir, $oDir, $oFile, $sPropertyName, $sPropertyValue
    $sFileName = StringMid($sPath, StringInStr($sPath, "\", 0, -1)+1)
    $sDir = StringLeft($sPath, StringInStr($sPath, "\", 0, -1))
    $oDir = $oShellApp.NameSpace($sDir)
    $oFile = $oDir.Parsename($sFileName)
    Dim $aFileInfo [1][2]
    $aFileInfo[0][0] = $oDir.GetDetailsOf("", 0)
    $aFileInfo[0][1] = $oDir.GetDetailsOf($oFile, 0)
    For $i = 1 To 320
        $sPropertyName = $oDir.GetDetailsOf("", $i)
        If $sPropertyName <> "" Then
            $sPropertyValue = $oDir.GetDetailsOf($oFile, $i)
            If $sPropertyValue <> "" Then
                _ArrayAdd($aFileInfo, $sPropertyName & "|" & $sPropertyValue)
            EndIf
        EndIf
    Next
EndFunc     ;==>_FileProperties

 

Link to comment
Share on other sites

This is quite strange.  I don't understand why changing extension of a file would suddenly make its properties management faster.  You do not convert the file, you just rename its extension.  I tested on my side multiple mp4 files (longest was about 1hr) and they were all processed instantly.

Did you try on another computer ?  I suspect that maybe some other program is interfering (AV ?)...

Link to comment
Share on other sites

7 hours ago, CYCho said:

So what I suspect is all that matters with speed of GetDetailsOf() may be the file extensions.

Each file extension has a declared handler. And even if the same handler, the dll that works on each may be different. It's probable ( in my mind ) that the handler/dll for MKV is better than the MP4 one.

Edited by argumentum
spelling

Follow the link to my code contribution ( and other things too ).
FAQ - Please Read Before Posting.
autoit_scripter_blue_userbar.png

Link to comment
Share on other sites

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
 Share

×
×
  • Create New...