summaryrefslogtreecommitdiff
path: root/src/libpiano
diff options
context:
space:
mode:
authorLars-Dominik Braun <lars@6xq.net>2012-06-06 21:13:43 +0200
committerLars-Dominik Braun <lars@6xq.net>2012-06-09 15:43:43 +0200
commit524abb97453f2140fcd3a7fa66d9d43851af19e1 (patch)
tree814e33a0d04137332f5a341721f96d4f8cccc9e2 /src/libpiano
parentb32348d88f700f4a3b5fb3a95f7ee40336952230 (diff)
downloadpianobar-windows-524abb97453f2140fcd3a7fa66d9d43851af19e1.tar.gz
pianobar-windows-524abb97453f2140fcd3a7fa66d9d43851af19e1.tar.bz2
pianobar-windows-524abb97453f2140fcd3a7fa66d9d43851af19e1.zip
piano: Select quality instead of audio format
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.
Diffstat (limited to 'src/libpiano')
-rw-r--r--src/libpiano/piano.c4
-rw-r--r--src/libpiano/piano.h12
-rw-r--r--src/libpiano/request.c31
-rw-r--r--src/libpiano/response.c35
4 files changed, 46 insertions, 36 deletions
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;