gboolean rbspotifysrc_get_size (GstBaseSrc *bsrc, guint64 *size) { RBSpotifySrc *src = RBSPOTIFYSRC (bsrc); // audio_fifo_t *af = &g_audio_fifo; if (sp_track_duration(src->track) > 0) { src->size = 2 * 2 * 44.100 * sp_track_duration(src->track) - 44100; *size = src->size; fprintf(stderr, "Get Size %d\n", (sp_track_duration(src->track)/1000)); return TRUE; } else { return FALSE; } }
/** * Print the given track title together with some trivial metadata * * @param track The track object */ void print_track(sp_track *track) { int duration = sp_track_duration(track); char url[256]; sp_link *l; #if WIN32 printf(" %s ", sp_track_is_starred(track) ? "*" : " "); #else printf(" %s ", sp_track_is_starred(track) ? "★" : "☆"); #endif printf("Track %s [%d:%02d] has %d artist(s), %d%% popularity", sp_track_name(track), duration / 60000, (duration / 1000) / 60, sp_track_num_artists(track), sp_track_popularity(track)); if(sp_track_disc(track)) printf(", %d on disc %d", sp_track_index(track), sp_track_disc(track)); printf("\n"); l = sp_link_create_from_track(track, 0); sp_link_as_string(l, url, sizeof(url)); printf("\t\t%s\n", url); sp_link_release(l); }
bool SpotifySong::updateMetadata() { if(sp_track_is_loaded(this->track)) { this->duration = sp_track_duration(this->track); this->title = sp_track_name(this->track); if(this->artist == nullptr) { this->artist = sp_track_artist(this->track,0); sp_artist_add_ref(this->artist); } if(this->album == nullptr) { this->album = sp_track_album(this->track); sp_album_add_ref(this->album); } } else return false; if(this->artist != nullptr && sp_artist_is_loaded(this->artist)) this->artistName = sp_artist_name(this->artist); else return false; if(this->album != nullptr && sp_album_is_loaded(this->album)) this->albumName = sp_album_name(this->album); else return false; return true; }
void AudioHTTPServer::startStreamingResponse( QxtWebRequestEvent* event, sp_track* track ) { // yay we gots a track // qDebug() << QThread::currentThreadId() << "We got a track!" << sp_track_name( track ) << sp_artist_name( sp_track_artist( track, 0 ) ) << sp_track_duration( track ); uint duration = sp_track_duration( track ); sp_error err = sp_session_player_load( SpotifySession::getInstance()->Session(), track ); if( err != SP_ERROR_OK ) { qWarning() << QThread::currentThreadId() << "Failed to start track from spotify :(" << sp_error_message( err ); sendErrorResponse( event ); return; } // qDebug() << QThread::currentThreadId() << "Starting to play!"; sp_session_player_play( SpotifySession::getInstance()->Session(), true ); SpotifySession::getInstance()->Playback()->startPlaying(); qDebug() << "Getting iodevice..."; spotifyiodev_ptr iodev = SpotifySession::getInstance()->Playback()->getIODeviceForNewTrack( duration ); // qDebug() << QThread::currentThreadId() << "Got iodevice to send:" << iodev << iodev.isNull() << iodev->isSequential() << iodev->isReadable(); QxtWebPageEvent* wpe = new QxtWebPageEvent( event->sessionID, event->requestID, iodev ); wpe->streaming = true; wpe->contentType = "audio/basic"; postEvent( wpe ); }
void play(sp_session *session, sp_track *track) { sp_error error = sp_session_player_load(session, track); if (error != SP_ERROR_OK) { fprintf(stderr, "Error: %s\n", sp_error_message(error)); exit(1); } sp_artist *artist = sp_track_artist(track, 0); sp_album *album = sp_track_album(track); int secs = sp_track_duration(track) / 1000; int mins = 0; while (secs >= 60) { mins++; secs -= 60; } printf("\n"); printf(" Track: %s\n", sp_track_name(track)); printf(" Artist: %s\n", sp_artist_name(artist)); printf(" Album: %s\n", sp_album_name(album)); printf(" Year: %d\n", sp_album_year(album)); printf(" Popularity: %d / 100\n", sp_track_popularity(track)); printf(" Duration: %02d:%02d\n", mins, secs); printf("\n"); printf("Playing...\n"); sp_session_player_play(session, 1); }
ListResponse<TrackInfo*>* SpotifyPlaylistContainer::listTracks( PlaylistTask* task) { ListResponse<TrackInfo*>* response = new ListResponse<TrackInfo*>(); response->setListType(ListTypeSong); ListPlaylistTrackInfo info = task->getCommandInfo().listPlaylistTrackInfo; int playlistId = info.playlist; if (playlistId > -1 && playlistId < sp_playlistcontainer_num_playlists(playlistContainer)) { bool sendName = ((info.trackInfoFlags & TrackInfoName) == TrackInfoName); bool sendArtist = ((info.trackInfoFlags & TrackInfoArtists) == TrackInfoArtists); bool sendAlbum = ((info.trackInfoFlags & TrackInfoAlbum) == TrackInfoAlbum); bool sendDuration = ((info.trackInfoFlags & TrackInfoDuration) == TrackInfoDuration); bool sendArtwork = ((info.trackInfoFlags & TrackInfoArtwork) == TrackInfoArtwork); sp_playlist* playlist = sp_playlistcontainer_playlist(playlistContainer, playlistId); int numTracks = sp_playlist_num_tracks(playlist); for (int i = 0; i < numTracks; i++) { TrackInfo* trackInfo = new TrackInfo(); trackInfo->id = i; sp_track* track = sp_playlist_track(playlist, i); if (sendName) { trackInfo->name = sp_track_name(track); } if (sendArtist) { trackInfo->numArtists = sp_track_num_artists(track); trackInfo->artists = new const char*[trackInfo->numArtists]; for (int j = 0; j < trackInfo->numArtists; j++) { trackInfo->artists[j] = sp_artist_name( sp_track_artist(track, j)); } } if (sendAlbum) { trackInfo->album = sp_album_name(sp_track_album(track)); } if (sendDuration) { trackInfo->duration = sp_track_duration(track); } if (sendArtwork) { trackInfo->artwork = sp_image_create(session, sp_album_cover(sp_track_album(track), SP_IMAGE_SIZE_NORMAL)); } response->addMember(trackInfo); } return response; } delete response; return nullptr; }
bool Codec::Init(const CStdString & strFile, unsigned int filecache) { m_bufferSize = 2048 * sizeof(int16_t) * 50; m_buffer = new char[m_bufferSize]; CStdString uri = URIUtils::GetFileName(strFile); CStdString extension = uri.Right(uri.GetLength() - uri.Find('.') - 1); if (extension.Left(12) == "spotifyradio") { //if its a radiotrack the radionumber and tracknumber is secretly encoded at the end of the extension CStdString trackStr = extension.Right( extension.GetLength() - extension.ReverseFind('#') - 1); Logger::printOut(extension); CStdString radioNumber = extension.Left(uri.Find('#')); Logger::printOut(radioNumber); radioNumber = radioNumber.Right( radioNumber.GetLength() - radioNumber.Find('#') - 1); Logger::printOut("loading codec radio"); RadioHandler::getInstance()->pushToTrack(atoi(radioNumber), atoi(trackStr)); } //we have a non legit extension so remove it manually uri = uri.Left(uri.Find('.')); Logger::printOut("trying to load track:"); Logger::printOut(uri); sp_link *spLink = sp_link_create_from_string(uri); m_currentTrack = sp_link_as_track(spLink); sp_track_add_ref(m_currentTrack); sp_link_release(spLink); m_endOfTrack = false; m_bufferPos = 0; m_startStream = false; m_isPlayerLoaded = false; m_TotalTime = sp_track_duration(m_currentTrack); //prefetch the next track! CPlayList& playlist = g_playlistPlayer.GetPlaylist(PLAYLIST_MUSIC); int nextSong = g_playlistPlayer.GetNextSong(); if (nextSong >= 0 && nextSong < playlist.size()){ CFileItemPtr song = playlist[nextSong]; if (song != NULL){ CStdString uri = song->GetPath(); if (uri.Left(7).Equals("spotify")){ uri = uri.Left(uri.Find('.')); Logger::printOut("prefetching track:"); Logger::printOut(uri); sp_link *spLink = sp_link_create_from_string(uri); sp_track* track = sp_link_as_track(spLink); sp_session_player_prefetch(getSession(), track); sp_link_release(spLink); } } } return true; }
void seek(list<int> int_params, list<string> string_params, sp_session *session, sp_track *track) { float position = (float)int_params.front() / 100.0; int pos_ms = (int) ((float) sp_track_duration(track) * position); if (s_is_playing) sp_session_player_play(session, false); sp_session_player_seek(session, pos_ms); if (s_is_playing) sp_session_player_play(session, true); s_player_position = pos_ms / 1000; }
void SpotWorker::loadPlayer(sp_track *track, bool rip, SoundSaver::FileType type) { totalFrames_ = sp_track_duration(track)*44; alsaWorker_->audioFifoFlush(); frameCounter_ = 0; closeFile(); if(rip) saveFile(track, type); sp_session_player_load(currentSession, track); }
void on_player_position_changed(list<int> int_params, list<string> string_params, sp_session *session, sp_track *track) { s_player_position++; int total_length = sp_track_duration(track) / 1000; float percentage = (float)s_player_position / (float)total_length; JNIEnv *env; jclass classLibSpotify = find_class_from_native_thread(&env); jmethodID methodId = env->GetStaticMethodID(classLibSpotify,"onPlayerPositionChanged","(F)V"); env->CallStaticVoidMethod(classLibSpotify, methodId, percentage); env->DeleteLocalRef(classLibSpotify); }
gboolean spop_mpris2_player_set_position(Mpris2Player* obj, GDBusMethodInvocation* invoc, const gchar* arg_TrackId, gint64 arg_Position) { g_debug("mpris2: set_position"); int pos = arg_Position / 1000; sp_track* track = NULL; queue_get_status(&track, NULL, NULL); if ((track != NULL) && (pos >= 0) && (pos <= sp_track_duration(track))) { // TODO: check arg_TrackId session_seek(pos); mpris2_player_emit_seeked(obj, pos * 1000); } mpris2_player_complete_set_position(obj, invoc); return TRUE; }
SxTrack::SxTrack(sp_track *spTrack) { // Logger::printOut("creating track"); // Logger::printOut(sp_track_name(spSxTrack)); while (!sp_track_is_loaded(spTrack)) ; //Logger::printOut("creating track loaded"); m_references = 1; m_spTrack = spTrack; m_name = sp_track_name(spTrack); m_rating = ceil((float)sp_track_popularity(spTrack) / 10); m_duration = 0.001 * sp_track_duration(spTrack); m_trackNumber = sp_track_index(spTrack); m_albumName = ""; m_albumArtistName = ""; m_year = 0; m_thumb = NULL; m_hasTHumb = false; //load the album and release it when we have harvested all data we need sp_album * album = sp_track_album(spTrack); if (sp_album_is_loaded(album)) { SxAlbum* sAlbum = AlbumStore::getInstance()->getAlbum(sp_track_album(spTrack), false); m_thumb = sAlbum->getThumb(); m_albumName = sAlbum->getAlbumName(); m_albumArtistName = sAlbum->getAlbumArtistName(); m_year = sAlbum->getAlbumYear(); //release it again AlbumStore::getInstance()->removeAlbum(sAlbum); if (m_thumb != NULL) { m_thumb->addRef(); m_hasTHumb = true; } } else Logger::printOut("no album loaded for track"); m_artistName = sp_artist_name(sp_track_artist(spTrack, 0)); sp_link *link = sp_link_create_from_track(spTrack, 0); m_uri = new char[256]; sp_link_as_string(link, m_uri, 256); sp_link_release(link); }
bool Codec::Init(const CStdString & strFile, unsigned int filecache) { m_bufferSize = 2048 * sizeof(int16_t) * 50; m_buffer = new char[m_bufferSize]; CStdString uri = URIUtils::GetFileName(strFile); CStdString extension = uri.Right(uri.GetLength() - uri.Find('.') - 1); //we have a non legit extension so remove it manually uri = uri.Left(uri.Find('.')); Logger::printOut("trying to load track:"); Logger::printOut(uri); sp_link *spLink = sp_link_create_from_string(uri); m_currentTrack = sp_link_as_track(spLink); sp_track_add_ref(m_currentTrack); sp_link_release(spLink); m_endOfTrack = false; m_bufferPos = 0; m_startStream = false; m_isPlayerLoaded = false; m_TotalTime = sp_track_duration(m_currentTrack); //prefetch the next track! CPlayList& playlist = g_playlistPlayer.GetPlaylist(PLAYLIST_MUSIC); int nextSong = g_playlistPlayer.GetNextSong(); if (nextSong >= 0 && nextSong < playlist.size()){ CFileItemPtr song = playlist[nextSong]; if (song != NULL){ CStdString uri = song->GetPath(); if (uri.Left(7).Equals("spotify")){ uri = uri.Left(uri.Find('.')); Logger::printOut("prefetching track:"); Logger::printOut(uri); sp_link *spLink = sp_link_create_from_string(uri); sp_track* track = sp_link_as_track(spLink); sp_session_player_prefetch(getSession(), track); sp_link_release(spLink); } } } return true; }
void queue_seek(guint pos) { sp_track* track; int dur; switch(g_status) { case PLAYING: case PAUSED: track = g_queue_peek_nth(&g_queue, g_current_track); dur = sp_track_duration(track); if (dur <= 0) g_warning("Can't get track duration."); else if ((pos < 0) || ((pos) >= dur)) g_info("Can't seek: value is out of range."); else session_seek(pos); break; case STOPPED: g_debug("Seek: stopped, doing nothing."); } }
// ---------------------------------------------------------------------------- // void SpotifyEngine::_startTrack( ) { if ( m_track_queue.size() ) { CSingleLock lock( &m_mutex, TRUE ); TrackQueueEntry entry = m_track_queue.front(); m_track_queue.pop_front(); m_current_track = entry.m_track; m_track_played_queue.push_back( entry ); sp_error result = sp_session_player_load( m_spotify_session, m_current_track ); if ( result != SP_ERROR_OK ) { log( "Error %d from sp_session_player_load", (INT)result ); } m_track_state = TRACK_STREAM_PENDING; m_track_length_ms = sp_track_duration( m_current_track ); m_track_seek_ms = entry.m_seek_ms > m_track_length_ms ? 0 : entry.m_seek_ms; getTrackLink( m_current_track, m_current_track_link ); if ( m_track_seek_ms != 0L ) sp_session_player_seek( m_spotify_session, m_track_seek_ms ); else if ( !haveTrackAnalysis(m_current_track_link) ) { m_analyzer = new TrackAnalyzer( &m_waveFormat, m_track_length_ms, m_current_track_link ); } if ( !isTrackPaused() ) { result = sp_session_player_play( m_spotify_session, true ); if ( result != SP_ERROR_OK ) { log( "Error %d from sp_session_player_play", (INT)result ); } } sendTrackQueueEvent(); } }
int Track::GetDuration() { int duration = sp_track_duration( m_pTrack ); return duration; }
int Track::duration() const { if(isValid()) return sp_track_duration(m_spTrack) / 1000; return 0; }
void SpotifySearch::searchComplete( sp_search *result, void *userdata ) { UserData* data = reinterpret_cast<UserData*>( userdata ); qDebug() << "Got search result for qid:" << data->qid; // we return the top 50 results for searches, just top 1 for resolve QVariantMap resp; resp[ "qid" ] = data->qid; resp[ "_msgtype" ] = "results"; QVariantList results; // TODO search by popularity! qDebug() << "Got num results:" << sp_search_num_tracks( result ); if( sp_search_num_tracks( result ) > 0 ) {// we have a result int num = qMin( sp_search_num_tracks( result ), data->fulltext ? 50 : 1 ); for( int i = 0; i < num; i++ ) { sp_track *const tr = sp_search_track( result, i ); if( !tr || !sp_track_is_loaded( tr ) ) { qDebug() << "Got still loading track, skipping"; continue; } sp_link* link = sp_link_create_from_track( tr, 0 ); QString uid = data->resolver->addToTrackLinkMap( link ); int duration = sp_track_duration( tr ) / 1000; QVariantMap track; track[ "track" ] = QString::fromUtf8( sp_track_name( tr ) ); track[ "artist" ] = QString::fromUtf8( sp_artist_name( sp_track_artist( tr, 0 ) ) ); track[ "album" ] = QString::fromUtf8( sp_album_name( sp_track_album( tr ) ) ); track[ "albumpos" ] = sp_track_index( tr ); track[ "discnumber"] = sp_track_disc( tr ); track[ "year" ] = sp_album_year( sp_track_album( tr ) ); track[ "mimetype" ] = "audio/basic"; track[ "source" ] = "Spotify"; track[ "url" ] = QString( "http://localhost:%1/sid/%2.wav" ).arg( data->resolver->port() ).arg( uid ); track[ "duration" ] = duration; track[ "score" ] = .95; // TODO track[ "bitrate" ] = 192; // TODO // 8 is "magic" number. we don't know how much spotify compresses or in which format (mp3 or ogg) from their server, but 1/8th is approximately how ogg -q6 behaves, so use that for better displaying quint32 bytes = ( duration * 44100 * 2 * 2 ) / 8; track[ "size" ] = bytes; results << track; data->searchCount = 0; //qDebug() << "Found Track:" << sp_track_name( tr ) << "\n\tReporting:" << track["url"]; } }else { QString didYouMean = QString::fromUtf8(sp_search_did_you_mean( result ) ); if(data->searchCount <= 1 ){ qDebug() << "Try nr." << data->searchCount << " Searched for" << QString::fromUtf8(sp_search_query( result ) ) << "Did you mean?"<< didYouMean; //int distance = QString::compare(QString::fromUtf8(sp_search_query( result ) ), QString::fromUtf8(sp_search_did_you_mean( result ) ), Qt::CaseInsensitive); //qDebug() << "Distance for query is " << distance;//if( distance < 4) sp_search_create( SpotifySession::getInstance()->Session(), sp_search_did_you_mean( result ) , 0, data->fulltext ? 50 : 1, 0, 0, 0, 0, &SpotifySearch::searchComplete, data ); data->searchCount++; return; } } resp[ "results" ] = results; sp_search_release( result ); data->resolver->sendMessage( resp ); }
/* only used to trigger sp_session_process_events when needed, * looks like about once a second */ static void* spotify_thread_func (void *data) { int timeout = -1; GTimeVal t; GstSpotSrc *spot = (GstSpotSrc *) data; if (!spotify_create_session (spot)) { GST_ERROR_OBJECT (spot, "Create_session error"); return FALSE; } while (spot->keep_spotify_thread) { sp_session_process_events (GST_SPOT_SRC_SPOTIFY_SESSION (spot), &timeout); g_get_current_time (&t); g_time_val_add (&t, timeout * 1000); g_cond_timed_wait (spot->process_events_cond, spot->process_events_mutex, &t); spot->spotify_thread_initiated = TRUE; while (spot->spot_works) { struct spot_work *spot_work; sp_error ret = SP_ERROR_INVALID_INDATA; spot_work = (struct spot_work *)spot->spot_works->data; g_mutex_lock (spot_work->spot_mutex); switch (spot_work->cmd) { case SPOT_CMD_START: GST_DEBUG_OBJECT (spot, "Uri = %s", GST_SPOT_SRC_URI_LOCATION (spot)); if (!spotify_login (spot)) { /* error message from within function */ break; } sp_link *link = sp_link_create_from_string (GST_SPOT_SRC_URI_LOCATION (spot)); if (!link) { GST_ERROR_OBJECT (spot, "Incorrect track ID:%s", GST_SPOT_SRC_URI_LOCATION (spot)); break; } GST_SPOT_SRC_CURRENT_TRACK (spot) = sp_link_as_track (link); if (!GST_SPOT_SRC_CURRENT_TRACK (spot)) { GST_ERROR_OBJECT (spot, "Could get track from uri=%s", GST_SPOT_SRC_URI_LOCATION (spot)); break; } #if 0 /* FIXME: why does not this work? */ if (!sp_track_is_available (GST_SPOT_SRC_CURRENT_TRACK (spot))) { /* this probably happens for tracks avaiable in other countries or something */ GST_ERROR_OBJECT (spot, "Track is not available, uri=%s", GST_SPOT_SRC_URI_LOCATION (spot)); break; } #endif sp_track_add_ref (GST_SPOT_SRC_CURRENT_TRACK (spot)); sp_link_add_ref (link); sp_session_process_events (GST_SPOT_SRC_SPOTIFY_SESSION (spot), &timeout); while (sp_track_is_loaded (GST_SPOT_SRC_CURRENT_TRACK (spot)) == 0) { sp_session_process_events (GST_SPOT_SRC_SPOTIFY_SESSION (spot), &timeout); usleep (10000); } GST_DEBUG_OBJECT (spot, "Now playing \"%s\"", sp_track_name (GST_SPOT_SRC_CURRENT_TRACK (spot))); ret = sp_session_player_load (GST_SPOT_SRC_SPOTIFY_SESSION (spot), GST_SPOT_SRC_CURRENT_TRACK (spot)); if (ret != SP_ERROR_OK) { GST_ERROR_OBJECT (spot, "Failed to load track '%s' uri=%s", sp_track_name (GST_SPOT_SRC_CURRENT_TRACK (spot)), (GST_SPOT_SRC_URI_LOCATION (spot))); break; } sp_session_process_events (GST_SPOT_SRC_SPOTIFY_SESSION (spot), &timeout); ret = sp_session_player_play (GST_SPOT_SRC_SPOTIFY_SESSION (spot), TRUE); if (ret != SP_ERROR_OK) { GST_ERROR_OBJECT (spot, "Failed to play track '%s' uri=%s", sp_track_name (GST_SPOT_SRC_CURRENT_TRACK (spot)), (GST_SPOT_SRC_URI_LOCATION (spot))); break; } break; case SPOT_CMD_PROCESS: sp_session_process_events (GST_SPOT_SRC_SPOTIFY_SESSION (spot), &timeout); break; case SPOT_CMD_PLAY: ret = sp_session_player_play (GST_SPOT_SRC_SPOTIFY_SESSION (spot), TRUE); break; case SPOT_CMD_DURATION: if (GST_SPOT_SRC_CURRENT_TRACK (spot)) { ret = sp_track_duration (GST_SPOT_SRC_CURRENT_TRACK (spot)); } break; case SPOT_CMD_STOP: if (GST_SPOT_SRC_CURRENT_TRACK (spot)) { ret = sp_session_player_play (GST_SPOT_SRC_SPOTIFY_SESSION (spot), FALSE); if (ret != SP_ERROR_OK) { break; } ret = SP_ERROR_OK; sp_session_player_unload (GST_SPOT_SRC_SPOTIFY_SESSION (spot)); } break; case SPOT_CMD_SEEK: if (GST_SPOT_SRC_CURRENT_TRACK (spot)) { ret = sp_session_player_seek (GST_SPOT_SRC_SPOTIFY_SESSION (spot), spot_work->opt); } break; default: g_assert_not_reached (); break; } /* print all errors caught and propagate to calling thread */ if (ret != SP_ERROR_OK) { GST_ERROR_OBJECT (spot, "Failed with SPOT_CMD=%d, ret=%d, error=%s", spot_work->cmd, ret, sp_error_message (ret)); } spot_work->ret = ret; spot->spot_works = g_list_remove (spot->spot_works, spot->spot_works->data); g_mutex_unlock (spot_work->spot_mutex); g_cond_broadcast (spot_work->spot_cond); } } return NULL; }
jobject createJTrackInstance(JNIEnv *env, sp_track *track) { jclass jClass; jobject trackInstance; jClass = (*env)->FindClass(env, "jahspotify/media/Track"); if (jClass == NULL) { fprintf(stderr,"jahspotify::createJTrackInstance: could not load jahnotify.media.Track\n"); return NULL; } trackInstance = (*env)->AllocObject(env,jClass); if (!trackInstance) { fprintf(stderr,"jahspotify::createJTrackInstance: could not create instance of jahspotify.media.Track\n"); return NULL; } sp_link *trackLink = sp_link_create_from_track(track,0); if (trackLink) { sp_link_add_ref(trackLink); jobject trackJLink = createJLinkInstance(env,trackLink); setObjectObjectField(env,trackInstance,"id","Ljahspotify/media/Link;",trackJLink); setObjectStringField(env,trackInstance,"title",sp_track_name(track)); setObjectIntField(env,trackInstance,"length",sp_track_duration(track)); setObjectIntField(env,trackInstance,"popularity",sp_track_popularity(track)); setObjectIntField(env,trackInstance,"trackNumber",sp_track_index(track)); sp_album *album = sp_track_album(track); if (album) { sp_album_add_ref(album); sp_link *albumLink = sp_link_create_from_album(album); if (albumLink) { sp_link_add_ref(albumLink); jobject albumJLink = createJLinkInstance(env,albumLink); jmethodID jMethod = (*env)->GetMethodID(env,jClass,"setAlbum","(Ljahspotify/media/Link;)V"); if (jMethod == NULL) { fprintf(stderr,"jahspotify::createJTrackInstance: could not load method setAlbum(link) on class Track\n"); return NULL; } // set it on the track (*env)->CallVoidMethod(env,trackInstance,jMethod,albumJLink); sp_link_release(albumLink); } int numArtists = sp_track_num_artists(track); if (numArtists > 0) { jmethodID jMethod = (*env)->GetMethodID(env,jClass,"addArtist","(Ljahspotify/media/Link;)V"); if (jMethod == NULL) { fprintf(stderr,"jahspotify::createJTrackInstance: could not load method addArtist(link) on class Track\n"); return NULL; } int i = 0; for (i = 0; i < numArtists; i++) { sp_artist *artist = sp_track_artist(track,i); if (artist) { sp_artist_add_ref(artist); sp_link *artistLink = sp_link_create_from_artist(artist); if (artistLink) { sp_link_add_ref(artistLink); jobject artistJLink = createJLinkInstance(env,artistLink); // set it on the track (*env)->CallVoidMethod(env,trackInstance,jMethod,artistJLink); sp_link_release(artistLink); } sp_artist_release(artist); } } } sp_album_release(album); } sp_link_release(trackLink); } return trackInstance; }
static PyObject * Track_duration(Track * self) { return Py_BuildValue("i", sp_track_duration(self->_track)); }
static void SP_CALLCONV search_complete(sp_search *search, void *userdata) { JNIEnv *env; jclass classLibspotify = find_class_from_native_thread(&env); string &qid = *static_cast<string*>(userdata); jstring j_qid = env->NewStringUTF(qid.c_str()); bool success = (sp_search_error(search) == SP_ERROR_OK) ? true : false; int count = sp_search_num_tracks(search); jstring j_trackname; jstring j_trackuri; jstring j_albumname; jstring j_artistname; sp_track *track; for (int i=0;i< count;i++){ track = sp_search_track(search, i); if (track != 0 && sp_track_error(track) == SP_ERROR_OK){ const char *temp = sp_track_name(track); if (temp != 0 && strlen(temp) != 0){ j_trackname = env->NewStringUTF(temp); } int trackDuration = sp_track_duration(track); if (sp_track_error(track) != SP_ERROR_OK) log("sp_track_error: %s",sp_error_message(sp_track_error(track))); int trackDiscnumber = sp_track_disc(track); if (sp_track_error(track) != SP_ERROR_OK) log("sp_track_error: %s",sp_error_message(sp_track_error(track))); int trackIndex = sp_track_index(track); if (sp_track_error(track) != SP_ERROR_OK) log("sp_track_error: %s",sp_error_message(sp_track_error(track))); char buffer [64]; sp_link *link = sp_link_create_from_track(track, 0); if (link != 0){ sp_link_as_string(link, buffer, 64); } j_trackuri = env->NewStringUTF(buffer); sp_album *album = sp_track_album(track); if (sp_track_error(track) != SP_ERROR_OK) log("sp_track_error: %s",sp_error_message(sp_track_error(track))); int albumYear = 0; if (album != 0){ temp = sp_album_name(album); albumYear = sp_album_year(album); if (temp != 0 && strlen(temp) != 0){ j_albumname = env->NewStringUTF(temp); } } sp_artist *artist = sp_track_artist(track,0); if (sp_track_error(track) != SP_ERROR_OK) log("sp_track_error: %s",sp_error_message(sp_track_error(track))); if (artist != 0){ temp = sp_artist_name(artist); if (temp != 0 && strlen(temp) != 0){ j_artistname = env->NewStringUTF(temp); } } jmethodID methodIdAddResult = env->GetStaticMethodID(classLibspotify, "addResult", "(Ljava/lang/String;Ljava/lang/String;IIILjava/lang/String;Ljava/lang/String;ILjava/lang/String;)V"); env->CallStaticVoidMethod(classLibspotify, methodIdAddResult, j_qid, j_trackname, trackDuration, trackDiscnumber, trackIndex, j_trackuri, j_albumname, albumYear, j_artistname); if (env->ExceptionCheck()) { env->ExceptionDescribe(); env->ExceptionClear(); } env->DeleteLocalRef(j_trackname); env->DeleteLocalRef(j_trackuri); env->DeleteLocalRef(j_artistname); env->DeleteLocalRef(j_albumname); j_trackname = NULL; j_trackuri = NULL; j_artistname = NULL; j_albumname = NULL; } } jmethodID methodIdOnResolved = env->GetStaticMethodID(classLibspotify, "onResolved", "(Ljava/lang/String;ZLjava/lang/String;Ljava/lang/String;)V"); jstring j_error = env->NewStringUTF(sp_error_message(sp_search_error(search))); jstring j_didyoumean = env->NewStringUTF(sp_search_did_you_mean(search)); env->CallStaticVoidMethod(classLibspotify, methodIdOnResolved, j_qid, success, j_error, j_didyoumean); if (env->ExceptionCheck()) { env->ExceptionDescribe(); env->ExceptionClear(); } env->DeleteLocalRef(classLibspotify); env->DeleteLocalRef(j_qid); env->DeleteLocalRef(j_error); env->DeleteLocalRef(j_didyoumean); log("Finished resolving query:'%s', success'%s', track count:'%d', qid:'%s'", sp_search_query(search), (success?"true":"false"), count, qid.c_str()); sp_search_release(search); delete &qid; }
void track_get_data(sp_track* track, gchar** name, gchar** artist, gchar** album, gchar** link, guint* duration, int* popularity) { sp_artist** art = NULL; sp_album* alb = NULL; sp_link* lnk; int i; int nb_art = 0; const char* s; sp_track_add_ref(track); if (!sp_track_is_loaded(track)) { sp_track_release(track); return; } /* Begin loading everything */ if (name) { *name = g_strdup(sp_track_name(track)); } if (artist) { nb_art = sp_track_num_artists(track); art = (sp_artist**) malloc(nb_art * sizeof(sp_artist*)); if (!art) g_error("Can't allocate memory."); for (i=0; i < nb_art; i++) { art[i] = sp_track_artist(track, i); sp_artist_add_ref(art[i]); } } if (album) { alb = sp_track_album(track); sp_album_add_ref(alb); } if (link) { GString* tmp; lnk = sp_link_create_from_track(track, 0); if (!lnk) g_error("Can't get URI from track."); tmp = g_string_sized_new(1024); if (sp_link_as_string(lnk, tmp->str, 1024) < 0) g_error("Can't render URI from link."); *link = tmp->str; g_string_free(tmp, FALSE); sp_link_release(lnk); } if (duration) { *duration = sp_track_duration(track); } if (popularity) { *popularity = sp_track_popularity(track); } /* Now create destination strings */ if (artist) { GString* tmp = g_string_new(""); for (i=0; i < nb_art; i++) { if (sp_artist_is_loaded(art[i])) s = sp_artist_name(art[i]); else s = "[artist not loaded]"; if (i != 0) g_string_append(tmp, ", "); g_string_append(tmp, s); sp_artist_release(art[i]); } *artist = tmp->str; g_string_free(tmp, FALSE); } if (album) { if (sp_album_is_loaded(alb)) *album = g_strdup(sp_album_name(alb)); else *album = g_strdup("[album not loaded]"); sp_album_release(alb); } sp_track_release(track); }
JNIEXPORT int JNICALL Java_jahspotify_impl_JahSpotifyImpl_playTrack (JNIEnv *env, jobject obj, jstring uri) { uint8_t *nativeURI = NULL; fprintf(stderr,"jahspotify::Java_jahspotify_impl_JahSpotifyImpl_play: Initiating play\n"); nativeURI = ( uint8_t * ) ( *env )->GetStringUTFChars ( env, uri, NULL ); fprintf(stderr,"jahspotify::Java_jahspotify_impl_JahSpotifyImpl_play: uri: %s\n", nativeURI); if (!g_audio_initialized) { audio_init(&g_audiofifo); g_audio_initialized = JNI_TRUE; } // For each track, read out the info and populate all of the info in the Track instance sp_link *link = sp_link_create_from_string(nativeURI); if (link) { sp_track *t = sp_link_as_track(link); if (!t) { fprintf(stderr,"No track from link\n"); return; } while (!sp_track_is_available(g_sess,t)) { fprintf(stderr,"jahspotify::Java_jahspotify_impl_JahSpotifyImpl_play: Waiting for track ...\n"); sleep(1); } if (sp_track_error(t) != SP_ERROR_OK) { fprintf(stderr,"jahspotify::Java_jahspotify_impl_JahSpotifyImpl_play: Error with track: %s\n",sp_error_message(sp_track_error(t))); return; } fprintf(stderr,"jahspotify::Java_jahspotify_impl_JahSpotifyImpl_play: name: %s duration: %d\n",sp_track_name(t),sp_track_duration(t)); if (g_currenttrack == t) { fprintf(stderr,"jahspotify::Java_jahspotify_impl_JahSpotifyImpl_play: Same track!\n"); return; } // If there is one playing, unload that now if (g_currenttrack && t != g_currenttrack) { // audio_fifo_flush(&g_audiofifo); // Unload the current track now sp_session_player_unload(g_sess); sp_link *currentTrackLink = sp_link_create_from_track(g_currenttrack,0); char *currentTrackLinkStr = NULL; if (currentTrackLink) { currentTrackLinkStr = malloc ( sizeof ( char ) * ( 100 ) ); sp_link_as_string(currentTrackLink,currentTrackLinkStr,100); sp_link_release(currentTrackLink); } signalTrackEnded(currentTrackLinkStr, JNI_TRUE); if (currentTrackLinkStr) { free(currentTrackLinkStr); } sp_track_release(g_currenttrack); g_currenttrack = NULL; } else { // audio_fifo_flush(&g_audiofifo); // audio_close(); // audio_init(&g_audiofifo); } sp_track_add_ref(t); sp_error result = sp_session_player_load(g_sess, t); if (sp_track_error(t) != SP_ERROR_OK) { fprintf(stderr,"jahspotify::Java_jahspotify_impl_JahSpotifyImpl_play: Issue loading track: %s\n", sp_error_message((sp_track_error(t)))); } fprintf(stderr,"jahspotify::Java_jahspotify_impl_JahSpotifyImpl_play: Track loaded: %s\n", (result == SP_ERROR_OK ? "yes" : "no")); // Update the global reference g_currenttrack = t; // Start playing the next track sp_session_player_play(g_sess, 1); fprintf(stderr,"jahspotify::Java_jahspotify_impl_JahSpotifyImpl_play: Playing track\n"); sp_link_release(link); signalTrackStarted(nativeURI); return 0; } else { fprintf(stderr,"jahspotify::Java_jahspotify_impl_JahSpotifyImpl_play: Unable to load link at this point\n"); } return 1; }