mirror of
https://github.com/clangen/musikcube.git
synced 2025-01-29 03:32:42 +00:00
Added track fetching timeouts to PlaybackService. This should skirt a
couple edge cases and possibly allow us to not immediately stop playback when reconnecting.
This commit is contained in:
parent
5e23a21aa6
commit
a06d6f28d1
@ -60,6 +60,12 @@ using musik::core::ILibraryPtr;
|
|||||||
using musik::core::audio::ITransport;
|
using musik::core::audio::ITransport;
|
||||||
using Editor = PlaybackService::Editor;
|
using Editor = PlaybackService::Editor;
|
||||||
|
|
||||||
|
/* internally PlaybackService leverages a message queue for synchronization;
|
||||||
|
tracks are a special in that they are heavy-weight so aggressively exjected
|
||||||
|
from caches... sometimes we may have to query for them. if they take more than
|
||||||
|
the specified timeout we consider it a failure and stop playback. */
|
||||||
|
static const size_t kTrackTimeoutMs = 3000;
|
||||||
|
|
||||||
#define NO_POSITION (size_t) -1
|
#define NO_POSITION (size_t) -1
|
||||||
#define START_OVER (size_t) -2
|
#define START_OVER (size_t) -2
|
||||||
|
|
||||||
@ -332,13 +338,17 @@ void PlaybackService::ProcessMessage(IMessage &message) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (this->index != NO_POSITION) {
|
if (this->index != NO_POSITION) {
|
||||||
track = this->playlist.Get(this->index);
|
track = this->playlist.GetWithTimeout(this->index, kTrackTimeoutMs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (track) {
|
if (track) {
|
||||||
this->OnTrackChanged(this->index, track);
|
this->OnTrackChanged(this->index, track);
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
this->Stop();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (eventType == StreamPlaying) {
|
if (eventType == StreamPlaying) {
|
||||||
this->PrepareNextTrack();
|
this->PrepareNextTrack();
|
||||||
@ -365,10 +375,13 @@ void PlaybackService::ProcessMessage(IMessage &message) {
|
|||||||
/* notify track change as soon as we're prepared. if we wait until
|
/* notify track change as soon as we're prepared. if we wait until
|
||||||
we start playing, it may be a while until the UI knows to redraw! */
|
we start playing, it may be a while until the UI knows to redraw! */
|
||||||
if (this->UriAtIndex(this->index) == transport->Uri()) {
|
if (this->UriAtIndex(this->index) == transport->Uri()) {
|
||||||
auto track = this->playlist.Get(this->index);
|
auto track = this->playlist.GetWithTimeout(this->index, kTrackTimeoutMs);
|
||||||
if (track) {
|
if (track) {
|
||||||
this->OnTrackChanged(this->index, track);
|
this->OnTrackChanged(this->index, track);
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
this->Stop();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -589,26 +602,18 @@ bool PlaybackService::HotSwap(const TrackList& tracks, size_t index) {
|
|||||||
bool found = false;
|
bool found = false;
|
||||||
auto playingTrack = this->GetPlaying();
|
auto playingTrack = this->GetPlaying();
|
||||||
if (playingTrack && tracks.Count() > index) {
|
if (playingTrack && tracks.Count() > index) {
|
||||||
auto supplantTrack = tracks.Get(index);
|
|
||||||
auto supplantLibrary = supplantTrack->Library();
|
|
||||||
auto supplantId = tracks.GetId(index);
|
auto supplantId = tracks.GetId(index);
|
||||||
|
const auto playingId = playingTrack->GetId();
|
||||||
auto playingId = playingTrack->GetId();
|
|
||||||
auto playingLibrary = playingTrack->Library();
|
|
||||||
|
|
||||||
/* look at the index hint, see if we can find a matching track without
|
/* look at the index hint, see if we can find a matching track without
|
||||||
iteration. */
|
iteration. */
|
||||||
if (supplantId == playingId && supplantLibrary == playingLibrary) {
|
if (supplantId == playingId) {
|
||||||
found = true;
|
found = true;
|
||||||
}
|
}
|
||||||
/* otherwise search the input */
|
/* otherwise search the input */
|
||||||
else {
|
else {
|
||||||
for (size_t i = 0; i < tracks.Count(); i++) {
|
for (size_t i = 0; i < tracks.Count(); i++) {
|
||||||
supplantTrack = tracks.Get(i);
|
if (tracks.GetId(i) == playingId) {
|
||||||
auto supplantLibrary = supplantTrack->Library();
|
|
||||||
auto supplantId = supplantTrack->GetId();
|
|
||||||
|
|
||||||
if (supplantId == playingId && supplantLibrary == playingLibrary) {
|
|
||||||
index = i;
|
index = i;
|
||||||
found = true;
|
found = true;
|
||||||
}
|
}
|
||||||
@ -828,7 +833,7 @@ double PlaybackService::GetDuration() {
|
|||||||
|
|
||||||
size_t index = this->index;
|
size_t index = this->index;
|
||||||
if (index < this->playlist.Count()) {
|
if (index < this->playlist.Count()) {
|
||||||
track = this->playlist.Get(index);
|
track = this->playlist.GetWithTimeout(index, kTrackTimeoutMs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -845,7 +850,7 @@ ITrack* PlaybackService::GetTrack(size_t index) {
|
|||||||
const size_t count = this->playlist.Count();
|
const size_t count = this->playlist.Count();
|
||||||
|
|
||||||
if (count && index < this->playlist.Count()) {
|
if (count && index < this->playlist.Count()) {
|
||||||
auto track = this->playlist.Get(index);
|
auto track = this->playlist.GetWithTimeout(index, kTrackTimeoutMs * 10);
|
||||||
if (track) {
|
if (track) {
|
||||||
return track->GetSdkValue();
|
return track->GetSdkValue();
|
||||||
}
|
}
|
||||||
@ -876,7 +881,7 @@ TrackPtr PlaybackService::GetTrackAtIndex(size_t index) {
|
|||||||
return TrackPtr();
|
return TrackPtr();
|
||||||
}
|
}
|
||||||
|
|
||||||
return this->playlist.Get(index);
|
return this->playlist.GetWithTimeout(index, kTrackTimeoutMs);
|
||||||
}
|
}
|
||||||
|
|
||||||
Editor PlaybackService::Edit() {
|
Editor PlaybackService::Edit() {
|
||||||
@ -1101,7 +1106,7 @@ void PlaybackService::Editor::Release() {
|
|||||||
|
|
||||||
std::string PlaybackService::UriAtIndex(size_t index) {
|
std::string PlaybackService::UriAtIndex(size_t index) {
|
||||||
if (index < this->playlist.Count()) {
|
if (index < this->playlist.Count()) {
|
||||||
auto track = this->playlist.Get(index);
|
auto track = this->playlist.GetWithTimeout(index, kTrackTimeoutMs);
|
||||||
if (track) {
|
if (track) {
|
||||||
return this->library->GetResourceLocator().GetTrackUri(track.get());
|
return this->library->GetResourceLocator().GetTrackUri(track.get());
|
||||||
}
|
}
|
||||||
@ -1128,7 +1133,7 @@ ITransport::Gain PlaybackService::GainAtIndex(size_t index) {
|
|||||||
Mode mode = (Mode)playbackPrefs->GetInt(keys::ReplayGainMode.c_str(), (int) Mode::Disabled);
|
Mode mode = (Mode)playbackPrefs->GetInt(keys::ReplayGainMode.c_str(), (int) Mode::Disabled);
|
||||||
|
|
||||||
if (mode != Mode::Disabled && index < this->playlist.Count()) {
|
if (mode != Mode::Disabled && index < this->playlist.Count()) {
|
||||||
auto track = this->playlist.Get(index);
|
auto track = this->playlist.GetWithTimeout(index, kTrackTimeoutMs);
|
||||||
if (track) {
|
if (track) {
|
||||||
auto rg = track->GetReplayGain();
|
auto rg = track->GetReplayGain();
|
||||||
float gain = (mode == Mode::Album) ? rg.albumGain : rg.trackGain;
|
float gain = (mode == Mode::Album) ? rg.albumGain : rg.trackGain;
|
||||||
|
@ -172,6 +172,22 @@ TrackPtr TrackList::Get(size_t index, bool async) const {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TrackPtr TrackList::GetWithTimeout(size_t index, size_t timeoutMs) const {
|
||||||
|
auto id = this->ids.at(index);
|
||||||
|
auto cached = this->GetFromCache(id);
|
||||||
|
if (cached) { return cached; }
|
||||||
|
|
||||||
|
auto target = std::make_shared<LibraryTrack>(id, this->library);
|
||||||
|
auto query = std::make_shared<TrackMetadataQuery>(target, this->library);
|
||||||
|
this->library->EnqueueAndWait(query, timeoutMs);
|
||||||
|
if (query->GetStatus() == IQuery::Finished) {
|
||||||
|
this->AddToCache(id, query->Result());
|
||||||
|
return query->Result();
|
||||||
|
}
|
||||||
|
|
||||||
|
return TrackPtr();
|
||||||
|
}
|
||||||
|
|
||||||
ITrack* TrackList::GetTrack(size_t index) const {
|
ITrack* TrackList::GetTrack(size_t index) const {
|
||||||
return this->Get(index)->GetSdkValue();
|
return this->Get(index)->GetSdkValue();
|
||||||
}
|
}
|
||||||
|
@ -79,8 +79,7 @@ namespace musik { namespace core {
|
|||||||
|
|
||||||
/* implementation specific */
|
/* implementation specific */
|
||||||
TrackPtr Get(size_t index, bool async = false) const;
|
TrackPtr Get(size_t index, bool async = false) const;
|
||||||
TrackPtr GetSync(size_t index) const { return this->Get(index, false); }
|
TrackPtr GetWithTimeout(size_t index, size_t timeoutMs) const;
|
||||||
TrackPtr GetAsync(size_t index) const { return this->Get(index, true); }
|
|
||||||
void ClearCache();
|
void ClearCache();
|
||||||
void Swap(TrackList& list);
|
void Swap(TrackList& list);
|
||||||
void CopyFrom(const TrackList& from);
|
void CopyFrom(const TrackList& from);
|
||||||
|
@ -292,16 +292,11 @@ void MainLayout::SwitchToLibraryLayout() {
|
|||||||
|
|
||||||
void MainLayout::OnLibraryConnectionStateChanged(ILibrary::ConnectionState state) {
|
void MainLayout::OnLibraryConnectionStateChanged(ILibrary::ConnectionState state) {
|
||||||
auto currentLayout = this->GetLayout();
|
auto currentLayout = this->GetLayout();
|
||||||
|
|
||||||
if (currentLayout == this->libraryLayout ||
|
if (currentLayout == this->libraryLayout ||
|
||||||
currentLayout == this->libraryNotConnectedLayout)
|
currentLayout == this->libraryNotConnectedLayout)
|
||||||
{
|
{
|
||||||
this->SwitchToLibraryLayout();
|
this->SwitchToLibraryLayout();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state == ILibrary::ConnectionState::Disconnected) {
|
|
||||||
this->playback.Stop();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainLayout::OnLibraryChanged(musik::core::ILibraryPtr prev, musik::core::ILibraryPtr curr) {
|
void MainLayout::OnLibraryChanged(musik::core::ILibraryPtr prev, musik::core::ILibraryPtr curr) {
|
||||||
|
@ -93,6 +93,7 @@ TrackListView::TrackListView(
|
|||||||
this->decorator = decorator;
|
this->decorator = decorator;
|
||||||
this->trackNumType = TrackRowRenderers::TrackNumType::Metadata;
|
this->trackNumType = TrackRowRenderers::TrackNumType::Metadata;
|
||||||
this->renderer = TrackRowRenderers::Get(TrackRowRenderers::Type::AlbumSort);
|
this->renderer = TrackRowRenderers::Get(TrackRowRenderers::Type::AlbumSort);
|
||||||
|
this->playing = playback.GetPlaying();
|
||||||
}
|
}
|
||||||
|
|
||||||
TrackListView::~TrackListView() {
|
TrackListView::~TrackListView() {
|
||||||
|
@ -373,6 +373,7 @@ TransportWindow::TransportWindow(
|
|||||||
this->repeatPos.y = 1;
|
this->repeatPos.y = 1;
|
||||||
this->volumePos.y = 1;
|
this->volumePos.y = 1;
|
||||||
this->timePos.y = 1;
|
this->timePos.y = 1;
|
||||||
|
this->currentTrack = playback.GetPlaying();
|
||||||
this->UpdateReplayGainState();
|
this->UpdateReplayGainState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user