Inside Last.FM: Bestimmten Titel direkt downloaden
Bevor ich dieses Thema weiter ausführe, will ich sagen, dass ich ungeheure Skrupel davor habe, in irgendeinem Programm jemals dieses Feature zu implementieren. Theoretisch ist es möglich, praktisch wird die Grauzone, die Last.FM ohnehin umgibt, um ein Vielfaches dunkler…
Es ist möglich, Titel vollständig, ganz gezielt und ohne Anmeldung von Last.FM herunterzuladen!
Hierfür verwendet man zwei Funktionen des APIs: track.getInfo und playlist.fetch. Die erste holt die Last.FM-ID des Titels, die zweite findet die Download-URL. Und zwar folgendermaßen:
Ausgehend von Interpret und Titel rufen wir via REST die Funktion track.getInfo auf:
http://ws.audioscrobbler.com/2.0/?method=track.getinfo&api_key=[APIKey]&artist=[Interpret]&track=[Titel]
Also z.B. “The Ballad of the RAA” von “The Rural Alberta Advantage” mit dem auf der API-Seite angegebenen Key:
http://ws.audioscrobbler.com/2.0/?method=track.getinfo&api_key=b25b959554ed76058ac220b7b2e0a026&artist=the+rural+alberta+advantage&track=the+ballad+of+the+raa
Wir erhalten folgende Antwort (XML):
<?xml version="1.0" encoding="utf-8"?> <lfm status="ok"> <track> <id>170204242</id> <name>The Ballad of The RAA</name> <mbid></mbid> <url>http://www.last.fm/music/The+Rural+Alberta+Advantage/_/The+Ballad+of+The+RAA</url> <duration>207000</duration> <streamable fulltrack="1">1</streamable> <listeners>2310</listeners> <playcount>12794</playcount> <artist> <name>The Rural Alberta Advantage</name> <mbid></mbid> <url>http://www.last.fm/music/The+Rural+Alberta+Advantage</url> </artist> ... </track> </lfm>
Uns interessieren die beiden hervorgehobenen Stellen: die erste liefert die gesuchte ID, die zweite sagt uns, ob der Track in voller Länge anhörbar ist. Nur wenn diese Zeile genau so (fulltrack=”1″) aussieht, funktioniert die hier beschriebene Methode!
Jetzt rufen wir playlist.fetch mithilfe dieser ID auf, indem wir die Playlist “lastfm://playlist/track/[ID]” verlangen:
http://ws.audioscrobbler.com/2.0/?method=playlist.fetch&api_key=[APIKey]&playlistURL=lastfm://playlist/track/[ID]&streaming=1&fod=1&api_sig=[Signatur]&sk=[Session]
- Alle Parameter (auch api_key!) alphabetisch ordnen.
- Parameternamen und -werte ohne Trennzeichen hintereinanderschreiben.
- API-Secret anhängen.
- MD5-Hash bilden.
Also bei uns bekäme man die Signatur allgemein mit (ohne Zeilenumbruch):
MD5(api_key[APIKey]fod1methodplaylist.fetchplaylistURLlastfm://playlist/track/[ID] sk[Session]streaming1[APISecret])
Wenn ich das so betrachte, ist die Signatur für die meisten derjenigen, die diese Methode hier angewandt haben nicht ohne weiteres zu erstellen und erfüllt somit wohl ihren Zweck.
Man bräuchte, um erfolgreich zu sein, einen Account bei Last.FM und einen API-Schlüssel. Beides ist kostenlos verfügbar, der Aufwand erhöht sich durch das Erstellen der Signatur und dem vorherigen Aufruf von auth.getMobileSession aber ungemein.
Der Parameter “streaming=1″ ist wichtig, da nur so auch der Pfad zur entsprechenden Datei übermittelt wird; “fod=1″ erweitert anscheinend unsere Zugriffsberechtigung von “Vorschau” auf “Ganzer Titel, falls verfügbar”. Für unseren Titel senden wir also
http://ws.audioscrobbler.com/2.0/?method=playlist.fetch&api_key=b25b959554ed76058ac220b7b2e0a026&playlistURL=lastfm://playlist/track/170204242&streaming=1&fod=1&api_sig=…&sk=…
und erhalten als Antwort so etwas wie:
<?xml version="1.0" encoding="utf-8"?> <lfm status="ok"> <playlist version="1" xmlns="http://xspf.org/ns/0/"> <title>The Ballad of The RAA</title> <creator>lastfm</creator> <link rel="http://www.lastfm/allflp"></link> <trackList> <track> <location>http://play.last.fm/anon/84c5974616cab2aadc698096893ee9d7.mp3</location> <id>170204242</id> <title>The Ballad of The RAA</title> <album></album> <creator>The Rural Alberta Advantage</creator> <duration>207000</duration> <extension application="http://www.last.fm"> <fullduration>207000</fullduration> <trackauth>9c1a1</trackauth> <artistpage>http://www.last.fm/music/The+Rural+Alberta+Advantage</artistpage> <albumpage></albumpage> <trackpage> http://www.last.fm/music/The+Rural+Alberta+Advantage/_/The+Ballad+of+The+RAA </trackpage> <buyTrackURL>...</buyTrackURL> <buyAlbumURL>...</buyAlbumURL> <freeTrackURL></freeTrackURL> <fodlimit></fodlimit> <license>arp</license> </extension> <image>http://userserve-ak.last.fm/serve/126s/19603485.jpg</image> </track> </trackList> </playlist> </lfm>
Und voilà, die hervorgehobene Zeile zeigt uns, wo wir die gesuchte Datei finden. Ist der Track nicht vollständig abspielbar erhalten wir immerhin die 30-Sekunden-Vorschau, aber wer will die schon…
Nun, das sind genug Informationen, dass jeder, der ein wenig Ahnung von Programmierung hat, sich einen eigenen Client zusammenbasteln kann, der gezielt bestimmte Titel herunterlädt. Auch eine Website ließe sich ohne weitere Probleme aufbauen, die zu den Eingaben “Interpret” und “Titel” die entsprechende URL findet.
Ich brauche Meinungen dazu…
P.S.: The Rural Alberta Advantage ist eine Indie-Band aus Kanada, die meiner Meinung nach Unterstützung verdient hat. Dementsprechend habe ich mir auch auf der Website der Band deren Album “Hometowns” gekauft. Sehr zu empfehlen!
Update (22.04.2009): Diese Methode habe ich als eines der Beispiel-Scripts für Lapicon implementiert.
Update (05.08.2009):
Last.FM hat einige Änderungen durchgeführt, die die Verwendung dieser Methode für jeden, der sie von Hand anwendet, sehr erschweren. Eine Implementierung in einem Programm wäre aber ohne weiteres möglich. (Es gibt meines Wissens auch einige Programme, die bisher auf diesem Weg an Musik gekommen sind. Die werden bestimmt angepasst. Nur bevor jemand mich darum bittet, sowas zu schreiben^^)
Hallo Yannick,
per Grundsatz finde ich die beschriebene Möglichkeit nett, denn es wäre die Verheiratung von Lea und LastSharp und würde somit ein gezieltes Ausprobieren von neuer Musik ermöglichen.
Wenn ich mir mal mein “LastSharp-Nutzerprofil” so betrachte, dann sieht dies bei mir wie folgt aus:
Ich lasse mir oft Musik von LastFM empfehlen. Die kommt dann auf eine SD-Karte und wird im Auto gehört, wenn man mal wieder länger unterwegs ist. Das was gefällt, wird dann ggf. gezielt nachgeladen, um einen Gesamteindruck zu bekommen (man mag ja nicht das berühmte One-Hit-Wonder kaufen).
Was gefällt, wird dann gekauft, denn mir persönlich ist MP3 mit 128 kBit zu wenig und ferner finde ich es nur sozial und gerecht, wenn ich Dienstleistung anderer (also die Erstellung von Musik, die ich wiederum wirklich nutze und nicht verwerfe) auch vergüte. Ich bin selber Dienstleister und erwarte dies auch von meinen Kunden. Ergo muß ich dies auch umgekehrt respektieren.
Betrachtet man Deine oben angerissene Diskussion aus diesen subjektiven Blickwinkel, dann finde ich es absolut ok, diese “Grauzone” zu nutzen.
Wenn ich aber an den potentiellen Missbrauch denke, dann ist mir auch klar, daß dies unter sozialen Gesichtspunkten nicht ok sein kann. Rechtlich kann ich es Nicht-Jurist nicht bewerten.
Viele Grüße,
Stefan
Stefan
6 Mrz 09 at 11:24
Ja, Stefan, ich kann dir in allen Punkten zustimmen: auch mir sind 128kbit viel zu wenig (in letzter Zeit setze ich auf Lossless-Formate wie FLAC – man hört den Unterschied wirklich deutlich!) und ich bin ebenfalls der Ansicht, dass die, die Musik machen, auch verdient haben, etwas dafür zu bekommen. (Meine Kaufstatistik: 30CDs in den letzten 4 Monaten – ist wohl das schlechte Gewissen…)
Rechtlich gesehen: selbst wenn Streaming plötzlich als Kopierschutz gelten sollte, verwende ich hier doch nur die von Last.FM angebotenen, öffentlich zugänglichen Funktionen, um eine ungeschützte Datei von einer offensichtlich legalen Quelle herunterzuladen. Ob man daraus einen Strick drehen kann?
Last.FM ist ideal zum Reinhören und zum Erweitern des musikalischen Horizonts. Aber wer sich mit dieser Qualität der Titel zufrieden gibt, hätte ohnehin nicht vorgehabt, sich eine CD zu kaufen… Meine Meinung.
Was ich daraus jetzt mache, weiß ich immer noch nicht. Einen Lastsharp-Extra-TuneIn-Modus? Ein kleines Zusatzprogramm? Eine Website? (Die wiederum wäre schon fertig, allerdings funktioniert sie nur auf einem Server, der PHP5 unterstützt und Verbindungen zu anderen Websites zulässt. Und so nen Server hab ich nicht.)
Mal sehn, mal sehn…
Yannick
xsc
6 Mrz 09 at 17:08
Ehrliche Meinung? ich bin dagegen.
Diese ausdrückliche dafür vorhandene Funktion führt m.E. nur dazu, daß Deine Programme in eine fragwürdige Ecke gerückt werden.
Und vor allem: wozu das Risiko? Wer einen bestimmten Titel will, der kann das über etwas Konfigurationsarbeit auch jetzt schon mit LastSharp: man füllt ein Playlist mit etwa 150 streambaren Titeln von etwa 20 verschiedenen Interpreten (die man niemals hören möchte) und schließt diese Interpreten mit einem komplexen Filter aus. Fügt man dann auch nur einen einzigen Titel zur Playlist hinzu, lädt mir LastSharp genau den und sonst nichts. Der einzige Aufwand nach der erstmaligen Konfiguration und Playlist-Erstellung wäre das Hinzufügen und hinterher wieder Löschen von der Playlist (wobei letzteres nicht mal notwendig wäre).
Aber letztendlich: wer einen bestimmten Titel haben möchte, der geht zu Blogsearchern wie Deezer, Dizzler, Seeqpod, Imeem oder Songza. Da findet man auch Titel, die last.fm gar nicht streamable hat.
LastSharp finde ich vielmehr geeignet für das Kennenlernen neuer Musik ohne online zu sein. Und damit die Möglichkeit nicht durch eine zu offensichtliche Funktion gefährdet wird, würde ich auf diese Direkt-Download-Funktion verzichten.
Jobo
6 Mrz 09 at 19:25
@Jobo:
Ja, das ist eben der Konflikt zwischen Benutzerfreundlichkeit, Komfort, Legalität und Semi-Legalität. Ich werde auf das Feature verzichten, auch auf die Gefahr hin, User an ein evtl. diese Methode implementierendes Programm zu verlieren. Aber zumindest kann ich das als tiefergehenden Einblick in Last.FM auf meinem Konto verbuchen – wie löblich das auch immer sein mag…
Yannick
xsc
7 Mrz 09 at 00:34
Recht habt Ihr!
In letzter Konsequenz würde man ein tolles Produkt für einen Funken Komfort nur in eine noch dunklere Grauzone bewegen. Das Risiko muss man wahrlich nicht eingehen.
Stefan
Stefan
10 Mrz 09 at 10:45
Huhu,
hätt da ne kleine frage, is zwar eig. OT aber hoffe mal das ihr mir helfen könnt.
Hab gestern last.fm zufällig entdeckt fands auch super soweit bis ich dann am playlist aspielen gescheitert bin bzw. das ding dazu zu bringen mehr als 1 titel zu spielen. Beim googlen dann über LastSharp gestolpert
was aber auch nich das gemacht hat was ich wollte ^^
meine playlist etc. findet der erst gar nicht und wenn ich über tag’s suche kommt bei jedem zweiten begriff ne fehlermeldung
*
Es ist ein Problem beim TuneIn aufgetreten:
Response:
response=FAILED
error=1
*
letztendlich bin ich dann hier gelandet aber das mit dem einzelnd runterladen is mir dann doch zu aufwendig
(tüddel schon seit gestern abend da dran rum…)dann auch noch für lieder die ich evtl. nur 2-3 mal anhöhre
naja wollt eig nur mal was anderes höhren als was meine CD’s hergeben
hab bestimmt nur irgendwo nen shice häkchen/kreuz/hebel/knopf, was auch immer, übersehn.
Also wenns da irgendne möglichkeit gibt musik zu höhren ohne ständig play/skip drücken zu müssen
mfg
hustensaft
11 Mrz 09 at 10:23
Geht es dir jetzt ums Herunterladen oder ums Anhören? Falls letzteres: du kannst die Lieder auch im Browser abspielen, aber das weißt du wahrscheinlich… (http://www.last.fm/listen)
Um die Lieder abzuspielen, die du herunterlädtst, musst du links unten einen Haken bei “Tracks nach dem Download abspielen” und “Automatisch mit dem Download fortfahren” setzen. Dann einfach einen Download starten und es sollte gehen.
Was allerdings das vermehrte Auftreten der “response=FAILED//error=1″-Fehler bedeutet, kann ich schlicht und einfach nicht sagen. Ich blick’s nicht…
Yannick
xsc
11 Mrz 09 at 18:40
sieht aus als wäre das gar nicht mehr möglich. ich bekomm immer nur einen 500er fehler wenn ich die adresse der mp3 direkt eingebe.
Veit
18 Mrz 09 at 16:30
Habs gerade nochmals ausprobiert und es funktioniert. Irgendetwas machst du wohl falsch… Aber ohne nähere Informationen kann ich dir da nicht helfen. Die andere Frage ist dann wiederum, ob ich helfen will, angesichts der Diskussion, die über die Fragwürdigkeit dieser Methode im Gange war…
Yannick
xsc
19 Mrz 09 at 01:47
Mit der Methode kann man aber nur die Titel herunterladen, die über lastfm.de in voller Länge anhörbar sind, richtig?
Thomas
19 Mrz 09 at 21:53
Richtig. Hier wird quasi das nachgemacht, was das Last.FM-Flash-Widget tut, um an die Lieder zu kommen, die es wiedergibt. Und da das Widget auch nur vollständig anhörbare Titel auch wirklich ganz wiedergibt, klappt das nur in diesem Fall.
Yannick
xsc
21 Mrz 09 at 20:03
[...] Antwort siehe oben: “Deine neueste Playlist wird in dem Player auf deiner Profilseite erscheinen, wo die Titel von dir oder anderen Leuten, die dein Profil besuchen, einzeln gespielt oder angespielt werden können.” Man kann also als Nicht-Abonennt nicht gezielt die eigene Playlist anhören, sondern nur, wenn sie auf der eigenen Profilseite erscheint. Und wie macht das Widget das dann? So: Inside Last.FM: Bestimmten Titel direkt downloaden [...]
Inside Last.FM: LastSharp und die eigene Playlist | xscDevBlog - LastSharp & Co.
21 Apr 09 at 19:46
Das mit dem Parameter streaming=true scheint seit neuestem nicht mehr zu funktionieren. Anscheinend benötigt man jetzt auch den “api_sig” Parameter, d.h. einen mit einem API-Key und Secret signierten Request. Jedenfalls macht Last.fm das jetzt so auf seiner eigenen Website, wenn der Flash-Player ein MP3 requested.
Rearden
4 Aug 09 at 23:25
@Rearden:
Habe ich bereits mitbekommen und in meinen Programmen auch ausgebessert. Werde das hier gleich nochmal aktualisieren, von dem her: Danke für den Hinweis!
Yannick
xsc
5 Aug 09 at 00:22
Hallo Zusammen,
als Fingerübung schreibe ich imom eine Java-Anwendung, der ein Benutzername entgegen nimmt und die Tracks aus der Playlisten downloadet.
Ich habe leider noch nicht verstanden, wie die Signatur und die Session erzeugt werden.
&api_sig=[Signatur]&sk=[Session]
API Beschreibung:
http://www.lastfm.de/api/desktopauth#6
Kann jemand in eigenen Worten die Zusammenstellung Idiotensicher erklären?
Nach meinem Verständnis sieht die Signatur folgendermaßen aus:
StringBuffer strb = new StringBuffer();
strb.append(“api_key”);
strb.append(API_KEY);
strb.append(“methodauth.getSessiontoken”);
strb.append(Authenticator.getToken(API_KEY));
strb.append(API_SEC);
Handelt es sich bei der Session um diese Methode? Falls ja, bin ich mit mit dem ersten Parameter nicht sicher!
Authenticator.getSession(Authenticator.getToken(API_KEY), API_KEY, API_SECRET);
Würde mich über eine Antwort freuen
Gruß,
Michael
Michael
23 Mrz 10 at 15:42
Also ja, das sieht für mich soweit richtig aus. Die Signatur wird erstellt, indem man alle Parameter, die man senden will (inklusive “method” und “api_key”) aufsteigend ordnet und Schlüssel und Wert ohne Leerzeichen aneinander hängt, dazu noch das API Secret. Dann, nicht vergessen, den MD5 Hash davon berechnen.
D.h. für den ersten Schritt, auth.getToken, ist die Signatur:
MD5(api_key[KEY]methodauth.getToken[SECRET])
Anschließend (nachdem der/das (?) Token vom User bestätigt wurde; Punkt 3 hier – das könnte ein Grund sein, warum dein Code-Ausschnitt nicht funktionieren würde… Wenn du das öffnen des Browsers umgehen willst, nimm auth.getMobileSession!) der Aufruf zu auth.getSession mit der Signatur
MD5(api_key[KEY]methodauth.getSessiontoken[TOKEN][SECRET])
Durch diesen Aufruf erhältst du Informationen zum User (Username, Abonnent?) und den Session-Key, den du speichern musst und ab sofort als Wert für den Parameter “sk” einsetzen kannst, z.B. bei album.getTags, was die folgende Signatur brauchen würde:
MD5(album[ALBUM]api_key[KEY]artist[ARTIST]methodalbum.getTagssk[SESSION][SECRET])
Man sieht hier, dass der “album”-Parameter vor “api_key” kommt, da die Parameterliste komplett sortiert werden muss.
Ich hoffe, das stimmt und hilft.
Yannick
xsc
23 Mrz 10 at 18:56