#include "MusicPlayer.h" #include #include #include MusicPlayer::MusicPlayer(QObject *parent) : QMediaPlayer(parent) { // init audio /// @todo remove magic number setVolume(50); // relay signal to qml connect(this, &QMediaPlayer::stateChanged, this, &MusicPlayer::isPlayingChanged); connect(this, &QMediaPlayer::currentMediaChanged, this, [this](const QMediaContent&){ // notify qml to refresh enable state of next and previous button emit hasNextChanged(); emit hasPreviousChanged(); }); connect(this, &QMediaPlayer::positionChanged, this, [this](qint64){ emit progressChanged(); }); connect(this, &QMediaPlayer::durationChanged, this, [this](qint64){ emit progressChanged(); emit mediaLengthChanged(); }); } void MusicPlayer::init(NavigationItemModel *item) { if(mCurrentItem == item){ return; } mCurrentItem = item; emit coverImageSourceChanged(); clearPlaylist(); readMedia(mCurrentItem->getPath()); } void MusicPlayer::navigateBack() { emit navigateTo(mCurrentItem); } void MusicPlayer::playPause() { if(isPlaying()) pause(); else play(); } void MusicPlayer::stopMusic() { if(isPlaying()){ stop(); resetPlaylistToFirstTrack(); } } void MusicPlayer::playNext() { if(!hasNext()) return; // checks if playlist exists playlist()->next(); } void MusicPlayer::playPrevious() { if(!hasPrevious()) return; // checks if playlist exists playlist()->previous(); } void MusicPlayer::resetPlaylistToFirstTrack() { if(!playlist() && !playlist()->isEmpty()) return; playlist()->setCurrentIndex(0); } bool MusicPlayer::isPlaying() const { return state() == State::PlayingState; } bool MusicPlayer::hasNext() const { if(!playlist()) return false; const auto nextIndex = playlist()->nextIndex(); /* player yields -1 as next index while playing last track */ return nextIndex >=0 && nextIndex < playlist()->mediaCount(); } bool MusicPlayer::hasPrevious() const { if(!playlist()) return false; const auto previousIndex = playlist()->previousIndex(); /* player inits with currentIndex -1 and hence previousIndex = last index * until started. Yet, previousButton should initially be disabled. */ return previousIndex >= 0 && previousIndex < playlist()->currentIndex(); } double MusicPlayer::getProgress() const { if(duration() <= 0 || position() < 0){ return 0.0; } return (double)position()/duration(); } QString MusicPlayer::getMediaTitle() const { return metaData("Title").toString(); } QString MusicPlayer::getMediaDuration() const { return millisecondsToString(duration()); } QString MusicPlayer::getPosition() const { return millisecondsToString(position()); } void MusicPlayer::clearPlaylist() { if(playlist()){ playlist()->clear(); } } void MusicPlayer::readMedia(const QString& path) { auto dir = QDir(path); if(!dir.exists()) return; // create playlist if necessary auto playList = playlist(); if(!playList){ playList = new QMediaPlaylist(this); setPlaylist(playList); } // add audio files to playlist dir.setNameFilters(SettingsHandler::getAudioFileNameFilters()); auto files = dir.entryInfoList(QDir::Files); for(auto file:files){ auto fileName = file.absoluteFilePath(); auto fileUrl = QUrl::fromLocalFile(fileName); playList->addMedia(QMediaContent(fileUrl)); } } QString MusicPlayer::millisecondsToString(int timeInMilliseconds) const { int seconds = timeInMilliseconds/1000; // ms to secons int minutes = seconds/60; //seconds to minutes seconds %= 60; // seconds remaining after subtracting minutes // format according to [M]M:ss // at leading zero to seconds if necessary QString secStr = (seconds < 10) ? "0"+QString::number(seconds) : QString::number(seconds); return QString::number(minutes) + ":" + secStr; }