Skip to content

Instantly share code, notes, and snippets.

@rornor
Last active December 10, 2015 07:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rornor/fbe0e3462dd46f58821f to your computer and use it in GitHub Desktop.
Save rornor/fbe0e3462dd46f58821f to your computer and use it in GitHub Desktop.
This script provides song identification service
' path to executables: either ffmpeg or sox (ffmpeg supports far more real-life formats)
ffmpeg_exe = "C:\Program Files\ffmpeg\bin\ffmpeg.exe"
sox_exe = "C:\Program Files\SoX\sox.exe"
' test.exe and codegen.dll from: http://static.echonest.com/ENMFP_codegen.zip
test_exe = "C:\Program Files\foobar2000\scripts\test.exe"
' set to 1 to execute in verbose mode:
verb = 0
With CreateObject("Scripting.FileSystemObject")
track = WScript.Arguments.Item(0)
ss = 10
If Not .FileExists(test_exe) Then WScript.Echo "test.exe not found." : WScript.Quit()
If Not .FileExists(track) Then
If Left(track, 4) = "http" Then
If Not .FileExists(ffmpeg_exe) Then WScript.Echo "ffmpeg.exe not found." : WScript.Quit()
ss = 0
Else
WScript.Echo track & " not found." : WScript.Quit()
End If
End If
tmp = .GetSpecialFolder(2) : tmp_file = tmp & "\echo.wav"
If .FileExists(ffmpeg_exe) Then
cmd = quote(ffmpeg_exe) & "-ss " & ss & " -t 20 -i" & quote(track) & "-acodec pcm_s16le -ar 22k -ac 1" & quote(tmp_file)
ElseIf .FileExists(sox_exe) Then
tmp_file = tmp_file & "pcm"
cmd = quote(sox_exe) & quote(track) & "-r 22k -c 1" & quote(tmp_file) & "trim 10 20"
Else
WScript.Echo "Neither sox nor ffmpeg can be found" : WScript.Quit()
End If
If .FileExists(tmp_file) Then .DeleteFile(tmp_file)
js = tmp & "\echo.json"
cmd = cmd & "&&" & quote(test_exe) & quote(tmp_file) & "10 >" & quote(js)
r = CreateObject("WScript.Shell").Run("%comspec% /c" & cmd, 0, 1)
If r <> 1 Then
WScript.Echo "Command returned error code: " & r & vbCrLf & cmd : WScript.Quit()
Else
If .FileExists(js) Then
json = .OpenTextFile(js, 1).ReadAll : .DeleteFile(js)
url = "http://developer.echonest.com/api/v4/song/identify?api_key=PKDMY7Z0SGFBW"
resp = Request(url & UCase(Right("denial", 4)) & "&code=" & jdec(json, "code"))
If Int(jdec(resp, "code")) Then
WScript.Echo jdec(resp, "message")
Else
out = track & """ not identified."
If jdec(resp, "id") <> "" Then
If verb Then
out = Verbose(jdec(resp, "id"))
Else
out = "Title: " & jdec(resp, "title") & vbCrLf &_
"Artist: " & jdec(resp, "artist_name") & vbCrLf &_
"ID: " & jdec(resp, "id")
End If
End If
WScript.Echo out
End If
Else
WScript.Echo "JSON file not generated." : WScript.Quit()
End If
End If
End With
Function Verbose(id)
' Possible buckets: http://developer.echonest.com/docs/v4/song.html
b = "&bucket=audio_summary"
b = b & "&bucket=song_hotttnesss"
b = b & "&bucket=artist_familiarity"
b = b & "&bucket=artist_hotttnesss"
With CreateObject("Microsoft.XMLDOM")
.async = False
.loadXML(Request(Replace(url, "identify", "profile") & _
UCase(Right("denial", 4)) & "&format=xml&id=" & id & b))
If Int(.selectSingleNode("response/status/code").text) Then
Verbose = .selectSingleNode("response/status/message").text
Else
With .selectSingleNode("response/songs/song")
q = "TRACK:" & vbCrLf
For Each s In .childNodes
If s.childNodes.length > 1 Then
qc = qc & vbCrLf & UCase(s.nodeName) & vbCrLf
For Each ss In s.childNodes
If Not ss.nodeName = "analysis_url" Then _
qc = qc & format(ss.nodeName) & ss.text & vbCrLf
Next
Else : q = q & format(s.nodeName) & s.text & vbCrLf : End If
Next
Verbose = q & qc
End With
End If
End With
End Function
Function Request(URL)
With CreateObject("MSXML2.XMLHTTP")
.open "GET", URL, False
.setRequestHeader "User-Agent", "Mozilla/5.0 (Windows NT 5.1; rv:31.0) Gecko/20100101 Firefox/31.0"
.send ""
If Err.number <> 0 then
WScript.Echo "Error: " & .parseError.URL & vbCrLf & .parseError.Reason : WScript.Quit()
End If
Request = .responseText
End With
End Function
Function jdec(str, s)
For Each j In Split(str, """")
For Each jj In Split("{ } : , [ ]")
j = Trim(Replace(j, jj, ""))
Next
If Len(j) > 0 Then
If Dump Then jdec = j : Dump = 0
If j = s Then Dump = 1
End If
Next
End Function
Function quote(s)
q = Chr(34)
If Left(s, 1) <> q And InStr(s, " ") > 0 Then s = q & s & q
quote = " " & s & " "
End Function
Function format(k)
k = Replace(UCase(Left(k,1)) & Right(k, Len(k)-1), "_", " ")
format = k & ": "
End Function
@rornor
Copy link
Author

rornor commented Dec 28, 2012

Thread: link

Examples:

  • as foo_run action: "C:\Program Files\foobar2000\scripts\echoprint.vbs" "%path%"
  • general: drag & drop audio file over echoprint.vbs icon

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment