/* copy proxy settings to waitress handle */ static void BarMainLoadProxy (const BarSettings_t *settings, WaitressHandle_t *waith) { /* set up proxy (control proxy for non-us citizen or global proxy for poor * firewalled fellows) */ if (settings->controlProxy != NULL) { /* control proxy overrides global proxy */ WaitressSetProxy (waith, settings->controlProxy); } else if (settings->proxy != NULL && strlen (settings->proxy) > 0) { WaitressSetProxy (waith, settings->proxy); } }
/* start new player thread */ static void BarMainStartPlayback (BarApp_t *app, pthread_t *playerThread) { BarUiPrintSong (&app->settings, app->playlist, app->curStation->isQuickMix ? PianoFindStationById (app->ph.stations, app->playlist->stationId) : NULL); if (app->playlist->audioUrl == NULL) { BarUiMsg (&app->settings, MSG_ERR, "Invalid song url.\n"); } else { /* setup player */ memset (&app->player, 0, sizeof (app->player)); WaitressInit (&app->player.waith); WaitressSetUrl (&app->player.waith, app->playlist->audioUrl); /* set up global proxy, player is NULLed on songfinish */ if (app->settings.proxy != NULL) { WaitressSetProxy (&app->player.waith, app->settings.proxy); } app->player.gain = app->playlist->fileGain; if ( !app->mute ) { app->player.scale = BarPlayerCalcScale (app->player.gain + app->settings.volume); } app->player.audioFormat = app->playlist->audioFormat; app->player.settings = &app->settings; pthread_mutex_init (&app->player.pauseMutex, NULL); pthread_cond_init (&app->player.pauseCond, NULL); /* throw event */ BarUiStartEventCmd (&app->settings, "songstart", app->curStation, app->playlist, &app->player, app->ph.stations, PIANO_RET_OK, WAITRESS_RET_OK); BarDownloadStart(app); /* prevent race condition, mode must _not_ be FREED if * thread has been started */ app->player.mode = PLAYER_STARTING; /* start player */ pthread_create (playerThread, NULL, BarPlayerThread, &app->player); } }
/* authenticate user */ static bool BarMainLoginUser (BarApp_t *app) { PianoReturn_t pRet; WaitressReturn_t wRet; PianoRequestDataLogin_t reqData; bool ret; #if 0 WaitressHandle_t waithSync; char *syncTime; unsigned long int syncTimeInt; /* skip sync step by fetching time from somewhere else */ WaitressInit (&waithSync); WaitressSetUrl (&waithSync, "http://ridetheclown.com/s2/synctime.php"); if (app->settings.proxy != NULL && strlen (app->settings.proxy) > 0) { WaitressSetProxy (&waithSync, app->settings.proxy); } wRet = WaitressFetchBuf (&waithSync, &syncTime); WaitressFree (&waithSync); if (wRet != WAITRESS_RET_OK) { BarUiMsg (&app->settings, MSG_ERR, "Unable to sync: %s\n", WaitressErrorToStr (wRet)); return false; } syncTimeInt = strtoul (syncTime, NULL, 0); app->ph.timeOffset = time (NULL) - syncTimeInt; free (syncTime); #endif app->ph.timeOffset = -30239998; /* woo! magic number */ reqData.user = app->settings.username; reqData.password = app->settings.password; reqData.step = 0; BarUiMsg (&app->settings, MSG_INFO, "Login... "); ret = BarUiPianoCall (app, PIANO_REQUEST_LOGIN, &reqData, &pRet, &wRet); BarUiStartEventCmd (&app->settings, "userlogin", NULL, NULL, &app->player, NULL, pRet, wRet); return ret; }
int BarFlyInit(BarSettings_t const* settings) { char const* const PATH_SEPARATORS = "/"; int exit_status = 0; int status; bool statusb; char* component; char* path = NULL; char* proxy = NULL; assert(settings != NULL); assert(settings->audioFileDir != NULL); /* * Initialize the Waitress handle. */ WaitressInit(&fly_waith); if (settings->controlProxy != NULL) { proxy = settings->controlProxy; } else if (settings->proxy != NULL) { proxy = settings->proxy; } if (proxy != NULL) { statusb = WaitressSetProxy(&fly_waith, proxy); if (!statusb) { BarUiMsg(settings, MSG_ERR, "Could not set proxy (proxy = '%s').\n", proxy); } } /* * Create the audio file directory and change into it. */ path = strdup(settings->audioFileDir); if (path == NULL) { BarUiMsg(settings, MSG_ERR, "Out of memory.\n"); goto error; } if (path[0] == '/') { status = chdir("/"); if (status != 0) { BarUiMsg(settings, MSG_ERR, "Could not create the audio file directory (%s).\n", path); goto error; } } component = strtok(path, PATH_SEPARATORS); while (component != NULL) { if ((strcmp(component, ".") == 0) || (strcmp(component, "") == 0)) { /* * This is the current directory. Do Nothing. */ } else if (strcmp(component, "..") == 0) { /* * Just change back up one directory. */ status = chdir(".."); if (status != 0) { BarUiMsg(settings, MSG_ERR, "Could not create the audio file " "directory (%s).\n", path); goto error; } } else { /* * Create the component of the path and change into it. */ status = mkdir(component, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); if ((status != 0) && (errno != EEXIST)) { BarUiMsg(settings, MSG_ERR, "Could not create the audio file " "directory (%s).\n", path); goto error; } status = chdir(component); if (status != 0) { BarUiMsg(settings, MSG_ERR, "Could not create the audio file " "directory (%s).\n", path); goto error; } } component = strtok(NULL, PATH_SEPARATORS); } goto end; error: exit_status = -1; end: if (path != NULL) { free(path); } return exit_status; }
/* start new player thread */ static void BarMainStartPlayback (BarApp_t *app, pthread_t *playerThread) { PianoReturn_t pRet; WaitressReturn_t wRet; /* is this an advertising track? */ if (app->playlist->adToken != NULL) { PianoRequestDataGetAdMetadata_t adReqData; adReqData.token = app->playlist->adToken; adReqData.quality = app->settings.audioQuality; BarUiMsg (&app->settings, MSG_INFO, "Fetching ads with token %s... ", adReqData.token); BarUiPianoCall (app, PIANO_REQUEST_GET_AD_METADATA, &adReqData, &pRet, &wRet); /* got token? */ if (adReqData.retTokenCount > 0) { PianoRequestDataRegisterAd_t regReqData; regReqData.token = adReqData.retToken; regReqData.tokenCount = adReqData.retTokenCount; regReqData.station = app->curStation; BarUiMsg (&app->settings, MSG_INFO, "Registering ad... "); BarUiPianoCall (app, PIANO_REQUEST_REGISTER_AD, ®ReqData, &pRet, &wRet); // change the current song to the actual audio ad url app->playlist->audioUrl = adReqData.audioUrl; // you can configure to get silence instead of ads or you can choose // to hear the ads. The default is silence if (app->settings.silenceAds) { app->playlist->fileGain = -999; app->playlist->title = strdup("Audio Ad (Silenced)"); } else { app->playlist->fileGain = adReqData.fileGain; app->playlist->title = strdup("Audio Ad"); } app->playlist->audioFormat = adReqData.audioFormat; app->playlist->artist = strdup("advertiser"); app->playlist->album = strdup("pianobar"); /* delete */ for (size_t i = 0; i < adReqData.retTokenCount; i++) { free (adReqData.retToken[i]); } free (adReqData.retToken); } } BarUiPrintSong (&app->settings, app->playlist, app->curStation->isQuickMix ? PianoFindStationById (app->ph.stations, app->playlist->stationId) : NULL); if (app->playlist->audioUrl == NULL) { BarUiMsg (&app->settings, MSG_ERR, "Invalid song url.\n"); } else { /* setup player */ memset (&app->player, 0, sizeof (app->player)); WaitressInit (&app->player.waith); WaitressSetUrl (&app->player.waith, app->playlist->audioUrl); /* set up global proxy, player is NULLed on songfinish */ if (app->settings.proxy != NULL) { WaitressSetProxy (&app->player.waith, app->settings.proxy); } app->player.gain = app->playlist->fileGain; app->player.scale = BarPlayerCalcScale (app->player.gain + app->settings.volume); app->player.audioFormat = app->playlist->audioFormat; app->player.settings = &app->settings; pthread_mutex_init (&app->player.pauseMutex, NULL); pthread_cond_init (&app->player.pauseCond, NULL); /* throw event */ BarUiStartEventCmd (&app->settings, "songstart", app->curStation, app->playlist, &app->player, app->ph.stations, PIANO_RET_OK, WAITRESS_RET_OK); /* prevent race condition, mode must _not_ be FREED if * thread has been started */ app->player.mode = PLAYER_STARTING; /* start player */ pthread_create (playerThread, NULL, BarPlayerThread, &app->player); } }