165 lines
4 KiB
C++
165 lines
4 KiB
C++
#include "MusicPlayer.h"
|
|
#include <QDir>
|
|
#include <QMediaPlaylist>
|
|
#include <controllers/SettingsHandler.h>
|
|
|
|
|
|
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;
|
|
}
|