Skip to main content

Notice

Please note that most of the software linked on this forum is likely to be safe to use. If you are unsure, feel free to ask in the relevant topics, or send a private message to an administrator or moderator. To help curb the problems of false positives, or in the event that you do find actual malware, you can contribute through the article linked here.
Topic: Batch m3u playlist creation for all folders (Read 19456 times) previous topic - next topic
0 Members and 1 Guest are viewing this topic.

Batch m3u playlist creation for all folders

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.

Batch m3u playlist creation for all folders

Reply #1
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

Batch m3u playlist creation for all folders

Reply #2
TAG can also do this from the command line. I use Speek's tag frontend, as the number of switches can be quite intimidating.

Batch m3u playlist creation for all folders

Reply #3
Thank you Paul, this is a nice and useful script


Batch m3u playlist creation for all folders

Reply #5
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

Batch m3u playlist creation for all folders

Reply #6
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



Batch m3u playlist creation for all folders

Reply #7
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.

Batch m3u playlist creation for all folders

Reply #8
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

Batch m3u playlist creation for all folders

Reply #9
Thank you, thank you!

Batch m3u playlist creation for all folders

Reply #10
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?

Batch m3u playlist creation for all folders

Reply #11
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.

Batch m3u playlist creation for all folders

Reply #12
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.

Batch m3u playlist creation for all folders

Reply #13
I would like to add my thanks to masterofimages

Here's a variation of their code that:
  • generates a playlist for a folder containing audio files where those folders also have subfolders that contain audio files. The original script only generates the playlist for the deepest folder (that had no further subfolders). I've simply commented out the if count statement and endif for this aim.
  • indents the log output according to depth of the folder
  • searches for flac audio files too (m3u playlists can be used with these file too)




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

 

Batch m3u playlist creation for all folders

Reply #14
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

Batch m3u playlist creation for all folders

Reply #15
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