156 lines
3.5 KiB
C++
156 lines
3.5 KiB
C++
#include "MusicPlayer.h"
|
|
#include <QDir>
|
|
#include <QMediaPlaylist>
|
|
|
|
|
|
|
|
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();
|
|
|
|
clearMediaList();
|
|
|
|
readMedia(mCurrentItem->getPath());
|
|
}
|
|
|
|
void MusicPlayer::navigateBack()
|
|
{
|
|
emit navigateTo(mCurrentItem);
|
|
}
|
|
|
|
void MusicPlayer::playPause()
|
|
{
|
|
if(isPlaying())
|
|
pause();
|
|
else
|
|
play();
|
|
}
|
|
|
|
void MusicPlayer::stopMusic()
|
|
{
|
|
if(isPlaying()){
|
|
stop();
|
|
}
|
|
}
|
|
|
|
void MusicPlayer::playNext()
|
|
{
|
|
if(!hasNext()) return; // checks if playlist exists
|
|
playlist()->next();
|
|
}
|
|
|
|
void MusicPlayer::playPrevious()
|
|
{
|
|
if(!hasPrevious()) return;
|
|
playlist()->previous();
|
|
}
|
|
|
|
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 mMediaTitle;
|
|
}
|
|
|
|
QString MusicPlayer::getMediaLength()
|
|
{
|
|
return timeToString(duration());
|
|
}
|
|
|
|
QString MusicPlayer::getTime()
|
|
{
|
|
return timeToString(position());
|
|
}
|
|
|
|
void MusicPlayer::clearMediaList()
|
|
{
|
|
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({"*.mp3", "*.flac"});
|
|
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::timeToString(int time)
|
|
{
|
|
int sec = time/1000;
|
|
int min = sec/60;
|
|
sec = sec-min*60;
|
|
QString secStr = (sec < 10) ? "0"+QString::number(sec) : QString::number(sec);
|
|
return QString::number(min) + ":" + secStr;
|
|
}
|