From 524abb97453f2140fcd3a7fa66d9d43851af19e1 Mon Sep 17 00:00:00 2001 From: Lars-Dominik Braun Date: Wed, 6 Jun 2012 21:13:43 +0200 Subject: piano: Select quality instead of audio format MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Pandora limited the audio formats we can request explicitly. Don’t rely on this and use the formats available with the given partner credentials. Closes #271. --- src/libpiano/piano.c | 4 ++++ src/libpiano/piano.h | 12 +++++++++--- src/libpiano/request.c | 31 ------------------------------- src/libpiano/response.c | 35 +++++++++++++++++++++++++++++++++-- 4 files changed, 46 insertions(+), 36 deletions(-) (limited to 'src/libpiano') diff --git a/src/libpiano/piano.c b/src/libpiano/piano.c index 74ab3ed..042121e 100644 --- a/src/libpiano/piano.c +++ b/src/libpiano/piano.c @@ -254,6 +254,10 @@ const char *PianoErrorToStr (PianoReturn_t ret) { return "Wrong email address or password."; break; + case PIANO_RET_QUALITY_UNAVAILABLE: + return "Selected audio quality is not available."; + break; + /* pandora error messages */ case PIANO_RET_P_INTERNAL: return "Internal error."; diff --git a/src/libpiano/piano.h b/src/libpiano/piano.h index d8bebcc..4ea164d 100644 --- a/src/libpiano/piano.h +++ b/src/libpiano/piano.h @@ -65,10 +65,15 @@ typedef enum { PIANO_AF_UNKNOWN = 0, PIANO_AF_AACPLUS = 1, PIANO_AF_MP3 = 2, - PIANO_AF_MP3_HI = 3, - PIANO_AF_AACPLUS_LO = 4, } PianoAudioFormat_t; +typedef enum { + PIANO_AQ_UNKNOWN = 0, + PIANO_AQ_LOW = 1, + PIANO_AQ_MEDIUM = 2, + PIANO_AQ_HIGH = 3, +} PianoAudioQuality_t; + typedef struct PianoSong { char *artist; char *stationId; @@ -178,7 +183,7 @@ typedef struct { typedef struct { PianoStation_t *station; - PianoAudioFormat_t format; + PianoAudioQuality_t quality; PianoSong_t *retPlaylist; } PianoRequestDataGetPlaylist_t; @@ -245,6 +250,7 @@ typedef enum { PIANO_RET_CONTINUE_REQUEST = 3, PIANO_RET_OUT_OF_MEMORY = 4, PIANO_RET_INVALID_LOGIN = 5, + PIANO_RET_QUALITY_UNAVAILABLE = 6, /* pandora error codes */ PIANO_RET_P_INTERNAL = PIANO_RET_OFFSET+0, diff --git a/src/libpiano/request.c b/src/libpiano/request.c index 35124f4..871620d 100644 --- a/src/libpiano/request.c +++ b/src/libpiano/request.c @@ -36,34 +36,6 @@ THE SOFTWARE. #include "piano.h" #include "crypt.h" -/* convert audio format id to string - * @param format id - * @return constant string - */ -static const char *PianoAudioFormatToString (PianoAudioFormat_t format) { - switch (format) { - case PIANO_AF_AACPLUS_LO: - return "HTTP_32_AACPLUS"; - break; - - case PIANO_AF_AACPLUS: - return "HTTP_64_AACPLUS"; - break; - - case PIANO_AF_MP3: - return "HTTP_128_MP3"; - break; - - case PIANO_AF_MP3_HI: - return "HTTP_192_MP3"; - break; - - default: - return NULL; - break; - } -} - /* prepare piano request (initializes request type, urlpath and postData) * @param piano handle * @param request structure @@ -156,14 +128,11 @@ PianoReturn_t PianoRequest (PianoHandle_t *ph, PianoRequest_t *req, assert (reqData != NULL); assert (reqData->station != NULL); assert (reqData->station->id != NULL); - assert (reqData->format != PIANO_AF_UNKNOWN); req->secure = true; json_object_object_add (j, "stationToken", json_object_new_string (reqData->station->id)); - json_object_object_add (j, "additionalAudioUrl", - json_object_new_string (PianoAudioFormatToString (reqData->format))); method = "station.getPlaylist"; break; diff --git a/src/libpiano/response.c b/src/libpiano/response.c index 73b223a..659ed2d 100644 --- a/src/libpiano/response.c +++ b/src/libpiano/response.c @@ -228,6 +228,7 @@ PianoReturn_t PianoResponse (PianoHandle_t *ph, PianoRequest_t *req) { assert (req->responseData != NULL); assert (reqData != NULL); + assert (reqData->quality != PIANO_AQ_UNKNOWN); json_object *items = json_object_object_get (result, "items"); assert (items != NULL); @@ -245,7 +246,37 @@ PianoReturn_t PianoResponse (PianoHandle_t *ph, PianoRequest_t *req) { continue; } - song->audioUrl = PianoJsonStrdup (s, "additionalAudioUrl"); + /* get audio url based on selected quality */ + static const char *qualityMap[] = {"", "lowQuality", "mediumQuality", + "highQuality"}; + assert (reqData->quality < sizeof (qualityMap)/sizeof (*qualityMap)); + static const char *formatMap[] = {"", "aacplus", "mp3"}; + json_object *map = json_object_object_get (s, "audioUrlMap"); + assert (map != NULL); + + if (map != NULL) { + map = json_object_object_get (map, qualityMap[reqData->quality]); + + if (map != NULL) { + const char *encoding = json_object_get_string ( + json_object_object_get (map, "encoding")); + assert (encoding != NULL); + for (size_t k = 0; k < sizeof (formatMap)/sizeof (*formatMap); k++) { + if (strcmp (formatMap[k], encoding) == 0) { + song->audioFormat = k; + break; + } + } + song->audioUrl = PianoJsonStrdup (map, "audioUrl"); + } else { + /* requested quality is not available */ + ret = PIANO_RET_QUALITY_UNAVAILABLE; + free (song); + PianoDestroyPlaylist (playlist); + goto cleanup; + } + } + song->artist = PianoJsonStrdup (s, "artistName"); song->album = PianoJsonStrdup (s, "albumName"); song->title = PianoJsonStrdup (s, "songName"); @@ -255,7 +286,6 @@ PianoReturn_t PianoResponse (PianoHandle_t *ph, PianoRequest_t *req) { song->detailUrl = PianoJsonStrdup (s, "songDetailUrl"); song->fileGain = json_object_get_double ( json_object_object_get (s, "trackGain")); - song->audioFormat = reqData->format; switch (json_object_get_int (json_object_object_get (s, "songRating"))) { case 1: @@ -665,6 +695,7 @@ PianoReturn_t PianoResponse (PianoHandle_t *ph, PianoRequest_t *req) { } } +cleanup: json_object_put (j); return ret; -- cgit v1.2.3