MediaPlayer::MediaPlayer(QObject *parent) : QObject(parent) , _playlist(nullptr) , _state(QMediaPlayer::StoppedState) , _localPlayer(new QtAV::AVPlayer(this)) , _remotePlayer(nullptr) , _stopAfterCurrent(false) { connect(_localPlayer, &QtAV::AVPlayer::stopped, this, [=]() { this->setState(QMediaPlayer::StoppedState); }); connect(_localPlayer, &QtAV::AVPlayer::loaded, this, [=]() { _localPlayer->audio()->setVolume(Settings::instance()->volume()); emit currentMediaChanged(_localPlayer->file()); this->setState(QMediaPlayer::PlayingState); }); connect(_localPlayer, &QtAV::AVPlayer::paused, this, [=](bool) { this->setState(QMediaPlayer::PausedState); }); connect(_localPlayer, &QtAV::AVPlayer::positionChanged, this, [=](qint64 pos) { if (_state == QMediaPlayer::PlayingState) { emit positionChanged(pos, _localPlayer->duration()); } }); _localPlayer->audio()->setVolume(Settings::instance()->volume()); connect(this, &MediaPlayer::currentMediaChanged, this, [=] (const QString &uri) { QWindow *w = QGuiApplication::topLevelWindows().first(); TrackDAO t = SqlDatabase().selectTrackByURI(uri); if (t.artist().isEmpty()) { w->setTitle(t.title() + " - Miam Player"); } else { w->setTitle(t.title() + " (" + t.artist() + ") - Miam Player"); } }); // Link core multimedia actions connect(this, &MediaPlayer::mediaStatusChanged, this, [=] (QMediaPlayer::MediaStatus status) { if (_state != QMediaPlayer::StoppedState && status == QMediaPlayer::EndOfMedia) { if (_stopAfterCurrent) { stop(); _stopAfterCurrent = false; } else { skipForward(); } } }); }
/** Do a non-recursive import of all the songs in a directory. Does NOT decend into subdirectories. @param trackDao The track data access object which provides a connection to the database. We use this parameter in order to make this function callable from separate threads. You need to use a different DB connection for each thread. @return true if the scan completed without being cancelled. False if the scan was cancelled part-way through. */ bool TrackCollection::importDirectory(const QString& directory, TrackDAO& trackDao, const QStringList& nameFilters, volatile bool* cancel) { //qDebug() << "TrackCollection::importDirectory(" << directory<< ")"; emit(startedLoading()); // QFileInfoList files; //get a list of the contents of the directory and go through it. QDirIterator it(directory, nameFilters, QDir::Files | QDir::NoDotAndDotDot); while (it.hasNext()) { //If a flag was raised telling us to cancel the library scan then stop. if (*cancel) { return false; } QString absoluteFilePath = it.next(); // If the track is in the database, mark it as existing. This code gets exectuted // when other files in the same directory have changed (the directory hash has changed). trackDao.markTrackLocationAsVerified(absoluteFilePath); // If the file already exists in the database, continue and go on to // the next file. // If the file doesn't already exist in the database, then add // it. If it does exist in the database, then it is either in the // user's library OR the user has "removed" the track via // "Right-Click -> Remove". These tracks stay in the library, but // their mixxx_deleted column is 1. if (!trackDao.trackExistsInDatabase(absoluteFilePath)) { //qDebug() << "Loading" << it.fileName(); emit(progressLoading(it.fileName())); TrackPointer pTrack = TrackPointer(new TrackInfoObject( absoluteFilePath), &QObject::deleteLater); if (trackDao.addTracksAdd(pTrack.data(), false)) { // Successful added // signal the main instance of TrackDao, that there is a // new Track in the database m_trackDao->databaseTrackAdded(pTrack); } else { qDebug() << "Track ("+absoluteFilePath+") could not be added"; } } } emit(finishedLoading()); return true; }
void PlaylistDialog::populatePreviewFromSaved(const QItemSelection &, const QItemSelection &) { static const int MAX_TRACKS_PREVIEW_AREA = 30; QModelIndexList indexes = savedPlaylists->selectionModel()->selectedIndexes(); bool empty = indexes.isEmpty(); this->clearPreview(!empty); if (indexes.size() == 1) { uint playlistId = _savedPlaylistModel->itemFromIndex(indexes.first())->data(PlaylistID).toUInt(); QList<TrackDAO> tracks = SqlDatabase::instance()->selectPlaylistTracks(playlistId); for (int i = 0; i < tracks.size(); i++) { TrackDAO track = tracks.at(i); QTreeWidgetItem *item = new QTreeWidgetItem; item->setText(0, QString("%1 (%2 - %3)").arg(track.title(), track.artist(), track.album())); previewPlaylist->addTopLevelItem(item); if (i + 1 == MAX_TRACKS_PREVIEW_AREA) { QTreeWidgetItem *item = new QTreeWidgetItem; item->setText(0, tr("And more tracks...")); previewPlaylist->addTopLevelItem(item); break; } } } loadPlaylists->setDisabled(empty); deletePlaylists->setDisabled(empty); exportPlaylists->setEnabled(indexes.size() == 1); // Some work for the Save button if (empty) { savePlaylists->setEnabled(false); } else { bool allPlaylistsAreModified = true; QMap<uint, Playlist*> map; for (int i = 0; i < _playlists.count(); i++) { Playlist *p = _playlists.at(i); map.insert(p->id(), p); } for (QModelIndex idx : indexes) { uint playlistId = idx.data(PlaylistID).toUInt(); if (map.contains(playlistId)) { Playlist *p = map.value(playlistId); allPlaylistsAreModified = allPlaylistsAreModified && p->isModified(); } } savePlaylists->setEnabled(allPlaylistsAreModified); } }
void RemoteControl::sendTrackInfos(const QString &track) { if (!_webSocket) { return; } QStringList args; args << QString::number(CMD_Track); SqlDatabase db; TrackDAO dao = db.selectTrackByURI(track); args << dao.uri(); args << dao.artistAlbum(); args << dao.album(); args << dao.title(); args << dao.trackNumber(); args << QString::number(dao.rating()); _webSocket->sendTextMessage(args.join(QChar::Null)); // Send cover if any if (Cover *cover = db.selectCoverFromURI(track)) { _webSocket->sendBinaryMessage(cover->byteArray()); } }