- Offizieller Beitrag
Hallo
Mit diesem schönen von mir geschrieben Tool könnt ihr kinderleicht CD Informationen von einer CD bekommen.
Folgende Informationen werden per TCP übermittelt:
- Artist
- Album Name
- Jahr
- Genre
- Sonstige CD Infos (EXTD)
- Titel mit länge und position auf der CD
Das alles funktioniert über die freie Datenbank FreeDB.org.
Das gleiche verfahren benutzt auch z.B. Audiograbber, ein Tool zum CD rippen.
Legt einfach irgendeine CD (keine MP3 CD sondern eine normale im Fachhandel erhätliche CD) ein und startet das Beispiel und guckt was passiert
Kleines Dankeschön an pee, der mir geholfen hat ein paar Parts von Perl nach AutoIt zu übertragen
Hier die CDDB.au3 (include Datei)
Spoiler anzeigen
#include-once
[/autoit] [autoit][/autoit] [autoit];CDDB.au3 - By GtaSpider
[/autoit] [autoit][/autoit] [autoit]Global $hWinmmDLL = DllOpen("winmm.dll")
[/autoit] [autoit][/autoit] [autoit][/autoit] [autoit];===============================================================================
;
; Function Name: _CDDBCreateQuery($sCD)
; Description:: Create a CDDB Query for e.g. freedb.org
; Parameter(s): $sCd - The CD Drive, e.g. e: or D:
; Requirement(s): -
; Return Value(s): On Success: Returns the CD Query.
; : On Error:
; : @error = 1 $sCD isn't a CD Drive
; : @error = 2 MCICommand failed - @extended = 0 --> Open CD faild
; @extended = 1 --> Number of Tracks faild
; : @error = 3 Failed to get the CD Checksum (CD ID) - @extended: Errorcode from __CDDBGetCDID()
; : @error = 4 Failed to get tracks
; : @error = 5 Failed to get LeadOut
;
; Author(s): GtaSpider
;
;===============================================================================
;
Func _CDDBCreateQuery($sCD)
Local $sRet, $iTotal, $i
$sCD = StringUpper(StringLeft($sCD, 2))
If (Not FileExists($sCD)) Or DriveGetType($sCD) <> "CDROM" Then Return SetError(1, 0, 0)
$sRet = __SendMCIString("open " & $sCD & " type cdaudio alias cd1")
If @error Then Return SetError(2, 0, 0)
$sRet = __SendMCIString("status cd1 number of tracks wait")
If @error Then Return SetError(2, 1, 0)
$iTotal = $sRet
$sRet = "cddb query " & __CDDBGetCDID($iTotal) & " " & $iTotal & " "
If @error Then Return SetError(3, @error, 0)
For $i = 1 To $iTotal
$sRet &= __CDDBGetTrack($i) & " "
If @error Then Return SetError(4, 0, 0)
Next
$sRet &= __CDDBGetLeadOut()
If @error Then Return SetError(4, 0, 0)
Return $sRet
EndFunc ;==>_CDDBCreateQuery
;===============================================================================
;
; Function Name: _RecvFreeDB
; Description:: Connect to the Freedb.org Database
; Parameter(s): $sQuery: The Query Returned e.g. by _CDDBCreateQuery
; Requirement(s): Internet Connection
; Return Value(s): On Success: Returns the string received from freedb.org in "INI format"
; : On Error:
; : @error = 1 - Wrong Query
; : @error = 2 - Failed to get the IP from freedb.org
; : @error = 3 - Failed to connect to freedb.org
; : @error = 4 - Error on freedb.org - Freedb is not ready (maybe too much Clients)
; : @error = 5 - Error on freedb.org - Authorization failed
; : @error = 6 - Error on freedb.org - Failed to set protocol ID
; : @error = 7 - Error on freedb.org - No matches found
; : @error = 8 - Error on freedb.org - No informations found
; Author(s): GtaSpider
;
;===============================================================================
;
Func _FreeDBRecvDB($sQuery, $fSecTry = False)
Local $sIP, $hSocket, $sCDChcksum
$sCDChcksum = StringRegExp($sQuery, "cddb query (.*?) ", 3)
If @error Or (Not IsArray($sCDChcksum)) Then Return SetError(1, 0, 0)
$sCDChcksum = $sCDChcksum[0]
TCPStartup()
$sIP = TCPNameToIP("mirror1.freedb.org")
If @error Or (Not StringLen($sIP)) Then Return SetError(2, 0, 0)
$hSocket = TCPConnect($sIP, 8880)
If @error Then Return SetError(3, @error, 0)
$sRecv = __TCPRecv($hSocket)
If (Not StringInStr($sRecv, "201")) And (Not StringInStr($sRecv, "ready")) Then Return SetError(4, 0, $sRecv)
TCPSend($hSocket, "cddb hello GtaSpider AutoIt AutoIt " & @AutoItVersion & @CRLF)
$sRecv = __TCPRecv($hSocket)
If Not StringInStr($sRecv, "200 Hello and welcome") Then Return SetError(5, 0, $sRecv)
TCPSend($hSocket, "proto 5" & @CRLF)
$sRecv = __TCPRecv($hSocket)
If Not StringInStr($sRecv, "201 OK, CDDB protocol level now: 5") Then Return SetError(6, 0, $sRecv)
TCPSend($hSocket, $sQuery & @CRLF)
$sRecv = __TCPRecv($hSocket) ; genre CDID Artist / CDName, z.B. 200 rock b009520e Green Day / Dookie
If StringInStr($sRecv, "211 Found inexact matches") And $fSecTry = False Then
TCPCloseSocket($hSocket)
TCPShutdown()
Return _FreeDBRecvDB(StringReplace($sQuery, $sCDChcksum, StringLower(Hex(Number("0x" & $sCDChcksum) - 0x200, 8))), True)
ElseIf StringInStr($sRecv, "211 Found inexact matches") And $fSecTry Then
Return $sRecv
EndIf
If Not StringInStr($sRecv, "200") Then Return SetError(7, 0, $sRecv)
$aSS = StringSplit($sRecv, " ")
TCPSend($hSocket, "cddb read " & $aSS[2] & " " & $sCDChcksum & @CRLF)
$sRecv = __TCPRecv($hSocket)
If Not StringInStr($sRecv, "210") Then Return SetError(8, 0, $sRecv)
Return $sRecv
EndFunc ;==>_FreeDBRecvDB
;===============================================================================
;
; Function Name: _FreeDBRetCDInfos
; Description:: Returns Artist, Albumname, Genre, Year and other informations of the CD in an array
; Parameter(s): $sDatabase - The Databasestring from e.g. _FreeDBRecvDB
; Requirement(s): -
; Return Value(s): On Success: Returns an array with following informations:
; : $aRet[0] = Artist
; : $aRet[1] = Album
; : $aRet[2] = Genre
; : $aRet[3] = Year
; : $aRet[4] = Other Informations
; Author(s): GtaSpider
;
;===============================================================================
;
Func _FreeDBRetCDInfos($sDatabase)
Local $aSS, $aRet[5], $sRDB
$sRDB = __ReadDatabase($sDatabase, "DTITLE")
If @error Then
$aRet[0] = "NO ARTIST"
$aRet[1] = "NO ALBUM"
Else
$aSS = StringSplit($sRDB, " / ", 1)
If $aSS[0] < 2 Then
$aRet[0] = __ReadDatabase($sDatabase, "DTITLE")
Else
$aRet[0] = $aSS[1]
$aRet[1] = $aSS[2]
EndIf
EndIf
$sRDB = __ReadDatabase($sDatabase, "DGENRE")
If @error Then
$aRet[2] = "NO GENRE"
Else
$aRet[2] = $sRDB
EndIf
$sRDB = __ReadDatabase($sDatabase, "DYEAR")
If @error Then
$aRet[3] = "NO YEAR"
Else
$aRet[3] = $sRDB
EndIf
$sRDB = __ReadDatabase($sDatabase, "EXTD")
If @error Then
$aRet[4] = "NO EXTD"
Else
$aRet[4] = $sRDB
EndIf
Return $aRet
EndFunc ;==>_FreeDBRetCDInfos
;===============================================================================
;
; Function Name: _FreeDBRetCDTracks
; Description:: Returns tracks, length of tracks and position of tracks of the CD in an 2D array
; Parameter(s): $sDatabase - The Databasestring from e.g. _FreeDBRecvDB
; Requirement(s): -
; Return Value(s): On Success returns an 0 based 2D array:
; : $aRet[0][0] = First track name
; : $aRet[0][1] = First track length
; : $aRet[0][2] = First track position
; : $aRet[n][0] = n track name
; : ....
; Author(s): GtaSpider
;
;===============================================================================
;
Func _FreeDBRetCDTracks($sDatabase)
Local $aRet[1][1], $sRead, $iTotal
$iTotal = __SendMCIString("status cd1 number of tracks wait")
If @error Then Return SetError(1, 0, 0)
ReDim $aRet[$iTotal][3]
For $i = 1 To $iTotal
$sRead = __ReadDatabase($sDatabase, "TTITLE" & $i - 1)
If @error Or $sRead = '' Then Return SetError(2, 0, 0)
$aRet[$i - 1][0] = $sRead
$aMSF = __SplitMSF(__SendMCIString("status cd1 length track " & $i))
If @error Then Return SetError(3, 0, 0)
$aRet[$i - 1][1] = $aMSF[1] & ":" & StringTrimLeft("00", StringLen(Round(Number($aMSF[2] & "." & $aMSF[3])))) & Round(Number($aMSF[2] & "." & $aMSF[3]))
$aMSF = __SplitMSF(__SendMCIString("status cd1 position track " & $i))
If @error Then Return SetError(3, 1, 0)
$aRet[$i - 1][2] = $aMSF[1] & ":" & StringTrimLeft("00", StringLen(Round(Number($aMSF[2] & "." & $aMSF[3])))) & Round(Number($aMSF[2] & "." & $aMSF[3]))
Next
Return $aRet
EndFunc ;==>_FreeDBRetCDTracks
Func __CDDBGetTrack($iTrack)
Local $sRet = __SendMCIString("status cd1 position track " & $iTrack), $aMSF
If @error Then Return SetError(1, 0, 0)
$aMSF = __SplitMSF($sRet)
If @error Then Return SetError(2, @extended, 0)
Return ($aMSF[1] * 75 * 60) + ($aMSF[2] * 75) + $aMSF[3]
EndFunc ;==>__CDDBGetTrack
Func __CDDBGetLeadOut()
Local $sRet = __SendMCIString("status cd1 length wait"), $aMSF
If @error Then Return SetError(1, 0, 0)
$aMSF = __SplitMSF($sRet)
If @error Then Return SetError(2, @extended, 0)
Return ($aMSF[1] * 60) + $aMSF[2] + 2
EndFunc ;==>__CDDBGetLeadOut
Func __CDDBSum($iSum)
Local $aSS = StringSplit($iSum, ""), $iRet
For $i = 1 To $aSS[0]
$iRet += Number($aSS[$i])
Next
Return $iRet
EndFunc ;==>__CDDBSum
Func __CDDBGetCDID($iTotal)
Local $iChecksum
For $i = 1 To $iTotal
$sRet = __SendMCIString("status cd1 position track " & $i)
$aMSF = __SplitMSF($sRet)
If @error Then Return SetError(1, @extended, 0)
$iChecksum += __CDDBSum($aMSF[1] * 60 + $aMSF[2])
Next
$aMSF = __SplitMSF(__SendMCIString("status cd1 length wait"))
If @error Then Return SetError(1, @extended, 0)
$leadout = ($aMSF[1] * 60 * 75 + ($aMSF[2]) * 75 + $aMSF[3])
$tottime = ($leadout / 75) - ($iTotal / 75)
$iChecksum = BitOR(BitShift(Mod($iChecksum, 0xff), -24), BitShift($tottime, -8), $iTotal)
Return StringLower(Hex($iChecksum, 8))
EndFunc ;==>__CDDBGetCDID
Func __SplitMSF($sMSF)
Local $aSS = StringSplit($sMSF, ":")
If @error Or $aSS[0] <> 3 Then Return SetError(1, @error, 0)
Return $aSS
EndFunc ;==>__SplitMSF
Func __ReadDatabase($sDatabase, $sKey)
Local $aRet = StringRegExp($sDatabase, $sKey & "=(.*?)\r\n", 3)
If @error Or IsArray($aRet) = False Then Return SetError(1, @error, 0)
Return $aRet[0]
EndFunc ;==>__ReadDatabase
Func __SendMCIString($sString, $iBuf = 255)
Local $aRet = DllCall($hWinmmDLL, "int", "mciSendString", "str", $sString, "str", "str", "int", $iBuf, "long", 0)
If @error Then Return SetError(@error, 0, 0)
Return $aRet[2]
EndFunc ;==>__SendMCIString
Func __TCPRecv($hSocket, $iSleep = 50, $iTimeOut = 20000, $iBuffersize = 1024, $iForceBinary = 0)
Local $sRecv, $sRet, $iErr = 0, $hTi
$hTi = TimerInit()
While TimerDiff($hTi) <= $iTimeOut
$sRecv = TCPRecv($hSocket, $iBuffersize, $iForceBinary)
$iErr = @error
If $iErr Then ExitLoop
While StringLen($sRecv)
$sRet &= $sRecv
$sRecv = TCPRecv($hSocket, $iBuffersize, $iForceBinary)
$iErr = @error
If (Not StringLen($sRecv)) Or $iErr Then ExitLoop 2
If TimerDiff($hTi) > $iTimeOut Then ExitLoop
WEnd
Sleep($iSleep)
WEnd
If TimerDiff($hTi) > $iTimeOut Then Return SetError(1, 0, "Timeout")
If $iErr Then Return SetError($iErr, 0, 0)
Return $sRet
EndFunc ;==>__TCPRecv
Func OnAutoItExit()
__SendMCIString("close cd1")
DllClose($hWinmmDLL)
EndFunc ;==>OnAutoItExit
Und hier ein Beispiel
Spoiler anzeigen
#include "CDDB.au3"
[/autoit] [autoit][/autoit] [autoit];Example for CDDB.au3 - By GtaSpider
[/autoit] [autoit][/autoit] [autoit]$aDGCD = DriveGetDrive("CDROM")
$sCombostring = ''
For $i = 1 To $aDGCD[0]
$sCombostring &= StringUpper($aDGCD[$i]) & "|"
Next
StringTrimRight($sCombostring, 1)
GUICreate("Choose one drive", 150, 95, -1, -1, -1, 128);$WS_EX_TOOLWINDOW
$hComb_Drive = GUICtrlCreateCombo("", 10, 10, 50, 22)
GUICtrlSetData(-1, $sCombostring, $aDGCD[1])
$hBut_AskFreeDB = GUICtrlCreateButton("Ask FreeDB", 65, 10, 80, 22, 1) ; Style = $BS_DEFPUSHBUTTON
$hLab_Text = GUICtrlCreateLabel('Please choose one of the CD drives and click on "Ask FreeDB" to receive informations of the CD.', 10, 35, 130, 60)
GUISetState()
While 1
Switch GUIGetMsg()
Case $hBut_AskFreeDB
$sLW = GUICtrlRead($hComb_Drive)
GUICtrlDelete($hComb_Drive)
GUICtrlDelete($hBut_AskFreeDB)
GUICtrlSetData($hLab_Text, "Please wait until I try to get the CDDBQuery of " & $sLW & " and send the query to FreeDB. This may take a couple of seconds.")
$hProg_Progress = GUICtrlCreateProgress(10, 10, 130, 14, 8);Stlye = $PBS_MARQUEE = 0x08 = 8
GUICtrlSetColor(-1, 0)
DllCall("UxTheme.dll", "int", "SetWindowTheme", "hwnd", GUICtrlGetHandle(-1), "wstr", "", "wstr", "")
GUICtrlSetPos($hLab_Text, 10, 25, 130, 65)
ExitLoop
Case - 3 ;$GUI_EVENT_CLOSE = -3
Exit
EndSwitch
WEnd
Global $iProg = 0
AdlibEnable("_SetProg", 100)
$hTi = TimerInit()
$sQuery = _CDDBCreateQuery($sLW)
If @error Or (Not $sQuery) Then Exit MsgBox(16, "Error", "errorcode " & @error)
ConsoleWrite($sQuery & @CRLF)
$sDatabase = _FreeDBRecvDB($sQuery)
If @error Or (Not $sDatabase) Then Exit MsgBox(16, "Error", "2errorcode " & @error & @CRLF & $sDatabase)
If StringInStr($sDatabase, "211 Found inexact matches") Then
GUICreate("More than just one found", 220, 185)
$hListV = GUICtrlCreateListView("Founded matches", 10, 10, 200, 150)
GUICtrlSendMsg(-1, 0x101E, 0, 180)
$aSS = StringSplit($sDatabase, @CRLF, 1)
For $i = 2 To $aSS[0] - 2
GUICtrlCreateListViewItem($aSS[$i], $hListV)
If $i = 2 Then GUICtrlSetState(-1,256);$GUI_FOCUS
Next
$hBut_OK = GUICtrlCreateButton("OK", 10, 165, 200, 15,1)
GUISetState()
While 1
Switch GUIGetMsg()
Case $hBut_OK
$aRead = StringSplit(StringTrimRight(GUICtrlRead(GUICtrlRead($hListV)), 1), " ")
GUIDelete()
$aQuery = StringSplit($sQuery, " ")
$sQuery = StringReplace($sQuery, $aQuery[3], $aRead[2])
ConsoleWrite($sQuery & @CRLF)
$sDatabase = _FreeDBRecvDB($sQuery)
If @error Or (Not $sDatabase) Then Exit MsgBox(16, "Error", "2errorcode " & @error & @CRLF & $sDatabase)
ExitLoop
Case - 3 ;$GUI_EVENT_CLOSE = -3
Exit
EndSwitch
WEnd
EndIf
$aCDInfos = _FreeDBRetCDInfos($sDatabase)
$aCDTracks = _FreeDBRetCDTracks($sDatabase)
$hTi = TimerDiff($hTi)
AdlibDisable()
GUIDelete()
GUICreate("Informations of the CD tooks " & Round($hTi / 1000, 1) & " seconds", 420, 110)
GUICtrlCreateLabel("CD Title:", 8, 10, 50)
GUICtrlCreateInput($aCDInfos[1], 55, 8, 150, 18)
GUICtrlCreateLabel("CD Artist:", 8, 30, 50)
GUICtrlCreateInput($aCDInfos[0], 55, 28, 150, 18)
GUICtrlCreateLabel("CD Genre:", 8, 50, 50)
GUICtrlCreateInput($aCDInfos[2], 55, 48, 150, 18)
GUICtrlCreateLabel("CD Year:", 8, 70, 50)
GUICtrlCreateInput($aCDInfos[3], 55, 68, 150, 18)
GUICtrlCreateLabel("CD Extd:", 8, 90, 50)
GUICtrlCreateInput($aCDInfos[4], 55, 88, 150, 18)
$hListV = GUICtrlCreateListView("Title|Length|Position", 210, 8, 200, 99)
GUICtrlSendMsg(-1, 0x101E, 0, 90)
GUICtrlSendMsg(-1, 0x101E, 1, 35)
GUICtrlSendMsg(-1, 0x101E, 2, 35)
For $i = 0 To UBound($aCDTracks) - 1
GUICtrlCreateListViewItem($aCDTracks[$i][0] & "|" & $aCDTracks[$i][1] & "|" & $aCDTracks[$i][2], $hListV)
Next
GUISetState()
[/autoit] [autoit][/autoit] [autoit]While GUIGetMsg() <> -3
WEnd
Func _SetProg()
$iProg += 1
GUICtrlSetData($hProg_Progress, $iProg)
EndFunc ;==>_SetProg
Ich hoffe es kann jemand gebrauchen, würde mich um Rückmeldungen freuen
Mfg Spider