mci zum auslesen von audiocd -> freedb abfragen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
genrich
User
Beiträge: 91
Registriert: Sonntag 27. Juni 2004, 17:46

Mittwoch 10. November 2004, 06:35

So jetzt habe ich es... Das Listing aus der Mailingliste war nicht ganz vollständig...

Code: Alles auswählen


from pygame import cdrom

def getDiskId( tracksInfo ):
    """
    Returns disc id based on tracksInfo which is tuple of ( track_start, track_length )
    """
    # check sum
    def sumDigits( val ):
        return int( reduce( lambda x, y: int( y )+ int( x ), str( val ) ) )

    # check sum
    checkSum= reduce( lambda x, y: x+ y, map( lambda x: sumDigits( int( x[ 0 ]/75 )), tracksInfo ) )
    # total length
    totalTime= reduce( lambda x, y: x+ y, map( lambda x: x[ 1 ], tracksInfo ) )
    return ( ( long(checkSum % 0xff) << 24 ) + ( long( totalTime/75 ) << 8 ) + len( tracksInfo ) )




cdrom.init()
cd=cdrom.CD(0)

print "Initialisierte..."
cd.init()

RAW_ID = getDiskId( [ ( cd.get_track_start( x )*75,cd.get_track_length( x )*75 ) for x in xrange( cd.get_numtracks() ) ] )

print "RAW_ID......:",RAW_ID
print "freedb ID...: %08lx" % RAW_ID
Nun ist das Ergebniss korrekt:

Code: Alles auswählen

RAW_ID......: 3708718608
freedb ID...: dd0e8e10
Obwohl das Listing schön kompakt ist, will ich es etwas Normalisieren... Die ganzen lambda Dinger verstehe ich nämlich nicht wirklich...
genrich
User
Beiträge: 91
Registriert: Sonntag 27. Juni 2004, 17:46

Mittwoch 10. November 2004, 07:45

So... Ich hab meine Variante mit der kompakten Varianten von oben gekreutzt...
Nun hab ich ein Listing, welches ich auch verstehe :lol:
Und es funktioniert!!! :D

Code: Alles auswählen

from pygame import cdrom

def DiscID(cd_object):
    def getHMS_f(Frames):
        # Umwandung von Frames in h:m:s.frames
        s,Frames = divmod(Frames,75)
        h,s = divmod(s,3600)
        m,s=divmod(s,60)
        return "%02.f:%02.f:%02.f.%02.f" % (h, m, s, Frames)

    def sumDigits( n ):
        # Berechnet die Quersumme
        # n=123456789 => 1+2+3+4+5+6+7+8+9 = 45
        ret = 0
        for i in str(n):
            ret += int(i)
        return ret

    checksum=0
    total_length = 0
    for i in range(TrackAnzahl):
        track_length = cd_object.get_track_length(i)*75
        print "%2d - %s" % (i, getHMS_f(track_length))
        total_length += track_length

        checksum += sumDigits( int(cd_object.get_track_start( i )) )

    print "\nTotalZeit: %s -> %dsek." % (getHMS_f(total_length), round(total_length/75))

    return (long(checksum % 0xff) << 24) + (long(total_length/75) << 8) + TrackAnzahl

cdrom.init()
cd_object=cdrom.CD(0)

print "Initialisierte..."
cd_object.init()

RAW_ID = getDiskId( cd_object )

print "RAW_ID......:",RAW_ID
print "freedb ID...: %08lx" % RAW_ID
Wobei... Ist es eigentlich ok, wenn man eine Funktion in einer Funktion packt??? Ich meine, eigentlich ist es praktisch, wenn man diese Funktion nur "lokal" braucht...
Um das selbe zu erreichen hätte ich normalerweise jetzt wieder eine Klasse draus gemacht...


Jetzt muß ich "nur" noch die eigentliche freedb Abfrage hinbekommen... Leider klappt das mit diesem alten CDDB.py spontan nicht... Ich erhalte immer 500 None zurück :(
genrich
User
Beiträge: 91
Registriert: Sonntag 27. Juni 2004, 17:46

Mittwoch 10. November 2004, 10:35

So... Hab nun eine Abfrage fertig...

Code: Alles auswählen

#!/usr/bin/python
# -*- coding: cp1252 -*-


import urllib, string


__version__="0.1"

UserEMail="test+test"

MaxReadLines=50 # Max. zu lesende Zeilen

# Use protocol version 5 to get DYEAR and DGENRE fields.
protocol = 5
default_server = 'http://freedb.freedb.org/~cddb/cddb.cgi'

ClientInfo = "&hello=%s+%s+%s&proto=%i" % (UserEMail, __file__, __version__, protocol)


def parseFreedbInfo(txt):
    """
    Wandelt die freedb Daten in einen Dictionary um
    """
    Info={}
    for i in txt:
        zeile=string.strip(i)
        if zeile==".": break

        if zeile[0]!="#":
            Item, txt = string.split( zeile , "=", 1)
            if txt!="":
                Info[Item]=txt

    return Info


def readHeader(response):
    Line = response.readline()
    header = string.strip( Line )
    code, msg = string.split( header , " ", 1)
    return code, msg




def GenreList():
    """
    Fragt die Liste aller verfügbarer Gernes bei freedb ab
    """
    url = default_server+"?cmd=cddb+lscat"+ ClientInfo
    #~ print url
    print "Frage Liste aller Gernes ab...",
    response = urllib.urlopen(url)

    code, msg = readHeader(response)
    print code

    # alles auslesen, bis auf die letzte Zeile
    #~ lines = response.readlines()[:-1]
    Genres = []
    for i in response.readlines()[:-1]:
        Genres.append(string.strip(i))
    return Genres


def DatenLesen(discID,AllItems=False):
    """
    Fragt die Daten zur CD bei freedb ab.
    AllItems=True  -> Es werden alle Gernes abgefragt
    AllItems=False -> Fragt nur das erste verfügbare Gerne ab
    """
    freedbInfo={}
    for Genre in GenreList():
        url = default_server+"?cmd=cddb+read+"+Genre+"+"+discID+ ClientInfo
        response = urllib.urlopen(url)

        code, msg = readHeader(response)

        print "%14s" % Genre,"-",

        if code=="210":
            print "Eintrag vorhanden!"

            freedbInfo[Genre] = parseFreedbInfo(response.readlines())

            if AllItems==False:
                # Nach dem ersten gefunden Eintrag -> abbruch
                break
        else:
            print "kein Eintrag vorhanden"

    return freedbInfo
Die Abfrage geht mit DatenLesen(freedbID)
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

Mittwoch 10. November 2004, 13:32

H genrich,
Wobei... Ist es eigentlich ok, wenn man eine Funktion in einer Funktion packt??? Ich meine, eigentlich ist es praktisch, wenn man diese Funktion nur "lokal" braucht...
Lokale Funktionen braucht man nicht oft, sind aber schon ok. Besonders wenn damit die Lesbarkeit eines Programmes erleichtert wird.


Gruß

Dookie
[code]#!/usr/bin/env python
import this[/code]
Antworten