예제 #1
0
 foreach (const QString &f, files) {
     m_playlist->addMedia(QMediaContent(QUrl::fromLocalFile(dir.absolutePath() + "/" + f)));
     emit tracksChanged(tracks());
     emit trackCountChanged(trackCount());
 }
void MediaPlayerPrivateAVFoundation::metadataLoaded()
{
    m_loadingMetadata = false;
    tracksChanged();
}
예제 #3
0
void MediaPlayerPrivateAVFoundation::dispatchNotification()
{
    ASSERT(isMainThread());

    Notification notification = Notification();
    {
        MutexLocker lock(m_queueMutex);
        
        if (m_queuedNotifications.isEmpty())
            return;
        
        if (!m_delayCallbacks) {
            // Only dispatch one notification callback per invocation because they can cause recursion.
            notification = m_queuedNotifications.first();
            m_queuedNotifications.remove(0);
        }
        
        if (!m_queuedNotifications.isEmpty() && !m_mainThreadCallPending)
            callOnMainThread(mainThreadCallback, this);
        
        if (!notification.isValid())
            return;
    }

    LOG(Media, "MediaPlayerPrivateAVFoundation::dispatchNotification(%p) - dispatching %d", this, static_cast<int>(notification.type()));

    switch (notification.type()) {
    case Notification::ItemDidPlayToEndTime:
        didEnd();
        break;
    case Notification::ItemTracksChanged:
        tracksChanged();
        updateStates();
        break;
    case Notification::ItemStatusChanged:
        updateStates();
        break;
    case Notification::ItemSeekableTimeRangesChanged:
        seekableTimeRangesChanged();
        updateStates();
        break;
    case Notification::ItemLoadedTimeRangesChanged:
        loadedTimeRangesChanged();
        updateStates();
        break;
    case Notification::ItemPresentationSizeChanged:
        sizeChanged();
        updateStates();
        break;
    case Notification::ItemIsPlaybackLikelyToKeepUpChanged:
        updateStates();
        break;
    case Notification::ItemIsPlaybackBufferEmptyChanged:
        updateStates();
        break;
    case Notification::ItemIsPlaybackBufferFullChanged:
        updateStates();
        break;
    case Notification::PlayerRateChanged:
        updateStates();
        rateChanged();
        break;
    case Notification::PlayerTimeChanged:
        timeChanged(notification.time());
        break;
    case Notification::SeekCompleted:
        seekCompleted(notification.finished());
        break;
    case Notification::AssetMetadataLoaded:
        metadataLoaded();
        updateStates();
        break;
    case Notification::AssetPlayabilityKnown:
        updateStates();
        playabilityKnown();
        break;
    case Notification::DurationChanged:
        invalidateCachedDuration();
        break;
    case Notification::ContentsNeedsDisplay:
        contentsNeedsDisplay();
        break;
    case Notification::InbandTracksNeedConfiguration:
#if HAVE(AVFOUNDATION_TEXT_TRACK_SUPPORT)
        m_inbandTrackConfigurationPending = false;
        configureInbandTracks();
#endif
        break;

    case Notification::None:
        ASSERT_NOT_REACHED();
        break;
    }
}
예제 #4
0
LibraryScanner::LibraryScanner(TrackCollection* collection,
                               UserSettingsPointer pConfig)
              : m_pCollection(collection),
                m_libraryHashDao(m_database),
                m_cueDao(m_database),
                m_playlistDao(m_database),
                m_crateDao(m_database),
                m_directoryDao(m_database),
                m_analysisDao(m_database, pConfig),
                m_trackDao(m_database, m_cueDao, m_playlistDao,
                           m_crateDao, m_analysisDao, m_libraryHashDao,
                           pConfig),
                m_stateSema(1), // only one transaction is possible at a time
                m_state(IDLE) {
    // Don't initialize m_database here, we need to do it in run() so the DB
    // conn is in the right thread.
    qDebug() << "Starting LibraryScanner thread.";

    // Move LibraryScanner to its own thread so that our signals/slots will
    // queue to our event loop.
    moveToThread(this);
    m_pool.moveToThread(this);

    unsigned static id = 0; // the id of this LibraryScanner, for debugging purposes
    setObjectName(QString("LibraryScanner %1").arg(++id));

    m_pool.setMaxThreadCount(kScannerThreadPoolSize);

    // Listen to signals from our public methods (invoked by other threads) and
    // connect them to our slots to run the command on the scanner thread.
    connect(this, SIGNAL(startScan()),
            this, SLOT(slotStartScan()));

    // Force the GUI thread's TrackInfoObject cache to be cleared when a library
    // scan is finished, because we might have modified the database directly
    // when we detected moved files, and the TIOs corresponding to the moved
    // files would then have the wrong track location.
    if (collection != NULL) { // false only during test
        TrackDAO* dao = &(collection->getTrackDAO());
        connect(this, SIGNAL(scanFinished()), dao, SLOT(clearCache()));
        connect(this, SIGNAL(trackAdded(TrackPointer)),
                dao, SLOT(databaseTrackAdded(TrackPointer)));
        connect(this, SIGNAL(tracksMoved(QSet<TrackId>, QSet<TrackId>)),
                dao, SLOT(databaseTracksMoved(QSet<TrackId>, QSet<TrackId>)));
        connect(this, SIGNAL(tracksChanged(QSet<TrackId>)),
                dao, SLOT(databaseTracksChanged(QSet<TrackId>)));
    }

    m_pProgressDlg.reset(new LibraryScannerDlg());
    connect(this, SIGNAL(progressLoading(QString)),
            m_pProgressDlg.data(), SLOT(slotUpdate(QString)));
    connect(this, SIGNAL(progressHashing(QString)),
            m_pProgressDlg.data(), SLOT(slotUpdate(QString)));
    connect(this, SIGNAL(scanStarted()),
            m_pProgressDlg.data(), SLOT(slotScanStarted()));
    connect(this, SIGNAL(scanFinished()),
            m_pProgressDlg.data(), SLOT(slotScanFinished()));
    connect(m_pProgressDlg.data(), SIGNAL(scanCancelled()),
            this, SLOT(slotCancel()));
    connect(&m_trackDao, SIGNAL(progressVerifyTracksOutside(QString)),
            m_pProgressDlg.data(), SLOT(slotUpdate(QString)));
    connect(&m_trackDao, SIGNAL(progressCoverArt(QString)),
            m_pProgressDlg.data(), SLOT(slotUpdateCover(QString)));

    start();
}
void MediaPlayerPrivateAVFoundation::dispatchNotification()
{
    ASSERT(isMainThread());

    Notification notification = Notification();
    {
        LockHolder lock(m_queueMutex);
        
        if (m_queuedNotifications.isEmpty())
            return;
        
        if (!m_delayCallbacks) {
            // Only dispatch one notification callback per invocation because they can cause recursion.
            notification = m_queuedNotifications.first();
            m_queuedNotifications.remove(0);
        }
        
        if (!m_queuedNotifications.isEmpty() && !m_mainThreadCallPending) {
            callOnMainThread([weakThis = createWeakPtr()] {
                if (!weakThis)
                    return;

                weakThis->mainThreadCallback();
            });
        }

        if (!notification.isValid())
            return;
    }

    if (notification.type() != Notification::FunctionType)
        LOG(Media, "MediaPlayerPrivateAVFoundation::dispatchNotification(%p) - dispatching %s", this, notificationName(notification));

    switch (notification.type()) {
    case Notification::ItemDidPlayToEndTime:
        didEnd();
        break;
    case Notification::ItemTracksChanged:
        tracksChanged();
        updateStates();
        break;
    case Notification::ItemStatusChanged:
        updateStates();
        break;
    case Notification::ItemSeekableTimeRangesChanged:
        seekableTimeRangesChanged();
        updateStates();
        break;
    case Notification::ItemLoadedTimeRangesChanged:
        loadedTimeRangesChanged();
        updateStates();
        break;
    case Notification::ItemPresentationSizeChanged:
        sizeChanged();
        updateStates();
        break;
    case Notification::ItemIsPlaybackLikelyToKeepUpChanged:
        updateStates();
        break;
    case Notification::ItemIsPlaybackBufferEmptyChanged:
        updateStates();
        break;
    case Notification::ItemIsPlaybackBufferFullChanged:
        updateStates();
        break;
    case Notification::PlayerRateChanged:
        updateStates();
        rateChanged();
        break;
    case Notification::PlayerTimeChanged:
        timeChanged(notification.time());
        break;
    case Notification::SeekCompleted:
        seekCompleted(notification.finished());
        break;
    case Notification::AssetMetadataLoaded:
        metadataLoaded();
        updateStates();
        break;
    case Notification::AssetPlayabilityKnown:
        updateStates();
        playabilityKnown();
        break;
    case Notification::DurationChanged:
        invalidateCachedDuration();
        break;
    case Notification::ContentsNeedsDisplay:
        contentsNeedsDisplay();
        break;
    case Notification::InbandTracksNeedConfiguration:
        m_inbandTrackConfigurationPending = false;
        configureInbandTracks();
        break;
    case Notification::FunctionType:
        notification.function()();
        break;
    case Notification::TargetIsWirelessChanged:
#if ENABLE(WIRELESS_PLAYBACK_TARGET)
        playbackTargetIsWirelessChanged();
#endif
        break;

    case Notification::None:
        ASSERT_NOT_REACHED();
        break;
    }
}
void MediaPlayerPrivateAVFoundation::dispatchNotification()
{
    ASSERT(isMainThread());

    Notification notification = Notification();
    {
        MutexLocker lock(m_queueMutex);
        
        if (m_queuedNotifications.isEmpty())
            return;
        
        if (!m_delayCallbacks) {
            // Only dispatch one notification callback per invocation because they can cause recursion.
            notification = m_queuedNotifications.first();
            m_queuedNotifications.remove(0);
        }
        
        if (!m_queuedNotifications.isEmpty() && !m_mainThreadCallPending)
            callOnMainThread(mainThreadCallback, this);
        
        if (!notification.isValid())
            return;
    }

    LOG(Media, "MediaPlayerPrivateAVFoundation::dispatchNotification(%p) - dispatching %d", this, static_cast<int>(notification.type()));

    switch (notification.type()) {
    case Notification::ItemDidPlayToEndTime:
        didEnd();
        break;
    case Notification::ItemTracksChanged:
        tracksChanged();
        break;
    case Notification::ItemStatusChanged:
        loadStateChanged();
        break;
    case Notification::ItemSeekableTimeRangesChanged:
        seekableTimeRangesChanged();
        loadStateChanged();
        break;
    case Notification::ItemLoadedTimeRangesChanged:
        loadedTimeRangesChanged();
        loadStateChanged();
        break;
    case Notification::ItemPresentationSizeChanged:
        sizeChanged();
        break;
    case Notification::ItemIsPlaybackLikelyToKeepUpChanged:
        loadStateChanged();
        break;
    case Notification::ItemIsPlaybackBufferEmptyChanged:
        loadStateChanged();
        break;
    case Notification::ItemIsPlaybackBufferFullChanged:
        loadStateChanged();
        break;
    case Notification::PlayerRateChanged:
        rateChanged();
        break;
    case Notification::PlayerTimeChanged:
        timeChanged(notification.time());
        break;
    case Notification::AssetMetadataLoaded:
        metadataLoaded();
        break;
    case Notification::AssetPlayabilityKnown:
        playabilityKnown();
        break;
    case Notification::None:
        ASSERT_NOT_REACHED();
        break;
    }
}
예제 #7
0
void ShowManager::addItem(QQuickItem *parent, int trackIdx, int startTime, quint32 functionID)
{
    // if no show is selected, then create a new one
    if (m_currentShow == NULL)
    {
        QString defaultName = QString("%1 %2").arg(tr("New Show")).arg(m_doc->nextFunctionID());
        m_currentShow = new Show(m_doc);
        m_currentShow->setName(defaultName);
        Function *f = qobject_cast<Function*>(m_currentShow);
        if (m_doc->addFunction(f) == false)
        {
            qDebug() << "Error in creating a new Show !";
            m_currentShow = NULL;
            return;
        }
        connect(m_currentShow, SIGNAL(timeChanged(quint32)), this, SLOT(slotTimeChanged(quint32)));
        emit currentShowIDChanged(m_currentShow->id());
        emit showNameChanged(m_currentShow->name());
    }

    Track *selectedTrack = NULL;

    // if no Track index is provided, then add a new one
    if (trackIdx == -1)
    {
        selectedTrack = new Track();
        selectedTrack->setName(tr("Track %1").arg(m_currentShow->tracks().count() + 1));
        m_currentShow->addTrack(selectedTrack);
        trackIdx = m_currentShow->tracks().count() - 1;
        emit tracksChanged();
    }
    else
    {
        if (trackIdx >= m_currentShow->tracks().count())
        {
            qDebug() << "Track index out of bounds !" << trackIdx;
            return;
        }
        selectedTrack = m_currentShow->tracks().at(trackIdx);
    }

    // and now create the actual ShowFunction and the QML item
    Function *func = m_doc->function(functionID);
    if (func == NULL)
        return;

    ShowFunction *showFunc = selectedTrack->createShowFunction(functionID);
    showFunc->setStartTime(startTime);
    showFunc->setDuration(func->totalDuration());
    showFunc->setColor(ShowFunction::defaultColor(func->type()));

    QQuickItem *newItem = qobject_cast<QQuickItem*>(siComponent->create());

    newItem->setParentItem(parent);
    newItem->setProperty("trackIndex", trackIdx);
    newItem->setProperty("sfRef", QVariant::fromValue(showFunc));
    newItem->setProperty("funcRef", QVariant::fromValue(func));

    quint32 itemIndex = m_itemsMap.isEmpty() ? 0 : m_itemsMap.lastKey() + 1;
    quint32 itemID = trackIdx << 16 | itemIndex;
    m_itemsMap[itemID] = newItem;

    emit showDurationChanged(m_currentShow->totalDuration());
}
예제 #8
0
void QSpotifyPlayQueue::onOfflineModeChanged()
{
    if (m_shuffle && m_implicitTracks)
        m_implicitTracks->setShuffle(true);
    emit tracksChanged();
}
예제 #9
0
void QSpotifyPlayQueue::tracksUpdated()
{
    emit tracksChanged();
}