Commit f07d305e authored by Michael Pyne's avatar Michael Pyne

PlayerManager: Queue up next tracks instead of stop/play cycle.

I did this because I got annoyed about my own log messages about
inhibiting/uninhibiting power management.

This ultimately was because Phonon forces a stop and then restart
sequence whenever forcibly changing the current media source, as we were
doing to switch tracks.

Phonon provides a way to queue up additional tracks to play when
playback is about to end which keeps itself in a playing state. I use
this method, which may also theoretically make gapless playback work.
parent d5123cc6
......@@ -26,6 +26,7 @@
#include <Phonon/AudioOutput>
#include <Phonon/MediaObject>
#include <Phonon/MediaSource>
#include <QPixmap>
#include <QTimer>
......@@ -49,6 +50,18 @@ using namespace ActionCollection;
enum PlayerManagerStatus { StatusStopped = -1, StatusPaused = 1, StatusPlaying = 2 };
////////////////////////////////////////////////////////////////////////////////
// static functions
////////////////////////////////////////////////////////////////////////////////
static void updateWindowTitle(const FileHandle &file)
{
JuK::JuKInstance()->setWindowTitle(i18nc(
"%1 is the artist and %2 is the title of the currently playing track.",
"%1 - %2 :: JuK",
file.tag()->artist(),
file.tag()->title()));
}
////////////////////////////////////////////////////////////////////////////////
// protected members
////////////////////////////////////////////////////////////////////////////////
......@@ -402,12 +415,7 @@ void PlayerManager::slotStateChanged(Phonon::State newstate, Phonon::State)
action("forwardAlbum")->setEnabled(true);
action("back")->setEnabled(true);
JuK::JuKInstance()->setWindowTitle(i18nc(
"%1 is the artist and %2 is the title of the currently playing track.",
"%1 - %2 :: JuK",
m_file.tag()->artist(),
m_file.tag()->title()));
updateWindowTitle(m_file);
emit signalPlay();
}
}
......@@ -443,8 +451,10 @@ void PlayerManager::setupAudio()
connect(m_output, &AudioOutput::volumeChanged, this, &PlayerManager::slotVolumeChanged);
connect(m_media, &MediaObject::stateChanged, this, &PlayerManager::slotStateChanged);
connect(m_media, &MediaObject::currentSourceChanged, this, &PlayerManager::trackHasChanged);
connect(m_media, &MediaObject::totalTimeChanged, this, &PlayerManager::slotLength);
connect(m_media, &MediaObject::tick, this, &PlayerManager::slotTick);
connect(m_media, &MediaObject::aboutToFinish, this, &PlayerManager::trackAboutToFinish);
connect(m_media, &MediaObject::finished, this, &PlayerManager::slotFinished);
connect(m_media, &MediaObject::seekableChanged, this, &PlayerManager::slotSeekableChanged);
......@@ -470,4 +480,35 @@ void PlayerManager::setRandomPlayMode(const QString &randomMode)
action<KToggleAction>("disableRandomPlay")->setChecked(true);
}
void PlayerManager::trackHasChanged(const Phonon::MediaSource &newSource)
{
if(newSource.type() == Phonon::MediaSource::Url) {
const auto item = CollectionList::instance()->lookup(newSource.url().path());
if(item) {
const auto newFile = item->file();
if(m_file != newFile)
emit signalItemChanged(newFile);
m_file = newFile;
updateWindowTitle(m_file);
}
} else {
qCWarning(JUK_LOG) << "Track has changed so something we didn't set???";
return;
}
}
void PlayerManager::trackAboutToFinish()
{
// Called when playback is in progress and a track is about to finish, gives us a
// chance to keep audio playback going without Phonon entering StoppedState
if(!m_playlistInterface)
return;
m_playlistInterface->playNext();
const auto file = m_playlistInterface->currentFile();
if(!file.isNull())
m_media->enqueue(QUrl::fromLocalFile(file.absFilePath()));
}
// vim: set et sw=4 tw=0 sta:
......@@ -33,6 +33,7 @@ namespace Phonon
{
class AudioOutput;
class MediaObject;
class MediaSource;
}
/**
......@@ -95,6 +96,9 @@ public slots:
void setMuted(bool m);
bool mute();
void trackHasChanged(const Phonon::MediaSource &newSource);
void trackAboutToFinish();
void setRandomPlayMode(const QString &randomMode);
signals:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment