HydrogenAudio

Hydrogenaudio Forum => General Audio => Topic started by: zambaretzu on 2006-07-03 19:54:16

Title: Batch m3u playlist creation for all folders
Post by: zambaretzu on 2006-07-03 19:54:16
I've been trying to find an easy way to do this, but I can't seem to find exactly what I need. I just want a simple way to:
Any help is appreciated.
Title: Batch m3u playlist creation for all folders
Post by: masterofimages on 2006-07-03 22:05:25
I've been trying to find an easy way to do this, but I can't seem to find exactly what I need. I just want a simple way to:
  • go through all my folders recursively
  • for each folder with mp3s and oggs, making an m3u for each
  • have the m3u in the actual folder, not the root folder
  • name the m3u just like its containing folder.
Any help is appreciated.


This script should sort you out:

Code: [Select]
Const ForReading = 1, ForWriting = 2, ForAppending = 8

delete = false
set args = WScript.Arguments
if args.Count > 0 then
    if LCase(args(0)) = "-d" then
        delete = true
    end if
end if

set fso = createobject("scripting.filesystemobject")
wscript.echo WriteM3u(fso.GetAbsolutePathName("."), delete) & " files written"

function WriteM3u(path, delete)
    dim count
    set fso = createobject("scripting.filesystemobject")
    set fdr = fso.GetFolder(path)
    if fdr.SubFolders.Count = 0 then
        m3u = path & "\" & fdr.name & ".m3u"
        if fso.FileExists(m3u) then
            if delete then
                wscript.echo "... deleting existing file"
                fso.DeleteFile m3u
            else
                wscript.echo "... renaming existing file"
                fso.MoveFile m3u, m3u & ".old"
            end if
        end if
        wscript.echo "... writing """ & fdr.name & ".m3u"""
        set m3ufile = fso.OpenTextFile(m3u, ForWriting, True)
        for each f in fdr.Files
            if right(f.Name, 3) = "mp3" or right(f.Name, 3) = "ogg" then
               m3ufile.WriteLine(f.Name)
            end if
        next
        m3ufile.Close
        count = 1
    else
        count = 0
        for each subfolder in fdr.subfolders
            wscript.echo "Searching """ & subfolder.path & """"
            count = count + WriteM3u(subfolder.path, delete)
        next
    end if
    
    WriteM3u = count
end function


Just save it to "WriteM3u.vbs" and stick it in the root directory of your mp3 and ogg files. To run, type:

Code: [Select]
cscript WriteM3u.vbs


By default it will rename any existing m3u files it finds. If you would rather delete them, just add "-d" to the end of the command-line, i.e.

Code: [Select]
cscript WriteM3u.vbs -d


-Paul
Title: Batch m3u playlist creation for all folders
Post by: carmik on 2006-07-04 00:04:00
TAG (http://synthetic-soul.co.uk/tag/) can also do this from the command line. I use Speek's tag frontend (http://members.home.nl/w.speek/tag.htm), as the number of switches can be quite intimidating.
Title: Batch m3u playlist creation for all folders
Post by: Julien on 2006-07-04 01:14:05
Thank you Paul, this is a nice and useful script
Title: Batch m3u playlist creation for all folders
Post by: masterofimages on 2006-07-04 21:08:07
Thank you Paul, this is a nice and useful script


Glad you found it useful. Enjoy
Title: Batch m3u playlist creation for all folders
Post by: zambaretzu on 2006-07-05 22:51:24
Yeah, thanks, it's awesome. If you wrote it yourself, maybe you could help me make one modification to it? It doesn't work right for albums with multiple CDs, because my folder structure for them looks like this:
Foldername\Disc 1\
Foldername\Disc 2\

Right now the script writes:
Foldername\Disc 1\Disc 1.m3u
Foldername\Disc 2\Disc 2.m3u

Is there any way to make it write (ideal):
Foldername\Disc 1\Foldername (Disc 1).m3u
Foldername\Disc 2\Foldername (Disc 2).m3u

or:
Foldername\Foldername (Disc 1).m3u
Foldername\Foldername (Disc 2).m3u

or even:
Foldername\Foldername.m3u (with files from both folders)

This would make the script supremely useful for me, hope you can do it
Title: Batch m3u playlist creation for all folders
Post by: masterofimages on 2006-07-06 18:04:19
Yeah, thanks, it's awesome. If you wrote it yourself, maybe you could help me make one modification to it? It doesn't work right for albums with multiple CDs, because my folder structure for them looks like this:
Foldername\Disc 1\
Foldername\Disc 2\
...


No problem zambaretzu. Try this:

Code: [Select]
Const ForReading = 1, ForWriting = 2, ForAppending = 8

delete = false
set args = WScript.Arguments
if args.Count > 0 then
    if LCase(args(0)) = "-d" then
        delete = true
    end if
end if

set fso = createobject("scripting.filesystemobject")
wscript.echo WriteM3u(fso.GetAbsolutePathName("."), delete) & " files written"

function WriteM3u(path, delete)
    dim count
    set fso = createobject("scripting.filesystemobject")
    set fdr = fso.GetFolder(path)
    if fdr.SubFolders.Count = 0 then
        if len(fdr.Name) = 6 and left(fdr.Name, 5) = "Disc " then
            m3uName = fdr.ParentFolder.Name & " (" & fdr.Name & ").m3u"
        else
            m3uName = fdr.Name & ".m3u"
        end if
        m3u = path & "\" & m3uName
        if fso.FileExists(m3u) then
            if delete then
                wscript.echo "... deleting existing file"
                fso.DeleteFile m3u
            else
                wscript.echo "... renaming existing file"
                fso.MoveFile m3u, m3u & ".old"
            end if
        end if
        wscript.echo "... writing """ & m3uName & """"
        set m3uFile = fso.OpenTextFile(m3u, ForWriting, True)
        for each f in fdr.Files
            if right(f.Name, 3) = "mp3" or right(f.Name, 3) = "ogg" then
               m3uFile.WriteLine(f.Name)
            end if
        next
        m3uFile.Close
        count = 1
    else
        count = 0
        for each subFolder in fdr.SubFolders
            wscript.echo "Searching """ & subFolder.Path & """"
            count = count + WriteM3u(subFolder.path, delete)
        next
    end if
    
    WriteM3u = count
end function


Title: Batch m3u playlist creation for all folders
Post by: zambaretzu on 2006-07-06 20:49:16
Thanks a lot masterofimages.

There's still a small issue: for some albums, I have artwork, stored under \Foldername\art\. The script writes an empty \Foldername\art\art.m3u but no \Foldername\Foldername.m3u like it should.
Title: Batch m3u playlist creation for all folders
Post by: masterofimages on 2006-07-07 01:22:36
Thanks a lot masterofimages.

There's still a small issue: for some albums, I have artwork, stored under \Foldername\art\. The script writes an empty \Foldername\art\art.m3u but no \Foldername\Foldername.m3u like it should.


So it does  And then there was... version 3 - with added comments for extra juicyness!

Code: [Select]
Const ForReading = 1, ForWriting = 2, ForAppending = 8

' Parse command-line arguments
delete = false
set args = WScript.Arguments
if args.Count > 0 then
    if LCase(args(0)) = "-d" then
        delete = true
    end if
end if

' Write m3u files for current directory tree
set fso = CreateObject("Scripting.FileSystemObject")
wscript.echo WriteM3u(fso.GetAbsolutePathName("."), delete) & " files written"

' Recursive function to write m3u files for a given path
function WriteM3u(path, delete)
    count = 0
    set fso = CreateObject("Scripting.FileSystemObject")
    set fdr = fso.GetFolder(path)
    
    ' Write m3u file for each subfolder
    if fdr.SubFolders.Count > 0 then
        for each subFolder in fdr.SubFolders
            count = count + WriteM3u(subFolder.path, delete)
        next
    end if
    
    ' If no files found in subfolders, write m3u file for this folder
    if count = 0 then
        wscript.echo "Scanning """ & fdr.Path & """"
        ' Build list of mp3/ogg files
        mp3List = ""
        for each f in fdr.Files
            if right(f.Name, 3) = "mp3" or right(f.Name, 3) = "ogg" then
               mp3List = mp3List & f.Name & VBCrLf
            end if
        next
        
        ' If any files found, write m3u file
        if mp3List <> "" then
            ' Multi-disc folder handling
            if len(fdr.Name) = 6 and left(fdr.Name, 5) = "Disc " then
                m3uName = fdr.ParentFolder.Name & " (" & fdr.Name & ").m3u"
            else
                m3uName = fdr.Name & ".m3u"
            end if
            
            ' Existing m3u file handling
            m3u = path & "\" & m3uName
            if fso.FileExists(m3u) then
                if delete then
                    wscript.echo "... deleting existing file"
                    fso.DeleteFile m3u
                else
                    wscript.echo "... renaming existing file"
                    fso.MoveFile m3u, m3u & ".old"
                end if
            end if
            
            ' Write new m3u file
            wscript.echo "... writing """ & m3uName & """"
            set m3uFile = fso.OpenTextFile(m3u, ForWriting, True)
            m3uFile.Write(mp3List)
            m3uFile.Close
            count = 1
        else
            wscript.echo "... no mp3/ogg files found"
        end if
    end if
    
    ' Return m3u file count
    WriteM3u = count
end function
Title: Batch m3u playlist creation for all folders
Post by: zambaretzu on 2006-07-12 01:00:43
Thank you, thank you!
Title: Batch m3u playlist creation for all folders
Post by: Tbenhov on 2006-07-24 14:26:58
Thanks for the great script!! Is it possible to make it name the playlists Artist - Album.m3u using the name of the album's containing folder?
Title: Batch m3u playlist creation for all folders
Post by: JustATechFan on 2013-01-05 14:52:45
I had been looking for an automated way to create folder based  playlists for over 4 years. Today I got lucky and came across this thread. The script kindly shared by masterofimages worked beautifully and solved my problem.

Thank you so much.
Title: Batch m3u playlist creation for all folders
Post by: ramalina on 2013-01-27 10:53:55
It would be perfect if the files were order by name.
This script produce a caual (not ordered) list of mp3 files inside the folders, producing an inconsistent playlist.
Title: Batch m3u playlist creation for all folders
Post by: therobyouknow on 2015-03-14 17:27:59
I would like to add my thanks to masterofimages

Here's a variation of their code that:




Code: [Select]
' credits:
' http://www.hydrogenaud.io/forums/index.php?showtopic=46167
' http://www.hydrogenaud.io/forums/index.php?showtopic=46167&st=0&p=408550&#entry408550

Const ForReading = 1, ForWriting = 2, ForAppending = 8

' Parse command-line arguments
delete = false
set args = WScript.Arguments
if args.Count > 0 then
    if LCase(args(0)) = "-d" then
        delete = true
    end if
end if

' Write m3u files for current directory tree
set fso = CreateObject("Scripting.FileSystemObject")
wscript.echo WriteM3u(fso.GetAbsolutePathName("."), delete, 0) & " files written"

' Recursive function to write m3u files for a given path
function WriteM3u(path, delete, depth)
    wscript.echo Space(depth*2) & "WriteM3u ( path = """ & path & """" & " delete = " & delete & ")"
    count = 0
    set fso = CreateObject("Scripting.FileSystemObject")
    set fdr = fso.GetFolder(path)
    
    ' Write m3u file for each subfolder
    if fdr.SubFolders.Count > 0 then
        for each subFolder in fdr.SubFolders
            depth = depth + 1
            count = count + WriteM3u(subFolder.path, delete, depth)
            depth = depth - 1
        next
    end if
    
    ' If no files found in subfolders, write m3u file for this folder
   ' if count = 0 then
        wscript.echo Space(depth*2) & "Scanning """ & fdr.Path & """"
        ' Build list of mp3/ogg files
        mp3List = ""
        for each f in fdr.Files
            if right(f.Name, 3) = "mp3" or right(f.Name, 3) = "ogg" or right(f.Name, 4) = "flac" then
               mp3List = mp3List & f.Name & VBCrLf
            end if
        next
        
        ' If any files found, write m3u file
        if mp3List <> "" then
            ' Multi-disc folder handling
            if len(fdr.Name) = 6 and left(fdr.Name, 5) = "Disc " then
                m3uName = fdr.ParentFolder.Name & " (" & fdr.Name & ").m3u"
            else
                m3uName = fdr.Name & ".m3u"
            end if
            
            ' Existing m3u file handling
            m3u = path & "\" & m3uName
            if fso.FileExists(m3u) then
                if delete then
                    wscript.echo Space(depth*2) & "  ... deleting existing file"
                    fso.DeleteFile m3u
                else
                    wscript.echo Space(depth*2) & "  ... renaming existing file"
                    fso.MoveFile m3u, m3u & ".old"
                end if
            end if
            
            ' Write new m3u file
            wscript.echo Space(depth*2) & "  ... writing """ & m3uName & """"
            set m3uFile = fso.OpenTextFile(m3u, ForWriting, True)
            m3uFile.Write(mp3List)
            m3uFile.Close
            count = 1
        else
            wscript.echo Space(depth*2) & "  ... no mp3/ogg files found"
        end if
    'else
    '    wscript.echo Space(depth*2) & "files found in subfolders"
   ' end if
    
    ' Return m3u file count
    WriteM3u = count
end function
Title: Batch m3u playlist creation for all folders
Post by: atouk on 2015-10-27 17:33:28
Found this nice script, but missed the sorting of dirs. So I included it (and created an account for this site, which annoyingly took me somewhat longer).

Furthermore I suppressed all the requesters for each subdir (I do want to sort some hundred dirs!). You can reactivate them by the verbose flag (-v) in the command line. Or just change "shutup = false" at the beginning of the script.

Be aware I used the last script, but didn't check much. There are some funny commented lines...

Here comes the code:
Code: [Select]
' credits:
' http://www.hydrogenaud.io/forums/index.php?showtopic=46167
' http://www.hydrogenaud.io/forums/index.php?showtopic=46167&st=0&p=408550&#entry408550

option explicit

Const ForReading = 1, ForWriting = 2, ForAppending = 8

' Set shutup = false if you really want to torture your mousebutton
shutup = true
delete = false
' Parse command-line arguments
set args = WScript.Arguments
if args.Count > 0 then
    if LCase(args(0)) = "-d" then
        delete = true
    end if
    if LCase(args(0)) = "-v" then
        shutup = false
    end if

    end if

' Write m3u files for current directory tree
set dirsort = CreateObject("System.Collections.ArrayList")
set fso = CreateObject("Scripting.FileSystemObject")
wscript.echo WriteM3u(fso.GetAbsolutePathName("."), delete, 0) & " files written"

' Recursive function to write m3u files for a given path
function WriteM3u(path, delete, depth)
    if not shutup then
        wscript.echo Space(depth*2) & "WriteM3u ( path = """ & path & """" & " delete = " & delete & ")"
    end if
    count = 0
    set fso = CreateObject("Scripting.FileSystemObject")
    set fdr = fso.GetFolder(path)
    
    ' Write m3u file for each subfolder
    if fdr.SubFolders.Count > 0 then
        for each subFolder in fdr.SubFolders
            depth = depth + 1
            count = count + WriteM3u(subFolder.path, delete, depth)
            depth = depth - 1
        next
    end if
    
    ' If no files found in subfolders, write m3u file for this folder
   ' if count = 0 then
        if not shutup then
            wscript.echo Space(depth*2) & "Scanning """ & fdr.Path & """"
        end if
        ' Build list of mp3/ogg/flac files
        ' 1st: create array

        for each f in fdr.Files
            if right(f.Name, 3) = "mp3" or right(f.Name, 3) = "ogg" or right(f.Name, 4) = "flac" then
                dirsort.Add f.Name
            end if
        next
        ' 2nd: sort array
        dirsort.Sort()
        ' 3rd: generate mp3list:
        mp3List = ""        
        for each f in dirsort
            mp3List = mp3List & f & VBCrLf
        next
        ' 4th: prepare next list (empty this array)
        dirsort.clear
        
        ' If any files found, write m3u file
        if mp3List <> "" then
            ' Multi-disc folder handling
            if len(fdr.Name) = 6 and left(fdr.Name, 5) = "Disc " then
                m3uName = fdr.ParentFolder.Name & " (" & fdr.Name & ").m3u"
            else
                m3uName = fdr.Name & ".m3u"
            end if
            
            ' Existing m3u file handling
            m3u = path & "\" & m3uName
            if fso.FileExists(m3u) then
                if delete then
                    if not shutup then
                        wscript.echo Space(depth*2) & "  ... deleting existing file"
                    end if
                    fso.DeleteFile m3u
                else
                    if not shutup then
                        wscript.echo Space(depth*2) & "  ... renaming existing file"
                    end if
                    fso.MoveFile m3u, m3u & ".old"
                end if
            end if
            
            ' Write new m3u file
'            wscript.echo Space(depth*2) & "  ... writing """ & m3uName & """"
            set m3uFile = fso.OpenTextFile(m3u, ForWriting, True)
            m3uFile.Write(mp3List)
            m3uFile.Close
            count = 1
        else
            wscript.echo Space(depth*2) & "  ... no mp3/ogg files found"
        end if
    'else
    '    wscript.echo Space(depth*2) & "files found in subfolders"
   ' end if
    
    ' Return m3u file count
    WriteM3u = count
end function
Title: Batch m3u playlist creation for all folders
Post by: atouk on 2015-11-01 17:11:02
Some days later I didn't find an edit button any more... so here comes a new version which should work better.
(I did include a "option explicit" and didn't check it properly as I was running an old version... sigh).

Improved the flag parsing and added a "prefix" constant for naming of the m3us if someone is interested.

Code: [Select]
' credits:
' http://www.hydrogenaud.io/forums/index.php?showtopic=46167
' http://www.hydrogenaud.io/forums/index.php?showtopic=46167&st=0&p=408550&#entry408550

option explicit

Const ForReading = 1, ForWriting = 2, ForAppending = 8
Const PreFix = ""  ' Set this string if you want your playlists with a given prefix (like "- classical - ")
dim shutup, delete, args, argc, fso, dirsort

' Set shutup = false if you really want to torture your mousebutton
shutup = true
delete = false
' Parse command-line arguments
set args = WScript.Arguments
for argc = 0 to args.Count-1
    if LCase(args(argc)) = "-d" then
        delete = true
    end if
    if LCase(args(a)) = "-v" then
        shutup = false
    end if
next

' Write m3u files for current directory tree
set dirsort = CreateObject("System.Collections.ArrayList")
set fso = CreateObject("Scripting.FileSystemObject")
wscript.echo WriteM3u(fso.GetAbsolutePathName("."), 0) & " files written"



' Recursive function to write m3u files for a given path
function WriteM3u(path, depth)
dim mp3List, count, fdr, subFolder, f, m3u, m3uName, m3uFile
    if not shutup then
        wscript.echo Space(depth*2) & "Working in path = """ & path & """" & " delete = " & delete
    end if
    count = 0
    set fdr = fso.GetFolder(path)
    
    ' Write m3u file for each subfolder
    if fdr.SubFolders.Count > 0 then
        for each subFolder in fdr.SubFolders
            ' Recurse into subfolders
            count = count + WriteM3u(subFolder.path, depth + 1)
        next
    end if
    
    ' If no files found in subfolders, write m3u file for this folder
    if count = 0 then
        if not shutup then
            wscript.echo Space(depth*2) & "Scanning """ & fdr.Path & """"
        end if
        ' Build list of mp3/ogg/flac files
        ' 1st: create array

        for each f in fdr.Files
            if lcase(right(f.Name, 3)) = "mp3" or lcase(right(f.Name, 3)) = "ogg" or lcase(right(f.Name, 4)) = "flac" then
                dirsort.Add f.Name
            end if
        next
        ' 2nd: sort array
        dirsort.Sort()
        ' 3rd: generate mp3list:
        mp3List = ""        
        for each f in dirsort
            mp3List = mp3List & f & VBCrLf
        next
        ' 4th: prepare next list (empty this array)
        dirsort.clear
        
        ' If any files found, write m3u file
        if mp3List <> "" then
            ' Multi-disc folder handling
            if len(fdr.Name) = 6 and left(fdr.Name, 5) = "Disc " then
                m3uName = PreFix & fdr.ParentFolder.Name & " (" & fdr.Name & ").m3u"
            else
                m3uName = PreFix & fdr.Name & ".m3u"
            end if
            
            ' Existing m3u file handling
            m3u = path & "\" & m3uName
            if fso.FileExists(m3u) then
                if delete then
                    if not shutup then
                        wscript.echo Space(depth*2) & "  ... deleting existing file"
                    end if
                    fso.DeleteFile m3u
                else
                    if not shutup then
                        wscript.echo Space(depth*2) & "  ... renaming existing file"
                    end if
                    fso.MoveFile m3u, m3u & ".old"
                end if
            end if
            
            ' Write new m3u file
            if not shutup then
                wscript.echo Space(depth*2) & "  ... writing """ & m3uName & """"
            end if
            set m3uFile = fso.OpenTextFile(m3u, ForWriting, True)
            m3uFile.Write(mp3List)
            m3uFile.Close
            count = 1
        else
            wscript.echo Space(depth*2) & "  ... no mp3/ogg files found"
        end if
    else
        if not shutup then
            wscript.echo Space(depth*2) & "files found in subfolders"
        end if
    end if
    
    ' Return m3u file count
    WriteM3u = count
end function