DonationCoder.com Software > Post New Requests Here
IDEA: Batch download lyrics for your mp3 songs in your library to the ID3 tag
skrommel:
:) Just delete the line, or download the latest AutoHotkey from www.autohotkey.com.
Skrommel
fatjoe:
by command line. Do you mean. making a shorcut and addnig -AddLyrics "c:\mp3\*.mp3" rescurse to the end of the target box?
Cause i did that and tested with the song The Pussycat Dolls - Buttons (id3 tag: artist: the pussycat dolls - title: buttons) -- and it didn't seem to do anythign when i ran it. Heres the lyric on azlyrics. http://www.azlyrics.com/lyrics/pussycatdolls/buttons.html
I set the target box of the shorcut to:
"F:\My Documents\My Music\batchlyrics.exe" -AddLyrics "C:\Documents and Settings\fatjoe\Desktop\*.mp3" Recurse
skrommel:
:) Here's another, called DownloadLyrics, without the dependency of Tag.exe
To make it work, save the text below as DownloadLyrics.ahk, then make a shortcut to it, rightclick the shortcut and select properties, and add the text after the command line, so it looks something like this:
"C:\DownloadLyrics\DownloadLyrics.ahk" "D:\*.mp3" Recurse Overwrite
Skrommel
--- ---;DownloadLyrics.ahk
; Downloads the lyrics of MP3 files
; For more tags and info on id3, check out the two first links on http://www.id3.org/develop.html
;Skrommel @2006
#SingleInstance,Force
#NoEnv
SetBatchLines,-1
If 0=0
{
MsgBox,0,DownloadLyrics - 1 Hour Software,DownloadLyrics - Downloads the lyrics of mp3 files from azlyrics.com`n`nCommand line: `tDownloadLyrics <path to mp3(s)> [Recurse Replace]`nExample: `t`tDownloadLyrics "C:\MP3\*.mp3" Recurse Replace`n`nRecurse=Recurse into subfolders`nReplace=Replace exsting lyrics`n`nFor more tools and information, visit www.1hoursoftware.com
ExitApp
}
path=%1%
recurse=0
If (2="recurse" Or 3="recurse")
recurse=1
replace=0
If (2="replace" Or 3="replace")
replace=1
Loop,%path%,0,%recurse%
{
TrayTip,DownloadLyrics,%A_LoopFileLongPath%
SplitPath,A_LoopFileLongPath,name,dir,ext,name_no_ext,drive
file=%A_LoopFileLongPath%
output=%dir%\%name_no_ext%.txt
title=
performer=
lyrics=
Gosub,READTAGS
Gosub,RETRIEVE
}
ExitApp
RETRIEVE:
If title=
Return
If performer=
Return
StringReplace,performer,performer,%A_Space%,+
Loop
{
StringGetPos,start,performer,++
If start<0
Break
StringReplace,performer,performer,++,+,All
}
StringReplace,title,title,%A_Space%,+,All
Loop
{
StringGetPos,start,title,++
If start<0
Break
StringReplace,title,title,++,+,All
}
lyricsexist=1
If lyrics<>
lyricsexist=0
file=http://search.azlyrics.com/cgi-bin/azseek.cgi?q=%performer%+%title%
UrlDownloadToFile,%file%,file.htm
FileRead,file,file.htm
StringGetPos,start,file,<b>1.</b>
If start=0
Return
StringGetPos,start,file,<a href=",,% start
start+=10
StringGetPos,stop,file,",,% start
StringMid,file,file,% start,% stop-start+1
TrayTip,DownloadLyrics,%file%
UrlDownloadToFile,%file%,file.htm
FileRead,file,file.htm
StringGetPos,start,file,"</b>
start+=9
StringGetPos,stop,file,`n<BR><BR>,,% start
StringMid,file,file,% start,% stop-start-2
tag=0
lyrics=
Loop,Parse,file
{
If A_LoopField=<
{
tag=1
Continue
}
If A_LoopField=>
{
tag=0
Continue
}
If tag=0
lyrics:=lyrics A_LoopField
}
If (lyrics<>"" And (replace=1 or lyricsexist=0))
{
FileDelete,%output%
FileAppend,%lyrics%,%output%
}
Return
READTAGS:
;;;;;;; HEADER ;;;;;;;
res:=BinRead(file,data,3,0)
fileidentifier:=DeHexify(data)
res:=BinRead(file,data,1,3)
majorversion:=data+0
res:=BinRead(file,data,1,4)
revisionnumber:=data+0
version=%majorversion%.%revisionnumber%
res:=BinRead(file,data,1,5)
flags=0x%data%
Transform,unsync,BitAnd,%flags%,256
Transform,extheader,BitAnd,%flags%,128
Transform,experimentalid,BitAnd,%flags%,64
Transform,footer,BitAnd,%flags%,32
res:=BinRead(file,data,2,8)
size=0x%data%
size+=0
extheaderpos:=10
;;;;;;; EXTENDEDHEADER ;;;;;;;
If extendedheader=1
{
res:=BinRead(file,data,4,extheaderpos)
frameid:=DeHexify(data)
res:=BinRead(file,data,4,extheaderpos+4)
extheadersize=0x%data%
extheadersize+=10
frameheaderpos:=extheaderpos+extheadersize
}
Else
frameheaderpos:=extheaderpos
;;;;;;; FRAMES ;;;;;;;
Loop
{
;;;;;;; FRAMEHEADER ;;;;;;;
res:=BinRead(file,data,4,frameheaderpos)
frameid:=DeHexify(data)
res:=BinRead(file,data,4,frameheaderpos+4)
framesize=0x%data%
framesize+=0
res:=BinRead(file,data,1,frameheaderpos+8)
flaga:=data
res:=BinRead(file,data,1,frameheaderpos+9)
flagb:=data
If frameid=
Break
; TIT2: title
; USLT: lyrics
; TPE1: performer
If (frameid="TPE1" Or frameid="TIT2" Or frameid="USLT")
{
framepos:=frameheaderpos+10 ;frameheadersize=10
;;;;;;; FRAME ;;;;;;;
If framesize>0
{
res:=BinRead(file,data,framesize,framepos)
frametext:=DeHexify(data)
If (frameid="TPE1")
performer:=frametext
Else
If (frameid="TIT2")
title:=frametext
Else
If (frameid="USLT")
StringTrimLeft,lyrics,frametext,3
}
}
frameheaderpos:=frameheaderpos+framesize+10 ;frameheadersize=10
If (frameheaderpos>=size)
Break
}
;MsgBox,0,id3v2,Performer:%performer% `nTitle:%title% `nLyrics:`n%lyrics%
Return
DeHexify(x)
{
StringLen,len,x
len:=len/2
string=
Loop,%len%
{
StringLeft,hex,x,2
hex=0x%hex%
Transform,y,Chr,%hex%
string:=string y
StringTrimLeft,x,x,2
}
Return,string
}
;By lazlo at http://www.autohotkey.com/forum/viewtopic.php?t=4546
/* ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; BinWrite ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
| - Open binary file
| - (Over)Write n bytes (n = 0: all)
| - From offset (offset < 0: counted from end)
| - Close file
| data -> file[offset + 0..n-1], rest of file unchanged
| Return #bytes actually written
*/ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
BinWrite(file, data, n=0, offset=0)
{
; Open file for WRITE (0x40..), OPEN_ALWAYS (4): creates only if it does not exists
h := DllCall("CreateFile","str",file,"Uint",0x40000000,"Uint",0,"UInt",0,"UInt",4,"Uint",0,"UInt",0)
IfEqual h,-1, SetEnv, ErrorLevel, -1
IfNotEqual ErrorLevel,0,Return,0 ; couldn't create the file
m = 0 ; seek to offset
IfLess offset,0, SetEnv,m,2
r := DllCall("SetFilePointerEx","Uint",h,"Int64",offset,"UInt *",p,"Int",m)
IfEqual r,0, SetEnv, ErrorLevel, -3
IfNotEqual ErrorLevel,0, {
t = %ErrorLevel% ; save ErrorLevel to be returned
DllCall("CloseHandle", "Uint", h)
ErrorLevel = %t% ; return seek error
Return 0
}
TotalWritten = 0
m := Ceil(StrLen(data)/2)
If (n <= 0 or n > m)
n := m
Loop %n%
{
StringLeft c, data, 2 ; extract next byte
StringTrimLeft data, data, 2 ; remove used byte
c = 0x%c% ; make it number
result := DllCall("WriteFile","UInt",h,"UChar *",c,"UInt",1,"UInt *",Written,"UInt",0)
TotalWritten += Written ; count written
if (!result or Written < 1 or ErrorLevel)
break
}
IfNotEqual ErrorLevel,0, SetEnv,t,%ErrorLevel%
h := DllCall("CloseHandle", "Uint", h)
IfEqual h,-1, SetEnv, ErrorLevel, -2
IfNotEqual t,,SetEnv, ErrorLevel, %t%
Return TotalWritten
}
/* ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; BinRead ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
| - Open binary file
| - Read n bytes (n = 0: all)
| - From offset (offset < 0: counted from end)
| - Close file
| data (replaced) <- file[offset + 0..n-1]
| Return #bytes actually read
*/ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
BinRead(file, ByRef data, n=0, offset=0)
{
h := DllCall("CreateFile","Str",file,"Uint",0x80000000,"Uint",3,"UInt",0,"UInt",3,"Uint",0,"UInt",0)
IfEqual h,-1, SetEnv, ErrorLevel, -1
IfNotEqual ErrorLevel,0,Return,0 ; couldn't open the file
m = 0 ; seek to offset
IfLess offset,0, SetEnv,m,2
r := DllCall("SetFilePointerEx","Uint",h,"Int64",offset,"UInt *",p,"Int",m)
IfEqual r,0, SetEnv, ErrorLevel, -3
IfNotEqual ErrorLevel,0, {
t = %ErrorLevel% ; save ErrorLevel to be returned
DllCall("CloseHandle", "Uint", h)
ErrorLevel = %t% ; return seek error
Return 0
}
TotalRead = 0
data =
IfEqual n,0, SetEnv n,0xffffffff ; almost infinite
format = %A_FormatInteger% ; save original integer format
SetFormat Integer, Hex ; for converting bytes to hex
Loop %n%
{
result := DllCall("ReadFile","UInt",h,"UChar *",c,"UInt",1,"UInt *",Read,"UInt",0)
if (!result or Read < 1 or ErrorLevel)
break
TotalRead += Read ; count read
c += 0 ; convert to hex
StringTrimLeft c, c, 2 ; remove 0x
c = 0%c% ; pad left with 0
StringRight c, c, 2 ; always 2 digits
data = %data%%c% ; append 2 hex digits
}
IfNotEqual ErrorLevel,0, SetEnv,t,%ErrorLevel%
h := DllCall("CloseHandle", "Uint", h)
IfEqual h,-1, SetEnv, ErrorLevel, -2
IfNotEqual t,,SetEnv, ErrorLevel, %t%
SetFormat Integer, %format% ; restore original format
Totalread += 0 ; convert to original format
Return TotalRead
}
fatjoe:
I think you're onto it. I ran it again.
"F:\My Documents\My Music\batchlyrics.exe" "C:\*.mp3" Overwrite
It popped up with Download Lyrics in the tray and the pussycat dolls - buttons. Then the link to the lyric page came after that. Then it went away. I checked the song but no lyrics were added though :(
Oh but I noticed the lyrics were downloaded to a file called file.htm in the folder that the EXE file was in. :tellme:
skrommel:
:tellme: I made DownloadLyrics create a text file with the same name as the MP3, as Tag.exe wouldn't work. I'm lookin into writing the lyrics to the MP3 file.
I could automate some of the freeware programs out there, but TagRunner looks like it'll do all the job.
Skrommel
Navigation
[0] Message Index
[#] Next page
[*] Previous page
Go to full version