AutoHotkey: Get Media Information and Display

Applies To:
  • Microsoft Windows 7 Professional v6.1.7601 32-bit
  • AutoHotkey v1.1.33.02

What?
This is a copied article just to store a permanent reference for if I ever need to build an app similar to the file explorer in the Microsoft Windows OS.

Why?
I had an app for use in MS Windows 7 to display the properties of sound files though this is also applicable to media files in general.

Windows File Explorer: Audio File Windows File Explorer: Video File

How?
So first I'm going to list a function I use called "Filexpro()", then list some examples of usage. And in the second-to-last section, I'll quickly convert a 100 nanoseconds unit to display Hours : Minutes : Seconds.

We could have tried out some cool new DLL files for MS Windows 10 but we needed something lightweight that doesn't require any extra files and that could work on MS Windows 7 (32-bit) for this particular app. For this reason, we are going to use a function by Skan called Filexpro() which is copied in the below:
copyraw
Filexpro( sFile := "", Kind := "", P* ) {           ; v.90 By SKAN on D1CC @ goo.gl/jyXFo9
    Local
    Static xDetails
    If ( sFile = "" )
    {                                                           ;   Deinit static variable
        xDetails := ""
        Return
    }
    fex := {}, _FileExt := ""
    Loop, Files, % RTrim(sfile,"\*/."), DF
    {
        If not FileExist( sFile:=A_LoopFileLongPath )
        {
            Return
        }
        SplitPath, sFile, _FileExt, _Dir, _Ext, _File, _Drv
        If ( p[p.length()] = "xInfo" )                          ;  Last parameter is xInfo
        {
            p.Pop()                                           ;         Delete parameter
            fex.SetCapacity(11)                               ; Make room for Extra info
            fex["_Attrib"]    := A_LoopFileAttrib
            fex["_Dir"]       := _Dir
            fex["_Drv"]       := _Drv
            fex["_Ext"]       := _Ext
            fex["_File"]      := _File
            fex["_File.Ext"]  := _FileExt
            fex["_FilePath"]  := sFile
            fex["_FileSize"]  := A_LoopFileSize
            fex["_FileTimeA"] := A_LoopFileTimeAccessed
            fex["_FileTimeC"] := A_LoopFileTimeCreated
            fex["_FileTimeM"] := A_LoopFileTimeModified
        }
        Break
    }
    If Not ( _FileExt )                                   ;    Filepath not resolved
    {
        Return
    }
    objShl := ComObjCreate("Shell.Application")
    objDir := objShl.NameSpace(_Dir)
    objItm := objDir.ParseName(_FileExt)
    If ( VarSetCapacity(xDetails) = 0 )                           ;     Init static variable
    {
        i:=-1,  xDetails:={},  xDetails.SetCapacity(309)
        While ( i++ < 309 )
        {
            xDetails[ objDir.GetDetailsOf(0,i) ] := i
        }
        xDetails.Delete("")
    }
    If ( Kind and Kind <> objDir.GetDetailsOf(objItm,11) )        ;  File isn't desired kind
    {
        Return
    }
    i:=0,  nParams:=p.Count(),  fex.SetCapacity(nParams + 11)
    While ( i++ < nParams )
    {
        Prop := p[i]
        If ( (Dot:=InStr(Prop,".")) and (Prop:=(Dot=1 ? "System":"") . Prop) )
        {
            fex[Prop] := objItm.ExtendedProperty(Prop)
            Continue
        }
        If ( PropNum := xDetails[Prop] ) > -1
        {
            fex[Prop] := ObjDir.GetDetailsOf(objItm,PropNum)
            Continue
        }
    }
    fex.SetCapacity(-1)
    Return fex
}
  1.  Filexpro( sFile :"", Kind :"", P* ) {           ; v.90 By SKAN on D1CC @ goo.gl/jyXFo9 
  2.      Local 
  3.      Static xDetails 
  4.      If ( sFile = "" ) 
  5.      {                                                           ;   Deinit static variable 
  6.          xDetails :"" 
  7.          Return 
  8.      } 
  9.      fex :{}, _FileExt :"" 
  10.      Loop, Files, % RTrim(sfile,"\*/."), DF 
  11.      { 
  12.          If not FileExist( sFile:=A_LoopFileLongPath ) 
  13.          { 
  14.              Return 
  15.          } 
  16.          SplitPath, sFile, _FileExt, _Dir, _Ext, _File, _Drv 
  17.          If ( p[p.length()] = "xInfo" )                          ;  Last parameter is xInfo 
  18.          { 
  19.              p.Pop()                                           ;         Delete parameter 
  20.              fex.SetCapacity(11)                               ; Make room for Extra info 
  21.              fex["_Attrib"]    := A_LoopFileAttrib 
  22.              fex["_Dir"]       := _Dir 
  23.              fex["_Drv"]       := _Drv 
  24.              fex["_Ext"]       := _Ext 
  25.              fex["_File"]      := _File 
  26.              fex["_File.Ext"]  := _FileExt 
  27.              fex["_FilePath"]  := sFile 
  28.              fex["_FileSize"]  := A_LoopFileSize 
  29.              fex["_FileTimeA"] := A_LoopFileTimeAccessed 
  30.              fex["_FileTimeC"] := A_LoopFileTimeCreated 
  31.              fex["_FileTimeM"] := A_LoopFileTimeModified 
  32.          } 
  33.          Break 
  34.      } 
  35.      If Not ( _FileExt )                                   ;    Filepath not resolved 
  36.      { 
  37.          Return 
  38.      } 
  39.      objShl :ComObjCreate("Shell.Application") 
  40.      objDir := objShl.NameSpace(_Dir) 
  41.      objItm := objDir.ParseName(_FileExt) 
  42.      If ( VarSetCapacity(xDetails) = 0 )                           ;     Init static variable 
  43.      { 
  44.          i:=-1,  xDetails:={},  xDetails.SetCapacity(309) 
  45.          While ( i++ < 309 ) 
  46.          { 
  47.              xDetails[ objDir.GetDetailsOf(0,i) ] := i 
  48.          } 
  49.          xDetails.Delete("") 
  50.      } 
  51.      If ( Kind and Kind <> objDir.GetDetailsOf(objItm,11) )        ;  File isn't desired kind 
  52.      { 
  53.          Return 
  54.      } 
  55.      i:=0,  nParams:=p.Count(),  fex.SetCapacity(nParams + 11) 
  56.      While ( i++ < nParams ) 
  57.      { 
  58.          Prop := p[i] 
  59.          If ( (Dot:=InStr(Prop,".")) and (Prop:=(Dot=1 ? "System":"") . Prop) ) 
  60.          { 
  61.              fex[Prop] := objItm.ExtendedProperty(Prop) 
  62.              Continue 
  63.          } 
  64.          If ( PropNum := xDetails[Prop] ) > -1 
  65.          { 
  66.              fex[Prop] := ObjDir.GetDetailsOf(objItm,PropNum) 
  67.              Continue 
  68.          } 
  69.      } 
  70.      fex.SetCapacity(-1) 
  71.      Return fex 
  72.  } 

Usage
copyraw
v_MyMediaFile := "C:\Users\Public\Music\Sample Music\Maid with the Flaxen Hair.mp3"
a_MediaObject := Filexpro( v_MyMediaFile,, "System.Media.Duration"
                                        , "System.Audio.ChannelCount"
                                        , "System.Audio.Compression"
                                        , "System.Audio.EncodingBitrate"
                                        , "System.Audio.Format"
                                        , "System.Audio.IsVariableBitRate"
                                        , "System.Audio.PeakValue"
                                        , "System.Audio.SampleRate"
                                        , "System.Audio.SampleSize"
                                        , "System.Audio.StreamName"
                                        , "System.Audio.StreamNumber" )

v_MyMediaFile := "C:\Users\Public\Videos\Sample Videos\Wildlife.wmv"
a_MediaObject := Filexpro( v_MyMediaFile,, "System.Media.Duration"
                                        , "System.Media.FrameCount"
                                        , "System.Video.EncodingBitrate"
                                        , "System.Video.Format"
                                        , "System.Video.FrameHeight"
                                        , "System.Video.FrameRate"
                                        , "System.Video.FrameWidth"
                                        , "System.Video.HorizontalAspectRatio"
                                        , "System.Video.Orientation"
                                        , "System.Video.VerticalAspectRatio" )

MsgBox % a_MediaObject["System.Media.Duration"]
// note this returns in 100ns units (= 100 nanoseconds) as per Microsoft Docs.
  1.  v_MyMediaFile :"C:\Users\Public\Music\Sample Music\Maid with the Flaxen Hair.mp3" 
  2.  a_MediaObject :Filexpro( v_MyMediaFile,, "System.Media.Duration" 
  3.                                          , "System.Audio.ChannelCount" 
  4.                                          , "System.Audio.Compression" 
  5.                                          , "System.Audio.EncodingBitrate" 
  6.                                          , "System.Audio.Format" 
  7.                                          , "System.Audio.IsVariableBitRate" 
  8.                                          , "System.Audio.PeakValue" 
  9.                                          , "System.Audio.SampleRate" 
  10.                                          , "System.Audio.SampleSize" 
  11.                                          , "System.Audio.StreamName" 
  12.                                          , "System.Audio.StreamNumber" ) 
  13.   
  14.  v_MyMediaFile :"C:\Users\Public\Videos\Sample Videos\Wildlife.wmv" 
  15.  a_MediaObject :Filexpro( v_MyMediaFile,, "System.Media.Duration" 
  16.                                          , "System.Media.FrameCount" 
  17.                                          , "System.Video.EncodingBitrate" 
  18.                                          , "System.Video.Format" 
  19.                                          , "System.Video.FrameHeight" 
  20.                                          , "System.Video.FrameRate" 
  21.                                          , "System.Video.FrameWidth" 
  22.                                          , "System.Video.HorizontalAspectRatio" 
  23.                                          , "System.Video.Orientation" 
  24.                                          , "System.Video.VerticalAspectRatio" ) 
  25.   
  26.  MsgBox % a_MediaObject["System.Media.Duration"] 
  27.  // note this returns in 100ns units (= 100 nanoseconds) as per Microsoft Docs. 

100ns Units
So the following snippet of code will convert your 100ns units to a displayable Hours : Minutes : Seconds format which is more user-friendly:
copyraw
; Function: Convert100nsToHMS: Convert MS 100 nanoseconds to Hours Minutes Seconds for display
Convert100nsToHMS( v_100NsUnits )
{
    v_NanoSeconds100    := v_100NsUnits * 1
    v_MicroSeconds      := Floor( v_NanoSeconds100 / 10)
    v_MilliSeconds      := Floor( v_MicroSeconds / 1000)
    v_Seconds           := Floor( v_MilliSeconds / 1000)

    v_CalcHours         := Floor( v_Seconds / 3600 )
    v_CalcMinutes1      := v_Seconds / 60
    v_CalcMinutes2      := Mod( v_CalcMinutes1, 60 )
    v_CalcMinutes       := Floor( v_CalcMinutes2 )
    v_CalcSeconds       := Mod( v_Seconds, 60)

    v_DispHours         := SubStr("0" . v_CalcHours, -1)
    v_DispMinutes       := SubStr("0" . v_CalcMinutes, -1)
    v_DispSeconds       := SubStr("0" . v_CalcSeconds, -1)

    v_DispHMS           := v_DispHours ":" v_DispMinutes ":" v_DispSeconds

    Return v_DispHMS
}

; ------------- Usage -------------
v_My100NsUnits  := 9858250000
v_DisplayHMS    := Convert100nsToHMS( v_My100NsUnits )

; yields 00:16:25
  1.  ; Function: Convert100nsToHMS: Convert MS 100 nanoseconds to Hours Minutes Seconds for display 
  2.  Convert100nsToHMS( v_100NsUnits ) 
  3.  { 
  4.      v_NanoSeconds100    := v_100NsUnits * 1 
  5.      v_MicroSeconds      :Floor( v_NanoSeconds100 / 10) 
  6.      v_MilliSeconds      :Floor( v_MicroSeconds / 1000) 
  7.      v_Seconds           :Floor( v_MilliSeconds / 1000) 
  8.   
  9.      v_CalcHours         :Floor( v_Seconds / 3600 ) 
  10.      v_CalcMinutes1      := v_Seconds / 60 
  11.      v_CalcMinutes2      :Mod( v_CalcMinutes1, 60 ) 
  12.      v_CalcMinutes       :Floor( v_CalcMinutes2 ) 
  13.      v_CalcSeconds       :Mod( v_Seconds, 60) 
  14.   
  15.      v_DispHours         :SubStr("0" . v_CalcHours, -1) 
  16.      v_DispMinutes       :SubStr("0" . v_CalcMinutes, -1) 
  17.      v_DispSeconds       :SubStr("0" . v_CalcSeconds, -1) 
  18.   
  19.      v_DispHMS           := v_DispHours ":" v_DispMinutes ":" v_DispSeconds 
  20.   
  21.      Return v_DispHMS 
  22.  } 
  23.   
  24.  ; ------------- Usage ------------- 
  25.  v_My100NsUnits  :9858250000 
  26.  v_DisplayHMS    :Convert100nsToHMS( v_My100NsUnits ) 
  27.   
  28.  ; yields 00:16:25 

Source(s):
Category: AutoHotkey :: Article: 726

Credit where Credit is Due:


Feel free to copy, redistribute and share this information. All that we ask is that you attribute credit and possibly even a link back to this website as it really helps in our search engine rankings.

Disclaimer: Please note that the information provided on this website is intended for informational purposes only and does not represent a warranty. The opinions expressed are those of the author only. We recommend testing any solutions in a development environment before implementing them in production. The articles are based on our good faith efforts and were current at the time of writing, reflecting our practical experience in a commercial setting.

Thank you for visiting and, as always, we hope this website was of some use to you!

Kind Regards,

Joel Lipman
www.joellipman.com

Related Articles

Joes Revolver Map

Accreditation

Badge - Certified Zoho Creator Associate
Badge - Certified Zoho Creator Associate

Donate & Support

If you like my content, and would like to support this sharing site, feel free to donate using a method below:

Paypal:
Donate to Joel Lipman via PayPal

Bitcoin:
Donate to Joel Lipman with Bitcoin bc1qf6elrdxc968h0k673l2djc9wrpazhqtxw8qqp4

Ethereum:
Donate to Joel Lipman with Ethereum 0xb038962F3809b425D661EF5D22294Cf45E02FebF
© 2024 Joel Lipman .com. All Rights Reserved.