; sort mp3 files into folders based on bitrate and if they are VBR or not
; AutoHotkey script
; by nod5
; 2020-05-14
; ---------------------------------------
; folder with mp3 files that we want to sort move
sourcefolder := "C:\some\folder"
; also recurse in sourcefolder? 1 means yes, 0 means no
recurse := 1
; target folder where we want the files to end up in subfolders
; for example VBR files go to \VBR subfolder, 128kbs CBR files got to \128 subfolder
destinationfolder := "D:\this other\location"
; ---------------------------------------
; disable recurse if in/out folders are same, to avoid endless loop
if (sourcefolder = destinationfolder)
recurse := 0
; recursively loop sourcefolder for mp3 files and move to a destinationfolder subfolder
Loop, Files
, % sourcefolder
"\*.mp3", % recurse ?
"R" :
"" {
; get audio properties as object
; we need these two properties:
; System.Audio.EncodingBitrate examples: 128000 (which is 128kbs), 320000, 263704, ...
; System.Audio.IsVariableBitRate value -1 if VBR otherwise value 0
Props := ["System.Audio.IsVariableBitRate", "System.Audio.EncodingBitrate"]
obj := Filexpro(A_LoopFilePath,, Props*) ; v.90 By SKAN on D1CC @ goo.gl/jyXFo9
; if VBR then move to subfolder "\VBR"
if (obj["System.Audio.IsVariableBitRate"] = "-1")
subfolder := "VBR"
else
{
; else move CBR to matching bitrate folder, for example "\128"
; get bitrate in kbs, for example 128000 -> 128
subfolder
:= SubStr(obj
["System.Audio.EncodingBitrate"],1,-3) }
if subfolder
{
if !
FileExist(destinationfolder
"\" subfolder
) FileMove, %
A_LoopFilePath, % destinationfolder
"\" subfolder
}
}
; function: Filexpro
; get extended properties from file
; by SKAN 2018-12-11
; https://www.autohotkey.com/boards/viewtopic.php?t=59882
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
{
{
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["_Dir"] := _Dir
fex["_Drv"] := _Drv
fex["_Ext"] := _Ext
fex["_File"] := _File
fex["_File.Ext"] := _FileExt
fex["_FilePath"] := sFile
}
}
If Not ( _FileExt ) ; Filepath not resolved
{
Return
}
objShl := ComObjCreate("Shell.Application")
objDir := objShl.NameSpace(_Dir)
objItm := objDir.ParseName(_FileExt)
{
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)
}
If ( PropNum := xDetails[Prop] ) > -1
{
fex[Prop] := ObjDir.GetDetailsOf(objItm,PropNum)
}
}
fex.SetCapacity(-1)
Return fex
}