예제 #1
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 );
    }
}
예제 #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() ) )
    {
        performLoadIODevice( d->currentTrack, d->currentTrack->url() );
    }
    else
    {
        QSharedPointer< QIODevice > io;
        performLoadTrack( result, result->url(), io );
    }
}
예제 #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 )
    {
        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();
}
예제 #4
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();
    }
}
예제 #5
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 );
    }
}
void
StreamConnection::reallyStartSending( const Tomahawk::result_ptr& result, QSharedPointer< QIODevice >& io )
{
    // Note: We don't really need to pass in 'result' here, since we already have it stored
    // as a member variable. The callback-signature of getIODeviceForUrl requires it, though.
    if ( !io || io.isNull() )
    {
        qDebug() << "Couldn't read from source:" << result->url();
        shutdown();
        return;
    }

    m_readdev = QSharedPointer<QIODevice>( io );
    sendSome();

    emit updated();
}
예제 #7
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();
    }
}
예제 #8
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;
}
예제 #9
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;
}
예제 #10
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;
}
예제 #11
0
void
AudioEngine::performLoadTrack( const Tomahawk::result_ptr& result, QSharedPointer< QIODevice >& io )
{
    Q_D( AudioEngine );

    bool err = false;
    {
        if ( !TomahawkUtils::isHttpResult( d->currentTrack->url() ) &&
             !TomahawkUtils::isLocalResult( 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::isHttpResult( d->currentTrack->url() ) &&
                 !TomahawkUtils::isLocalResult( d->currentTrack->url() ) )
            {
                if ( QNetworkReply* qnr_io = qobject_cast< QNetworkReply* >( io.data() ) )
                    d->mediaObject->setCurrentSource( new QNR_IODeviceStream( qnr_io, this ) );
                else
                    d->mediaObject->setCurrentSource( io.data() );
                d->mediaObject->currentSource().setAutoDelete( false );
            }
            else
            {
                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 = io;
            queueState( Playing );

            if ( TomahawkSettings::instance()->privateListeningMode() != TomahawkSettings::FullyPrivate )
            {
                d->currentTrack->track()->startPlaying();
            }

            sendNowPlayingNotification( Tomahawk::InfoSystem::InfoNowPlaying );
        }
    }

    if ( err )
    {
        stop();
        return;
    }

    d->waitingOnNewTrack = false;
    return;
}