void AudioEngine::playItem( Tomahawk::playlistinterface_ptr playlist, const Tomahawk::result_ptr& result, const Tomahawk::query_ptr& fromQuery ) { tDebug( LOGEXTRA ) << Q_FUNC_INFO << ( result.isNull() ? QString() : result->url() ); if ( !m_playlist.isNull() ) m_playlist.data()->reset(); setPlaylist( playlist ); if ( playlist.isNull() && !fromQuery.isNull() ) m_currentTrackPlaylist = playlistinterface_ptr( new SingleTrackPlaylistInterface( fromQuery ) ); else m_currentTrackPlaylist = playlist; if ( !result.isNull() ) { loadTrack( result ); } else if ( !m_playlist.isNull() && m_playlist.data()->retryMode() == PlaylistModes::Retry ) { m_waitingOnNewTrack = true; if ( isStopped() ) emit sendWaitingNotification(); else stop(); } }
void AudioEngine::loadTrack( const Tomahawk::result_ptr& result ) { Q_D( AudioEngine ); tDebug( LOGEXTRA ) << Q_FUNC_INFO << ( result.isNull() ? QString() : result->url() ); if ( result.isNull() ) { stop(); return; } setCurrentTrack( result ); if ( !TomahawkUtils::isLocalResult( d->currentTrack->url() ) && !TomahawkUtils::isHttpResult( d->currentTrack->url() ) && !TomahawkUtils::isRtmpResult( d->currentTrack->url() ) ) { boost::function< void ( QSharedPointer< QIODevice >& ) > callback = boost::bind( &AudioEngine::performLoadTrack, this, result, _1 ); Servent::instance()->getIODeviceForUrl( d->currentTrack, callback ); } else { QSharedPointer< QIODevice > io; performLoadTrack( result, io ); } }
void AudioEngine::loadTrack( const Tomahawk::result_ptr& result ) { Q_D( AudioEngine ); tDebug( LOGEXTRA ) << Q_FUNC_INFO << ( result.isNull() ? QString() : result->url() ); if ( result.isNull() ) { stop(); return; } setCurrentTrack( result ); if ( !TomahawkUtils::isLocalResult( d->currentTrack->url() ) && !TomahawkUtils::isHttpResult( d->currentTrack->url() ) && !TomahawkUtils::isRtmpResult( d->currentTrack->url() ) ) { performLoadIODevice( d->currentTrack, d->currentTrack->url() ); } else { QSharedPointer< QIODevice > io; performLoadTrack( result, result->url(), io ); } }
void AudioEngine::loadNextTrack() { tDebug( LOGEXTRA ) << Q_FUNC_INFO; Tomahawk::result_ptr result; if ( m_queue && m_queue->trackCount() ) { result = m_queue->nextItem(); } if ( !m_playlist.isNull() && result.isNull() ) { result = m_playlist.data()->nextItem(); } if ( !result.isNull() ) loadTrack( result ); else { if ( !m_playlist.isNull() && m_playlist.data()->retryMode() == Tomahawk::PlaylistInterface::Retry ) m_waitingOnNewTrack = true; stop(); } }
void AudioEngine::loadNextTrack() { Q_D( AudioEngine ); tDebug( LOGEXTRA ) << Q_FUNC_INFO; Tomahawk::result_ptr result; if ( d->stopAfterTrack && d->currentTrack ) { if ( d->stopAfterTrack->track()->equals( d->currentTrack->track() ) ) { d->stopAfterTrack.clear(); stop(); return; } } if ( d->queue && d->queue->trackCount() ) { query_ptr query = d->queue->tracks().first(); if ( query && query->numResults() ) result = query->results().first(); } if ( !d->playlist.isNull() && result.isNull() ) { tDebug( LOGVERBOSE ) << Q_FUNC_INFO << "Loading playlist's next item" << d->playlist.data() << d->playlist->shuffled(); if ( d->playlist.data()->nextResult() ) { result = d->playlist.data()->setSiblingResult( 1 ); setCurrentTrackPlaylist( d->playlist ); } } if ( !result.isNull() ) { tDebug( LOGVERBOSE ) << Q_FUNC_INFO << "Got next item, loading track"; loadTrack( result ); } else { if ( !d->playlist.isNull() && d->playlist.data()->retryMode() == Tomahawk::PlaylistModes::Retry ) d->waitingOnNewTrack = true; stop(); } }
void AudioEngine::loadNextTrack() { tDebug( LOGEXTRA ) << Q_FUNC_INFO; Tomahawk::result_ptr result; if ( !m_stopAfterTrack.isNull() && !m_currentTrack.isNull() ) { if ( m_stopAfterTrack->equals( m_currentTrack->toQuery() ) ) { m_stopAfterTrack.clear(); stop(); return; } } if ( m_queue && m_queue->trackCount() ) { query_ptr query = m_queue->tracks().first(); if ( query && query->numResults() ) result = query->results().first(); } if ( !m_playlist.isNull() && result.isNull() ) { tDebug( LOGVERBOSE ) << Q_FUNC_INFO << "Loading playlist's next item" << m_playlist.data() << m_playlist->shuffled(); if ( m_playlist.data()->nextResult() ) { result = m_playlist.data()->nextResult(); m_currentTrackPlaylist = m_playlist; } } if ( !result.isNull() ) { tDebug( LOGVERBOSE ) << Q_FUNC_INFO << "Got next item, loading track"; loadTrack( result ); } else { if ( !m_playlist.isNull() && m_playlist.data()->retryMode() == Tomahawk::PlaylistModes::Retry ) m_waitingOnNewTrack = true; stop(); } }
void AudioEngine::loadPreviousTrack() { Q_D( AudioEngine ); tDebug( LOGEXTRA ) << Q_FUNC_INFO; if ( d->playlist.isNull() ) { stop(); return; } Tomahawk::result_ptr result; if ( d->playlist.data()->previousResult() ) { result = d->playlist.data()->setSiblingResult( -1 ); setCurrentTrackPlaylist( d->playlist ); } if ( !result.isNull() ) loadTrack( result ); else stop(); }
void AudioControls::onPlaybackStarted( const Tomahawk::result_ptr& result ) { if ( result.isNull() ) return; if ( m_currentTrack.isNull() || ( !m_currentTrack.isNull() && m_currentTrack.data()->id() != result.data()->id() ) ) onPlaybackLoading( result ); qint64 duration = AudioEngine::instance()->currentTrackTotalTime(); if ( duration == -1 ) duration = result.data()->duration() * 1000; ui->seekSlider->setRange( 0, duration ); ui->seekSlider->setValue( 0 ); m_phononTickCheckTimer.stop(); m_sliderTimeLine.stop(); m_sliderTimeLine.setDuration( duration ); m_sliderTimeLine.setFrameRange( 0, duration ); m_sliderTimeLine.setCurrentTime( 0 ); m_seekMsecs = -1; ui->seekSlider->setVisible( true ); m_noTimeChange = false; m_lastSliderCheck = 0; }
void AudioEngine::loadTrack( const Tomahawk::result_ptr& result ) { Q_D( AudioEngine ); tDebug( LOGEXTRA ) << Q_FUNC_INFO << ( result.isNull() ? QString() : result->url() ); if ( !result ) { stop(); return; } // We do this to stop the audio as soon as a user activated another track // If we don't block the audioOutput signals, the state change will trigger // loading yet another track d->audioOutput->blockSignals( true ); d->audioOutput->stop(); d->audioOutput->blockSignals( false ); setCurrentTrack( result ); if ( !TomahawkUtils::isLocalResult( d->currentTrack->url() ) && !TomahawkUtils::isHttpResult( d->currentTrack->url() ) && !TomahawkUtils::isRtmpResult( d->currentTrack->url() ) ) { performLoadIODevice( d->currentTrack, d->currentTrack->url() ); } else { QSharedPointer< QIODevice > io; performLoadTrack( result, result->url(), io ); } }
void StreamConnection::startSending( const Tomahawk::result_ptr& result ) { if ( result.isNull() ) { qDebug() << "Can't handle invalid result!"; shutdown(); return; } m_result = result; qDebug() << "Starting to transmit" << m_result->url(); QSharedPointer<QIODevice> io = Servent::instance()->getIODeviceForUrl( m_result ); if( !io ) { qDebug() << "Couldn't read from source:" << m_result->url(); shutdown(); return; } m_readdev = QSharedPointer<QIODevice>( io ); sendSome(); emit updated(); }
void AudioEngine::loadTrack( const Tomahawk::result_ptr& result ) { Q_D( AudioEngine ); tDebug( LOGEXTRA ) << Q_FUNC_INFO << ( result.isNull() ? QString() : result->url() ); if ( !result ) { stop(); return; } // We do this to stop the audio as soon as a user activated another track // If we don't block the audioOutput signals, the state change will trigger // loading yet another track d->audioOutput->blockSignals( true ); d->audioOutput->stop(); d->audioOutput->blockSignals( false ); setCurrentTrack( result ); ScriptJob* job = result->resolvedBy()->getStreamUrl( result ); connect( job, SIGNAL( done( QVariantMap ) ), SLOT( gotStreamUrl( QVariantMap ) ) ); job->setProperty( "result", QVariant::fromValue( result ) ); job->start(); }
void QueryLabel::setResult( const Tomahawk::result_ptr& result ) { if ( result.isNull() ) return; if ( !m_text.isEmpty() && contentsMargins().left() != 0 ) // FIXME: hacky m_textMargins = contentsMargins(); setContentsMargins( BOXMARGIN * 2, BOXMARGIN / 2, BOXMARGIN * 2, BOXMARGIN / 2); if ( m_result.isNull() || m_result.data() != result.data() ) { m_result = result; m_query = m_result->toQuery(); QList<Tomahawk::result_ptr> rl; rl << m_result; m_query->addResults( rl ); updateLabel(); emit textChanged( text() ); emit resultChanged( m_result ); } }
void AudioControls::onPlaybackStarted( const Tomahawk::result_ptr result ) { if ( result.isNull() ) return; if ( m_currentTrack.isNull() || ( !m_currentTrack.isNull() && m_currentTrack.data()->id() != result.data()->id() ) ) onPlaybackLoading( result ); qint64 duration = AudioEngine::instance()->currentTrackTotalTime(); if ( duration <= 0 ) duration = result.data()->track()->duration() * 1000; ui->seekSlider->setRange( 0, duration ); ui->seekSlider->setValue( 0 ); ui->seekSlider->setEnabled( AudioEngine::instance()->canSeek() ); ui->timeLabel->setText( TomahawkUtils::timeToString( 0 ) ); ui->timeLeftLabel->setText( "-" + TomahawkUtils::timeToString( 0 ) ); tLog() << Q_FUNC_INFO << duration; m_sliderTimeLine.setDuration( duration ); m_sliderTimeLine.setFrameRange( 0, duration ); m_sliderTimeLine.setCurveShape( QTimeLine::LinearCurve ); m_sliderTimeLine.setCurrentTime( 0 ); m_seeked = false; int updateRate = (double)1000 / ( (double)ui->seekSlider->contentsRect().width() / (double)( duration / 1000 ) ); m_sliderTimeLine.setUpdateInterval( qBound( 40, updateRate, 500 ) ); m_lastSliderCheck = 0; m_phononTickCheckTimer.start( 500 ); }
void DatabaseCommand_Resolve::exec( DatabaseImpl* lib ) { /* * Resolving is a 2 stage process. * 1) find list of trk/art/alb IDs that are reasonable matches to the metadata given * 2) find files in database by permitted sources and calculate score, ignoring * results that are less than MINSCORE */ if ( !m_query->resultHint().isEmpty() ) { qDebug() << "Using result-hint to speed up resolving:" << m_query->resultHint(); Tomahawk::result_ptr result = lib->resultFromHint( m_query ); if ( !result.isNull() && ( result->collection().isNull() || result->collection()->source()->isOnline() ) ) { QList<Tomahawk::result_ptr> res; res << result; emit results( m_query->id(), res ); return; } } if ( m_query->isFullTextQuery() ) fullTextResolve( lib ); else resolve( lib ); }
bool TrackProxyModel::filterAcceptsRow( int sourceRow, const QModelIndex& sourceParent ) const { TrackModelItem* pi = itemFromIndex( sourceModel()->index( sourceRow, 0, sourceParent ) ); if ( !pi ) return false; const Tomahawk::query_ptr& q = pi->query(); if( q.isNull() ) // uh oh? filter out invalid queries i guess return false; Tomahawk::result_ptr r; if ( q->numResults() ) r = q->results().first(); if ( !m_showOfflineResults && !r.isNull() && !r->collection()->source()->isOnline() ) return false; if ( filterRegExp().isEmpty() ) return true; QStringList sl = filterRegExp().pattern().split( " ", QString::SkipEmptyParts ); foreach( QString s, sl ) { s = s.toLower(); if ( !r.isNull() ) { if ( !r->artist()->name().toLower().contains( s ) && !r->album()->name().toLower().contains( s ) && !r->track().toLower().contains( s ) ) { return false; } } else { if ( !q->artist().toLower().contains( s ) && !q->album().toLower().contains( s ) && !q->track().toLower().contains( s ) ) { return false; } } }
void AudioEngine::playItem( Tomahawk::PlaylistInterface* playlist, const Tomahawk::result_ptr& result ) { tDebug( LOGEXTRA ) << Q_FUNC_INFO << ( result.isNull() ? QString() : result->url() ); if ( !m_playlist.isNull() ) m_playlist.data()->reset(); setPlaylist( playlist ); m_currentTrackPlaylist = playlist->getSharedPointer(); if ( !result.isNull() ) loadTrack( result ); else if ( !m_playlist.isNull() && m_playlist.data()->retryMode() == PlaylistInterface::Retry ) { m_waitingOnNewTrack = true; stop(); } }
bool PlayableProxyModel::filterAcceptsRow( int sourceRow, const QModelIndex& sourceParent ) const { PlayableItem* pi = itemFromIndex( sourceModel()->index( sourceRow, 0, sourceParent ) ); if ( !pi ) return false; if ( m_maxVisibleItems >= 0 && sourceRow > m_maxVisibleItems - 1 ) return false; if ( m_hideDupeItems ) { for ( int i = 0; i < sourceRow; i++ ) { PlayableItem* di = itemFromIndex( sourceModel()->index( i, 0, sourceParent ) ); if ( !di ) continue; bool b = ( pi->query() && pi->query()->equals( di->query() ) ) || ( pi->album() && pi->album() == di->album() ) || ( pi->artist() && pi->artist()->name() == di->artist()->name() ); if ( b && filterAcceptsRow( i, sourceParent ) ) return false; } } if ( pi->query() ) { const Tomahawk::query_ptr& q = pi->query()->displayQuery(); if ( q.isNull() ) // uh oh? filter out invalid queries i guess return false; Tomahawk::result_ptr r; if ( q->numResults() ) r = q->results().first(); if ( !m_showOfflineResults && ( r.isNull() || !r->isOnline() ) ) return false; if ( filterRegExp().isEmpty() ) return true; QStringList sl = filterRegExp().pattern().split( " ", QString::SkipEmptyParts ); foreach( QString s, sl ) { s = s.toLower(); if ( !q->artist().toLower().contains( s ) && !q->album().toLower().contains( s ) && !q->track().toLower().contains( s ) ) { return false; } } }
void AudioEngine::loadPreviousTrack() { tDebug( LOGEXTRA ) << Q_FUNC_INFO; if ( m_playlist.isNull() ) { stop(); return; } Tomahawk::result_ptr result = m_playlist.data()->previousItem(); if ( !result.isNull() ) loadTrack( result ); else stop(); }
void StreamConnection::startSending( const Tomahawk::result_ptr& result ) { if ( result.isNull() ) { qDebug() << "Can't handle invalid result!"; shutdown(); return; } m_result = result; qDebug() << "Starting to transmit" << m_result->url(); boost::function< void ( QSharedPointer< QIODevice >& ) > callback = boost::bind( &StreamConnection::reallyStartSending, this, result, _1 ); Tomahawk::UrlHandler::getIODeviceForUrl( m_result, m_result->url(), callback ); }
void AudioControls::onPlaybackStarted( const Tomahawk::result_ptr& result ) { tDebug( LOGEXTRA ) << Q_FUNC_INFO; if ( result.isNull() ) return; if ( m_currentTrack.isNull() || ( !m_currentTrack.isNull() && m_currentTrack.data()->id() != result.data()->id() ) ) onPlaybackLoading( result ); qint64 duration = AudioEngine::instance()->currentTrackTotalTime(); if ( duration == -1 ) duration = result.data()->duration() * 1000; ui->seekSlider->setRange( 0, duration ); ui->seekSlider->setValue( 0 ); m_phononTickCheckTimer.stop(); m_sliderTimeLine.stop(); m_sliderTimeLine.setDuration( duration ); m_sliderTimeLine.setFrameRange( 0, duration ); m_sliderTimeLine.setCurrentTime( 0 ); m_seekMsecs = -1; ui->seekSlider->setVisible( true ); m_noTimeChange = false; m_lastSliderCheck = 0; Tomahawk::InfoSystem::InfoStringHash trackInfo; trackInfo["artist"] = result->artist()->name(); trackInfo["album"] = result->album()->name(); Tomahawk::InfoSystem::InfoRequestData requestData; requestData.caller = s_acInfoIdentifier; requestData.type = Tomahawk::InfoSystem::InfoAlbumCoverArt; requestData.input = QVariant::fromValue< Tomahawk::InfoSystem::InfoStringHash >( trackInfo ); requestData.customData = QVariantMap(); Tomahawk::InfoSystem::InfoSystem::instance()->getInfo( requestData ); }
void MetadataEditor::loadResult( const Tomahawk::result_ptr& result ) { if ( result.isNull() ) return; m_result = result; setEditable( result->collection() && result->collection()->source()->isLocal() ); setTitle( result->track()->track() ); setArtist( result->track()->artist() ); setAlbum( result->track()->album() ); setAlbumPos( result->track()->albumpos() ); setDuration( result->track()->duration() ); setYear( result->track()->year() ); setBitrate( result->bitrate() ); if ( result->collection() && result->collection()->source()->isLocal() ) { QString furl = m_result->url(); if ( furl.startsWith( "file://" ) ) furl = furl.right( furl.length() - 7 ); QFileInfo fi( furl ); setFileName( fi.absoluteFilePath() ); setFileSize( TomahawkUtils::filesizeToString( fi.size() ) ); } setWindowTitle( result->track()->track() ); if ( m_interface ) { m_index = m_interface->indexOfResult( result ); if ( m_index >= 0 ) enablePushButtons(); } }
void DatabaseCommand_Resolve::exec( DatabaseImpl* lib ) { QList<Tomahawk::result_ptr> res; if ( !m_query->resultHint().isEmpty() ) { qDebug() << "Using result-hint to speed up resolving:" << m_query->resultHint(); Tomahawk::result_ptr result = lib->result( m_query->resultHint() ); if ( !result.isNull() && result->collection()->source()->isOnline() ) { res << result; emit results( m_query->id(), res ); return; } } /* Resolving is a 2 stage process. 1) find list of trk/art/alb IDs that are reasonable matches to the metadata given 2) find files in database by permitted sources and calculate score, ignoring results that are less than MINSCORE */ typedef QPair<int, float> scorepair_t; // STEP 1 QList< int > artists = lib->searchTable( "artist", m_query->artist(), 10 ); QList< int > tracks = lib->searchTable( "track", m_query->track(), 10 ); QList< int > albums = lib->searchTable( "album", m_query->album(), 10 ); if( artists.length() == 0 || tracks.length() == 0 ) { qDebug() << "No candidates found in first pass, aborting resolve" << m_query->artist() << m_query->track(); emit results( m_query->id(), res ); return; } // STEP 2 TomahawkSqlQuery files_query = lib->newquery(); QStringList artsl, trksl; foreach( int i, artists ) artsl.append( QString::number( i ) ); foreach( int i, tracks ) trksl.append( QString::number( i ) ); QString sql = QString( "SELECT " "url, mtime, size, md5, mimetype, duration, bitrate, file_join.artist, file_join.album, file_join.track, " "artist.name as artname, " "album.name as albname, " "track.name as trkname, " "file.source, " "file_join.albumpos, " "artist.id as artid, " "album.id as albid " "FROM file, file_join, artist, track " "LEFT JOIN album ON album.id = file_join.album " "WHERE " "artist.id = file_join.artist AND " "track.id = file_join.track AND " "file.id = file_join.file AND " "file_join.artist IN (%1) AND " "file_join.track IN (%2)" ) .arg( artsl.join( "," ) ) .arg( trksl.join( "," ) ); files_query.prepare( sql ); files_query.exec(); while( files_query.next() ) { Tomahawk::result_ptr result( new Tomahawk::Result() ); source_ptr s; const QString url_str = files_query.value( 0 ).toString(); if( files_query.value( 13 ).toUInt() == 0 ) { s = SourceList::instance()->getLocal(); result->setUrl( url_str ); } else { s = SourceList::instance()->get( files_query.value( 13 ).toUInt() ); if( s.isNull() ) { Q_ASSERT( false ); continue; } result->setUrl( QString( "servent://%1\t%2" ).arg( s->userName() ).arg( url_str ) ); } Tomahawk::artist_ptr artist = Tomahawk::Artist::get( files_query.value( 15 ).toUInt(), files_query.value( 10 ).toString(), s->collection() ); Tomahawk::album_ptr album = Tomahawk::Album::get( files_query.value( 16 ).toUInt(), files_query.value( 11 ).toString(), artist, s->collection() ); result->setModificationTime( files_query.value( 1 ).toUInt() ); result->setSize( files_query.value( 2 ).toUInt() ); result->setMimetype( files_query.value( 4 ).toString() ); result->setDuration( files_query.value( 5 ).toUInt() ); result->setBitrate( files_query.value( 6 ).toUInt() ); result->setArtist( artist ); result->setAlbum( album ); result->setTrack( files_query.value( 12 ).toString() ); result->setRID( uuid() ); result->setAlbumPos( files_query.value( 14 ).toUInt() ); result->setId( files_query.value( 9 ).toUInt() ); float score = how_similar( m_query, result ); result->setScore( score ); if( score < MINSCORE ) continue; result->setCollection( s->collection() ); res << result; } emit results( m_query->id(), res ); }
bool AudioEngine::loadTrack( const Tomahawk::result_ptr& result ) { bool err = false; { QSharedPointer<QIODevice> io; if ( result.isNull() ) err = true; else { setCurrentTrack( result ); if ( !isHttpResult( m_currentTrack->url() ) && !isLocalResult( m_currentTrack->url() ) ) { io = Servent::instance()->getIODeviceForUrl( m_currentTrack ); if ( !io || io.isNull() ) { tLog() << "Error getting iodevice for" << result->url(); err = true; } } } if ( !err ) { tLog() << "Starting new song:" << m_currentTrack->url(); emit loading( m_currentTrack ); if ( !isHttpResult( m_currentTrack->url() ) && !isLocalResult( m_currentTrack->url() ) ) { if ( QNetworkReply* qnr_io = qobject_cast< QNetworkReply* >( io.data() ) ) m_mediaObject->setCurrentSource( new QNR_IODeviceStream( qnr_io, this ) ); else m_mediaObject->setCurrentSource( io.data() ); m_mediaObject->currentSource().setAutoDelete( false ); } else { if ( !isLocalResult( m_currentTrack->url() ) ) { QUrl furl = m_currentTrack->url(); if ( m_currentTrack->url().contains( "?" ) ) { furl = QUrl( m_currentTrack->url().left( m_currentTrack->url().indexOf( '?' ) ) ); furl.setEncodedQuery( QString( m_currentTrack->url().mid( m_currentTrack->url().indexOf( '?' ) + 1 ) ).toLocal8Bit() ); } m_mediaObject->setCurrentSource( furl ); } else { QString furl = m_currentTrack->url(); #ifdef Q_WS_WIN if ( furl.startsWith( "file://" ) ) furl = furl.right( furl.length() - 7 ); #endif tLog( LOGVERBOSE ) << "Passing to Phonon:" << furl << furl.toLatin1(); m_mediaObject->setCurrentSource( furl ); } m_mediaObject->currentSource().setAutoDelete( true ); } if ( !m_input.isNull() ) { m_input->close(); m_input.clear(); } m_input = io; queueState( Playing ); emit started( m_currentTrack ); if ( TomahawkSettings::instance()->privateListeningMode() != TomahawkSettings::FullyPrivate ) { DatabaseCommand_LogPlayback* cmd = new DatabaseCommand_LogPlayback( m_currentTrack, DatabaseCommand_LogPlayback::Started ); Database::instance()->enqueue( QSharedPointer<DatabaseCommand>(cmd) ); } sendNowPlayingNotification( Tomahawk::InfoSystem::InfoNowPlaying ); } } if ( err ) { stop(); return false; } m_waitingOnNewTrack = false; return true; }
void Api_v1_5::playback( QxtWebRequestEvent* event, const QString& command ) { if ( command == "next") { JSON_REPLY( QMetaObject::invokeMethod( AudioEngine::instance(), "next", Qt::QueuedConnection ) , "Skipping to the next track failed." ); } else if ( command == "previous" ) { JSON_REPLY( QMetaObject::invokeMethod( AudioEngine::instance(), "previous", Qt::QueuedConnection ), "Rewinding to the previous track failed." ); } else if ( command == "playpause" ) { JSON_REPLY( QMetaObject::invokeMethod( AudioEngine::instance(), "playPause", Qt::QueuedConnection ), "Play/Pause failed." ); } else if ( command == "play" ) { JSON_REPLY( QMetaObject::invokeMethod( AudioEngine::instance(), "play", Qt::QueuedConnection ), "Starting the playback failed." ); } else if ( command == "pause" ) { JSON_REPLY( QMetaObject::invokeMethod( AudioEngine::instance(), "pause", Qt::QueuedConnection ), "Pausing the current track failed." ); } else if ( command == "stop" ) { JSON_REPLY( QMetaObject::invokeMethod( AudioEngine::instance(), "stop", Qt::QueuedConnection ), "Stopping the current track failed." ); } else if ( command == "lowervolume" ) { JSON_REPLY( QMetaObject::invokeMethod( AudioEngine::instance(), "lowerVolume", Qt::QueuedConnection ), "Lowering volume failed." ); } else if ( command == "raisevolume" ) { JSON_REPLY( QMetaObject::invokeMethod( AudioEngine::instance(), "raiseVolume", Qt::QueuedConnection ), "Raising volume failed." ); } else if ( command == "currenttrack" ) { QByteArray json; Tomahawk::result_ptr currentTrack = AudioEngine::instance()->currentTrack(); if ( currentTrack.isNull() ) { json = "{ \"playing\": false }"; } else { QVariantMap trackInfo; trackInfo.insert( "playing", true ); trackInfo.insert( "paused", AudioEngine::instance()->isPaused() ); trackInfo.insert( "position", AudioEngine::instance()->currentTime() / 1000 ); trackInfo.insert( "bitrate", currentTrack->bitrate() ); if ( currentTrack->resolvedBy() ) { QString resolverName = currentTrack->resolvedBy()->name(); trackInfo.insert( "resolvedBy", resolverName ); } else { trackInfo.insert( "resolvedBy", "<unknown resolver>" ); } trackInfo.insert( "score", currentTrack->score() ); trackInfo.insert( "album", currentTrack->track()->album() ); trackInfo.insert( "albumpos", currentTrack->track()->albumpos() ); trackInfo.insert( "artist", currentTrack->track()->artist() ); trackInfo.insert( "duration", currentTrack->track()->duration() ); trackInfo.insert( "track", currentTrack->track()->track() ); bool ok; json = TomahawkUtils::toJson( trackInfo, &ok ); Q_ASSERT( ok ); } QxtWebPageEvent * e = new QxtWebPageEvent( event->sessionID, event->requestID, json ); e->headers.insert( "Access-Control-Allow-Origin", "*" ); e->contentType = "application/json"; m_service->postEvent( e ); } else if ( command == "volume" ) { QByteArray json = QString( "{ \"result\": \"ok\", \"volume\": %1}" ).arg( AudioEngine::instance()->volume() ).toUtf8(); QxtWebPageEvent * e = new QxtWebPageEvent( event->sessionID, event->requestID, json ); e->headers.insert( "Access-Control-Allow-Origin", "*" ); e->contentType = "application/json"; m_service->postEvent( e ); } else { m_service->sendJsonError( event, "No such playback command." ); } }
void AudioEngine::performLoadTrack( const Tomahawk::result_ptr& result, QSharedPointer< QIODevice >& io ) { Q_D( AudioEngine ); if ( currentTrack() != result ) { tLog( LOGVERBOSE ) << Q_FUNC_INFO << "Track loaded too late, skip."; return; } tDebug( LOGEXTRA ) << Q_FUNC_INFO << ( result.isNull() ? QString() : result->url() ); QSharedPointer< QIODevice > ioToKeep = io; bool err = false; { if ( !( TomahawkUtils::isLocalResult( d->currentTrack->url() ) || TomahawkUtils::isHttpResult( d->currentTrack->url() ) || TomahawkUtils::isRtmpResult( d->currentTrack->url() ) ) && ( !io || io.isNull() ) ) { tLog() << "Error getting iodevice for" << result->url(); err = true; } if ( !err ) { tLog() << "Starting new song:" << d->currentTrack->url(); d->state = Loading; emit loading( d->currentTrack ); if ( !TomahawkUtils::isLocalResult( d->currentTrack->url() ) && !TomahawkUtils::isHttpResult( d->currentTrack->url() ) && !TomahawkUtils::isRtmpResult( d->currentTrack->url() ) ) { QSharedPointer<QNetworkReply> qnr = io.objectCast<QNetworkReply>(); if ( !qnr.isNull() ) { d->mediaObject->setCurrentSource( new QNR_IODeviceStream( qnr, this ) ); // We keep track of the QNetworkReply in QNR_IODeviceStream // and Phonon handles the deletion of the // QNR_IODeviceStream object ioToKeep.clear(); d->mediaObject->currentSource().setAutoDelete( true ); } else { d->mediaObject->setCurrentSource( io.data() ); // We handle the deletion via tracking in d->input d->mediaObject->currentSource().setAutoDelete( false ); } } else { /* * TODO: Do we need this anymore as we now do HTTP streaming ourselves? * Maybe this can be useful for letting phonon do other protocols? */ if ( !TomahawkUtils::isLocalResult( d->currentTrack->url() ) ) { QUrl furl = d->currentTrack->url(); if ( d->currentTrack->url().contains( "?" ) ) { furl = QUrl( d->currentTrack->url().left( d->currentTrack->url().indexOf( '?' ) ) ); TomahawkUtils::urlSetQuery( furl, QString( d->currentTrack->url().mid( d->currentTrack->url().indexOf( '?' ) + 1 ) ) ); } tLog( LOGVERBOSE ) << "Passing to Phonon:" << furl; d->mediaObject->setCurrentSource( furl ); } else { QString furl = d->currentTrack->url(); if ( furl.startsWith( "file://" ) ) furl = furl.right( furl.length() - 7 ); tLog( LOGVERBOSE ) << "Passing to Phonon:" << QUrl::fromLocalFile( furl ); d->mediaObject->setCurrentSource( QUrl::fromLocalFile( furl ) ); } d->mediaObject->currentSource().setAutoDelete( true ); } if ( !d->input.isNull() ) { d->input->close(); d->input.clear(); } d->input = ioToKeep; d->mediaObject->play(); if ( TomahawkSettings::instance()->privateListeningMode() != TomahawkSettings::FullyPrivate ) { d->currentTrack->track()->startPlaying(); } sendNowPlayingNotification( Tomahawk::InfoSystem::InfoNowPlaying ); } } if ( err ) { stop(); return; } d->waitingOnNewTrack = false; return; }
bool PlayableProxyModel::nameFilterAcceptsRow( int sourceRow, PlayableItem* pi, const QModelIndex& sourceParent ) const { if ( m_hideEmptyParents && pi->source() ) { if ( !sourceModel()->rowCount( sourceModel()->index( sourceRow, 0, sourceParent ) ) ) { return false; } } const Tomahawk::query_ptr& query = pi->query(); if ( query ) { Tomahawk::result_ptr r; if ( query->numResults() ) r = query->results().first(); if ( !m_showOfflineResults && ( r.isNull() || !r->isOnline() ) ) return false; const QRegExp regexp = filterRegExp(); if ( regexp.isEmpty() ) return true; QStringList sl = regexp.pattern().split( " ", QString::SkipEmptyParts ); foreach( const QString& s, sl ) { const Tomahawk::track_ptr& track = query->track(); if ( !track->artist().contains( s, Qt::CaseInsensitive ) && !track->album().contains( s, Qt::CaseInsensitive ) && !track->track().contains( s, Qt::CaseInsensitive ) ) { return false; } } } const Tomahawk::album_ptr& al = pi->album(); if ( al ) { QStringList sl = filterRegExp().pattern().split( " ", QString::SkipEmptyParts ); foreach( const QString& s, sl ) { if ( !al->name().contains( s, Qt::CaseInsensitive ) && !al->artist()->name().contains( s, Qt::CaseInsensitive ) ) { return false; } } return true; } const Tomahawk::artist_ptr& ar = pi->artist(); if ( ar ) { QStringList sl = filterRegExp().pattern().split( " ", QString::SkipEmptyParts ); foreach( const QString& s, sl ) { if ( !ar->name().contains( s, Qt::CaseInsensitive ) ) { return false; } } return true; } return true; }
bool AudioEngine::loadTrack( const Tomahawk::result_ptr& result ) { bool err = false; { QSharedPointer<QIODevice> io; if ( result.isNull() ) err = true; else { setCurrentTrack( result ); if ( !isHttpResult( m_currentTrack->url() ) && !isLocalResult( m_currentTrack->url() ) ) { io = Servent::instance()->getIODeviceForUrl( m_currentTrack ); if ( !io || io.isNull() ) { tLog() << "Error getting iodevice for" << result->url(); err = true; } } } if ( !err ) { tLog() << "Starting new song:" << m_currentTrack->url(); emit loading( m_currentTrack ); if ( !isHttpResult( m_currentTrack->url() ) && !isLocalResult( m_currentTrack->url() ) ) { m_mediaObject->setCurrentSource( io.data() ); m_mediaObject->currentSource().setAutoDelete( false ); m_isPlayingHttp = false; } else { if ( !isLocalResult( m_currentTrack->url() ) ) { QUrl furl = m_currentTrack->url(); if ( m_currentTrack->url().contains( "?" ) ) { furl = QUrl( m_currentTrack->url().left( m_currentTrack->url().indexOf( '?' ) ) ); furl.setEncodedQuery( QString( m_currentTrack->url().mid( m_currentTrack->url().indexOf( '?' ) + 1 ) ).toLocal8Bit() ); } m_mediaObject->setCurrentSource( furl ); } else { QString furl = m_currentTrack->url(); #ifdef Q_OS_WIN32 if ( furl.startsWith( "file://" ) ) furl = furl.right( furl.length() - 7 ); #endif m_mediaObject->setCurrentSource( furl ); } m_mediaObject->currentSource().setAutoDelete( true ); m_isPlayingHttp = true; } if ( !m_input.isNull() ) { m_input->close(); m_input.clear(); } m_input = io; m_mediaObject->play(); emit started( m_currentTrack ); DatabaseCommand_LogPlayback* cmd = new DatabaseCommand_LogPlayback( m_currentTrack, DatabaseCommand_LogPlayback::Started ); Database::instance()->enqueue( QSharedPointer<DatabaseCommand>(cmd) ); Tomahawk::InfoSystem::InfoCriteriaHash trackInfo; trackInfo["title"] = m_currentTrack->track(); trackInfo["artist"] = m_currentTrack->artist()->name(); trackInfo["album"] = m_currentTrack->album()->name(); if ( TomahawkSettings::instance()->verboseNotifications() ) sendNowPlayingNotification(); Tomahawk::InfoSystem::InfoSystem::instance()->pushInfo( s_aeInfoIdentifier, Tomahawk::InfoSystem::InfoNowPlaying, QVariant::fromValue< Tomahawk::InfoSystem::InfoCriteriaHash >( trackInfo ) ); } } if ( err ) { stop(); return false; } m_waitingOnNewTrack = false; return true; }