Przeglądaj źródła

gap when changing queue workaround

philippe44 1 rok temu
rodzic
commit
f6269a2f7a

+ 0 - 1
components/spotify/cspot/include/TrackPlayer.h

@@ -37,7 +37,6 @@ class TrackPlayer : bell::Task {
   typedef std::function<size_t(uint8_t*, size_t, std::string_view)>
       DataCallback;
   typedef std::function<void()> EOFCallback;
-  typedef std::function<bool()> isAiringCallback;
 
   TrackPlayer(std::shared_ptr<cspot::Context> ctx,
               std::shared_ptr<cspot::TrackQueue> trackQueue,

+ 2 - 1
components/spotify/cspot/include/TrackQueue.h

@@ -54,6 +54,7 @@ class QueuedTrack {
 
   uint32_t requestedPosition;
   std::string identifier;
+  bool loading = false;
 
   // Will return nullptr if the track is not ready
   std::shared_ptr<cspot::CDNAudioFile> getAudioFile();
@@ -100,7 +101,7 @@ class TrackQueue : public bell::Task {
   bool hasTracks();
   bool isFinished();
   bool skipTrack(SkipDirection dir, bool expectNotify = true);
-  void updateTracks(uint32_t requestedPosition = 0, bool initial = false);
+  bool updateTracks(uint32_t requestedPosition = 0, bool initial = false);
   TrackInfo getTrackInfo(std::string_view identifier);
   std::shared_ptr<QueuedTrack> consumeTrack(
       std::shared_ptr<QueuedTrack> prevSong, int& offset);

+ 8 - 6
components/spotify/cspot/src/SpircHandler.cpp

@@ -205,16 +205,18 @@ void SpircHandler::handleFrame(std::vector<uint8_t>& data) {
       playbackState->syncWithRemote();
 
       // 1st track is the current one, but update the position
-      trackQueue->updateTracks(
+      bool cleared = trackQueue->updateTracks(
           playbackState->remoteFrame.state.position_ms +
-              ctx->timeProvider->getSyncedTimestamp() -
-              playbackState->innerFrame.state.position_measured_at,
-          false);
+          ctx->timeProvider->getSyncedTimestamp() -
+          playbackState->innerFrame.state.position_measured_at);
 
       this->notify();
 
-      sendEvent(EventType::FLUSH);
-      trackPlayer->resetState();
+      // need to re-load all if streaming track is completed
+      if (cleared) {
+          sendEvent(EventType::FLUSH);
+          trackPlayer->resetState();
+      }
       break;
     }
     case MessageType_kMessageTypeShuffle: {

+ 2 - 0
components/spotify/cspot/src/TrackPlayer.cpp

@@ -201,6 +201,7 @@ void TrackPlayer::runTask() {
       }
 
       eof = false;
+      track->loading = true;
 
       CSPOT_LOG(info, "Playing");
 
@@ -255,6 +256,7 @@ void TrackPlayer::runTask() {
 
       // always move back to LOADING (ensure proper seeking after last track has been loaded)
       currentTrackStream = nullptr;
+      track->loading = false;
     }
 
     if (eof) {

+ 22 - 6
components/spotify/cspot/src/TrackQueue.cpp

@@ -587,8 +587,9 @@ bool TrackQueue::isFinished() {
   return currentTracksIndex >= currentTracks.size() - 1;
 }
 
-void TrackQueue::updateTracks(uint32_t requestedPosition, bool initial) {
+bool TrackQueue::updateTracks(uint32_t requestedPosition, bool initial) {
   std::scoped_lock lock(tracksMutex);
+  bool cleared = true;
 
   if (initial) {
     // Clear preloaded tracks
@@ -609,13 +610,28 @@ void TrackQueue::updateTracks(uint32_t requestedPosition, bool initial) {
 
     playableSemaphore->give();
   } else {
-    // Clear preloaded tracks
-    preloadedTracks.clear();
-
     // Copy requested track list
     currentTracks = playbackState->remoteTracks;
 
-    // Push a song on the preloaded queue
-    queueNextTrack(0, requestedPosition);
+    // try to not re-load track if we are still loading it
+    if (preloadedTracks[0]->loading) {
+      // remove everything except first track
+      preloadedTracks.erase(preloadedTracks.begin() + 1, preloadedTracks.end());
+
+      // Push a song on the preloaded queue
+      CSPOT_LOG(info, "Keeping current track");
+      queueNextTrack(1);
+
+      cleared = false;
+    } else {
+      // Clear preloaded tracks
+      preloadedTracks.clear();
+
+      // Push a song on the preloaded queue
+      CSPOT_LOG(info, "Re-loading current track");
+      queueNextTrack(0, requestedPosition);
+    }
   }
+
+  return cleared;
 }