Beispiel #1
0
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();
    }
}
Beispiel #2
0
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 );
    }
}
Beispiel #3
0
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 );
    }
}
Beispiel #4
0
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();
    }
}
Beispiel #5
0
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();
    }
}
Beispiel #6
0
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();
    }
}
Beispiel #7
0
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();
}
Beispiel #8
0
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;
}
Beispiel #9
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();
}
Beispiel #11
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 );

    ScriptJob* job = result->resolvedBy()->getStreamUrl( result );
    connect( job, SIGNAL( done( QVariantMap ) ), SLOT( gotStreamUrl( QVariantMap ) ) );
    job->setProperty( "result", QVariant::fromValue( result ) );
    job->start();
}
Beispiel #12
0
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 );
    }
}
Beispiel #13
0
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;
            }
        }
    }
Beispiel #16
0
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;
            }
        }
    }
Beispiel #18
0
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 );
}
Beispiel #20
0
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 );
}
Beispiel #21
0
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 );
}
Beispiel #23
0
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;
}
Beispiel #24
0
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." );
    }
}
Beispiel #25
0
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;
}
Beispiel #26
0
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;
}
Beispiel #27
0
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;
}