-
-
Save rornor/98127e4a96866d0d44fa to your computer and use it in GitHub Desktop.
foobar2000, foo_run script for creating dynamic playlist based on single track as seed. It's fully automated if foo_comserver component is available, otherwise it creates XSPF playlist which can be loaded manually.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Set XML = CreateObject("MSXML2.DOMDocument.6.0") | |
XML.async = False | |
Set ARG = WScript.Arguments | |
If ARG.Count < 1 Then | |
WScript.Echo "Usage: wscript echosong.vbs [%MUSICBRAINZ_TRACKID%|""%artist%"" ""%title%""] [interactive]" | |
WScript.Quit() | |
Else | |
url = "http://developer.echonest.com/api/v4/playlist/static?api_key=PKDMY7Z0SGFBW" | |
If Len(ARG.Item(0)) = 36 And UBound(Split(ARG.Item(0), "-")) = 4 Then | |
mb = MusicBrainz(ARG.Item(0)) : GetSongID mb(0), mb(1) | |
Else | |
If ARG.Count > 1 Then GetSongID ARG.Item(0), ARG.Item(1) | |
End If | |
End If | |
Function MusicBrainz(id) | |
XML.setProperty "SelectionNamespaces", "xmlns:m='http://musicbrainz.org/ns/mmd-2.0#'" | |
XML.loadXML(Request("http://musicbrainz.org/ws/2/recording/" & id & "?inc=artists")) | |
If XML.lastChild.nodeName = "error" Then | |
WScript.Echo "Invalid MBID!" : WScript.Quit() | |
Else | |
artist = XML.selectSingleNode(_ | |
"m:metadata/m:recording/m:artist-credit/m:name-credit/m:artist[1]/@id").text | |
title = XML.selectSingleNode("m:metadata/m:recording/m:title").text | |
MusicBrainz = array(artist, title) | |
End If | |
End Function | |
Sub GetSongID(artist, title) | |
title = "&title=" & title | |
If Len(artist) = 36 And UBound(Split(artist, "-")) = 4 Then | |
artist = "&artist_id=musicbrainz:artist:" & artist | |
Else : artist = "&artist=" & artist : End If | |
If XML.loadXML(Request(Replace(url,"playlist/static","song/search") &_ | |
UCase(Right("denial", 4)) & artist & title & "&format=xml")) Then | |
Set song = XML.selectNodes("response/songs/song[1]/id") | |
If song.length Then | |
param = "&song_id=" | |
If ARG.item(ARG.length-1) = "interactive" Then param = Dialog & param | |
GetPlaylist param & song.item(0).text | |
Else | |
WScript.Echo "Seed track not found!" | |
End If | |
Else | |
WScript.Echo "Invalid request!" | |
End If | |
End Sub | |
Sub GetPlaylist(param) | |
XML.loadXML(Request(url & UCase(Right("denial", 4)) & param &_ | |
"&results=100&type=song-radio&format=xml")) | |
On Error Resume Next | |
Set fb2k = CreateObject("Foobar2000.Application.0.7") | |
if err.number <> 0 then | |
WriteXSPF | |
Else | |
WriteM3U | |
End If | |
End Sub | |
Sub WriteXSPF() | |
Set XSPF = CreateObject("MSXML2.DOMDocument.6.0") : XSPF.async = False | |
XSPF.loadXML("<?xml version='1.0' encoding='UTF-8'?>" &_ | |
"<playlist version='1' xmlns='http://xspf.org/ns/0/'></playlist>") | |
Set frag = XSPF.createDocumentFragment | |
Set trks = XSPF.createElement("trackList") | |
For Each song in XML.selectNodes("response/songs/song") | |
Set newElem = XSPF.createElement("track") | |
For Each s In song.childNodes | |
If s.nodeName = "artist_name" Then | |
Set newTag = XSPF.createElement("creator") | |
newTag.appendChild(XSPF.createTextNode(s.text)) | |
newElem.appendChild(newTag) | |
End If | |
If s.nodeName = "title" Then newElem.appendChild(s) | |
trks.appendChild(newElem) | |
Next | |
Next | |
Set doc = XSPF.documentElement | |
frag.appendChild(trks) | |
doc.appendChild(frag) | |
path = Replace(WScript.ScriptFullName, WScript.ScriptName, "") & "echo.xspf" | |
XSPF.save(path) : WScript.Echo "Playlist: """ & path & """ successfully created." | |
End Sub | |
Sub WriteM3U() | |
Set fb2k = WScript.CreateObject("Foobar2000.Application.0.7") | |
Set FSO = CreateObject("Scripting.FileSystemObject") | |
Set SHO = CreateObject("WScript.Shell") | |
path = Replace(WScript.ScriptFullName, WScript.ScriptName, "") & "echo.m3u" | |
Set m3u = fso.CreateTextFile(path) | |
Set lib = fb2k.MediaLibrary | |
For Each song in XML.selectNodes("response/songs/song") | |
For Each s In song.childNodes | |
If s.nodeName = "artist_name" Then qra = s.text | |
If s.nodeName = "title" Then qrt = s.text | |
Next | |
Set qry = lib.GetTracks("artist IS " & qra & " AND title IS " & qrt) | |
If qry.Count Then m3u.WriteLine qry.Item(0).Path : run = 1 | |
Next | |
m3u.close : q = Chr(34) | |
If run Then exec = SHO.run(q & fb2k.ApplicationPath & q & " " & q & path & q, 0, 1) | |
End Sub | |
Function Dialog() | |
desc = desc + "max_tempo (or min_tempo):" + vbCrLf | |
desc = desc + " 0.0 < tempo < 500.0 (BPM)" + vbCrLf | |
desc = desc + "max_duration (or min_duration):" + vbCrLf | |
desc = desc + " 0.0 < duration < 3600.0 (seconds)" + vbCrLf | |
desc = desc + "max_loudness (or min_loudness):" + vbCrLf | |
desc = desc + " -100.0 < loudness < 100.0 (dB)" + vbCrLf | |
desc = desc + "max_danceability (or min_danceability):" + vbCrLf | |
desc = desc + " 0.0 < danceability < 1.0" + vbCrLf | |
desc = desc + "max_energy (or min_energy):" + vbCrLf | |
desc = desc + " 0.0 < energy < 1.0" + vbCrLf | |
desc = desc + "artist_max_familiarity (or artist_min_familiarity):" + vbCrLf | |
desc = desc + " 0.0 < familiarity < 1.0" + vbCrLf | |
desc = desc + "artist_max_hotttnesss (or artist_min_hotttnesss):" + vbCrLf | |
desc = desc + " 0.0 < hotttnesss < 1.0" + vbCrLf | |
desc = desc + "artist_start_year_before (or artist_start_year_after):" + vbCrLf | |
desc = desc + " 1970, 2011, present" + vbCrLf | |
desc = desc + "artist_end_year_before (or artist_end_year_after):" + vbCrLf | |
desc = desc + " 1970, 2011, present" + vbCrLf | |
desc = desc + "song_max_hotttnesss (or song_min_hotttnesss):" + vbCrLf | |
desc = desc + " 0.0 < hotttnesss < 1.0" + vbCrLf | |
desc = desc + "mode:" + vbCrLf | |
desc = desc + " (minor, major) 0, 1" + vbCrLf | |
desc = desc + "key:" + vbCrLf | |
desc = desc + " 0 - 11 (C, C#, D, Eb, E, F, F#, G, Ab, A, Bb, B)" + vbCrLf | |
desc = desc + vbCrLf + "--------------------" | |
desc = desc + vbCrLf + "Use any number or parameters separate by colon" | |
desc = desc + vbCrLf + "Example: ""key=3:min_tempo=150"" (w/o quotes)" | |
q = Trim(InputBox(desc, "Additional Parameters", "")) | |
If q <> "" Then | |
For Each p in Split(q, ":") : qp = qp & "&" & Replace(p," ", "") : Next | |
Dialog = qp | |
Else | |
Dialog = q | |
End If | |
End Function | |
Function Request(url) | |
Set HTTP = CreateObject("MSXML2.XMLHTTP") | |
HTTP.open "GET", url, False | |
HTTP.setRequestHeader "User-Agent", _ | |
"Mozilla/5.0 (Windows NT 5.1; rv:12.0) Gecko/20100101 Firefox/12.0" | |
HTTP.send "" | |
If Err.number <> 0 then | |
WScript.Echo "Error: " & HTTP.parseError.url & vbCrLf & HTTP.parseError.Reason | |
WScript.Quit() | |
End If | |
Request = HTTP.responseText | |
End Function |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thread: link
Example foo_run action:
wscript echosong.vbs $if2(%MUSICBRAINZ_TRACKID%,"%artist%" "%title%")
or simply:
wscript echosong.vbs "%artist%" "%title%"