mirror of
https://github.com/sle118/squeezelite-esp32.git
synced 2025-12-09 21:17:18 +03:00
add missing files, removing un-nedded ones
This commit is contained in:
@@ -1,10 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstddef> // for size_t
|
||||
#include <cstdint> // for uint8_t
|
||||
#include <memory> // for shared_ptr, unique_ptr
|
||||
#include <string> // for string
|
||||
#include <vector> // for vector
|
||||
#include <cstddef> // for size_t
|
||||
#include <cstdint> // for uint8_t
|
||||
#include <memory> // for shared_ptr, unique_ptr
|
||||
#include <string> // for string
|
||||
#include <vector> // for vector
|
||||
|
||||
#include "Crypto.h" // for Crypto
|
||||
#include "HTTPClient.h" // for HTTPClient
|
||||
@@ -16,46 +16,45 @@ class WrappedSemaphore;
|
||||
namespace cspot {
|
||||
class AccessKeyFetcher;
|
||||
|
||||
class CDNTrackStream {
|
||||
class CDNAudioFile {
|
||||
|
||||
public:
|
||||
CDNTrackStream(std::shared_ptr<cspot::AccessKeyFetcher>);
|
||||
~CDNTrackStream();
|
||||
|
||||
enum class Status { INITIALIZING, HAS_DATA, HAS_URL, FAILED };
|
||||
|
||||
struct TrackInfo {
|
||||
std::string trackId;
|
||||
std::string name;
|
||||
std::string album;
|
||||
std::string artist;
|
||||
std::string imageUrl;
|
||||
int duration;
|
||||
};
|
||||
|
||||
TrackInfo trackInfo;
|
||||
|
||||
Status status;
|
||||
std::unique_ptr<bell::WrappedSemaphore> trackReady;
|
||||
|
||||
void fetchFile(const std::vector<uint8_t>& trackId,
|
||||
const std::vector<uint8_t>& audioKey);
|
||||
|
||||
void fail();
|
||||
CDNAudioFile(const std::string& cdnUrl, const std::vector<uint8_t>& audioKey);
|
||||
|
||||
/**
|
||||
* @brief Opens connection to the provided cdn url, and fetches track metadata.
|
||||
*/
|
||||
void openStream();
|
||||
|
||||
/**
|
||||
* @brief Read and decrypt part of the cdn stream
|
||||
*
|
||||
* @param dst buffer where to read received data to
|
||||
* @param amount of bytes to read
|
||||
*
|
||||
* @returns amount of bytes read
|
||||
*/
|
||||
size_t readBytes(uint8_t* dst, size_t bytes);
|
||||
|
||||
/**
|
||||
* @brief Returns current position in CDN stream
|
||||
*/
|
||||
size_t getPosition();
|
||||
|
||||
/**
|
||||
* @brief returns total size of the audio file in bytes
|
||||
*/
|
||||
size_t getSize();
|
||||
|
||||
/**
|
||||
* @brief Seeks the track to provided position
|
||||
* @param position position where to seek the track
|
||||
*/
|
||||
void seek(size_t position);
|
||||
|
||||
private:
|
||||
const int OPUS_HEADER_SIZE = 8 * 1024;
|
||||
const int OPUS_FOOTER_PREFFERED = 1024 * 12; // 12K should be safe
|
||||
const int OPUS_FOOTER_PREFFERED = 1024 * 12; // 12K should be safe
|
||||
const int SEEK_MARGIN_SIZE = 1024 * 4;
|
||||
|
||||
const int HTTP_BUFFER_SIZE = 1024 * 14;
|
||||
@@ -74,12 +73,9 @@ class CDNTrackStream {
|
||||
0x3f, 0x63, 0x0d, 0x93};
|
||||
std::unique_ptr<Crypto> crypto;
|
||||
|
||||
std::shared_ptr<cspot::AccessKeyFetcher> accessKeyFetcher;
|
||||
|
||||
std::unique_ptr<bell::HTTPClient::Response> httpConnection;
|
||||
bool isConnected = false;
|
||||
|
||||
size_t position = 0; // Spotify header size
|
||||
size_t position = 0;
|
||||
size_t totalFileSize = 0;
|
||||
size_t lastRequestPosition = 0;
|
||||
size_t lastRequestCapacity = 0;
|
||||
@@ -87,7 +83,6 @@ class CDNTrackStream {
|
||||
bool enableRequestMargin = false;
|
||||
|
||||
std::string cdnUrl;
|
||||
std::vector<uint8_t> trackId;
|
||||
std::vector<uint8_t> audioKey;
|
||||
|
||||
void decrypt(uint8_t* dst, size_t nbytes, size_t pos);
|
||||
@@ -1,40 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h> // for uint8_t
|
||||
#include <memory> // for shared_ptr, unique_ptr, weak_ptr
|
||||
#include <vector> // for vector
|
||||
|
||||
#include "MercurySession.h" // for MercurySession
|
||||
#include "TrackReference.h" // for TrackReference
|
||||
#include "protobuf/metadata.pb.h" // for Episode, Restriction, Track
|
||||
|
||||
namespace cspot {
|
||||
class AccessKeyFetcher;
|
||||
class CDNTrackStream;
|
||||
struct Context;
|
||||
|
||||
class TrackProvider {
|
||||
public:
|
||||
TrackProvider(std::shared_ptr<cspot::Context> ctx);
|
||||
~TrackProvider();
|
||||
|
||||
std::shared_ptr<CDNTrackStream> loadFromTrackRef(TrackReference& trackRef);
|
||||
|
||||
private:
|
||||
std::shared_ptr<AccessKeyFetcher> accessKeyFetcher;
|
||||
std::shared_ptr<cspot::Context> ctx;
|
||||
std::unique_ptr<cspot::CDNTrackStream> cdnStream;
|
||||
|
||||
Track trackInfo;
|
||||
Episode episodeInfo;
|
||||
std::weak_ptr<CDNTrackStream> currentTrackReference;
|
||||
TrackReference trackIdInfo;
|
||||
|
||||
void queryMetadata();
|
||||
void onMetadataResponse(MercurySession::Response& res);
|
||||
bool doRestrictionsApply(Restriction* restrictions, int count);
|
||||
void fetchFile(const std::vector<uint8_t>& fileId,
|
||||
const std::vector<uint8_t>& trackId);
|
||||
bool canPlayTrack(int index);
|
||||
};
|
||||
} // namespace cspot
|
||||
134
components/spotify/cspot/include/TrackQueue.h
Normal file
134
components/spotify/cspot/include/TrackQueue.h
Normal file
@@ -0,0 +1,134 @@
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h> // for size_t
|
||||
#include <atomic>
|
||||
#include <deque>
|
||||
#include <mutex>
|
||||
#include <functional>
|
||||
|
||||
#include "BellTask.h"
|
||||
#include "PlaybackState.h"
|
||||
#include "TrackReference.h"
|
||||
|
||||
#include "protobuf/metadata.pb.h" // for Track, _Track, AudioFile, Episode
|
||||
|
||||
namespace bell {
|
||||
class WrappedSemaphore;
|
||||
};
|
||||
|
||||
namespace cspot {
|
||||
struct Context;
|
||||
class AccessKeyFetcher;
|
||||
class CDNAudioFile;
|
||||
|
||||
// Used in got track info event
|
||||
struct TrackInfo {
|
||||
std::string name, album, artist, imageUrl, trackId;
|
||||
uint32_t duration;
|
||||
|
||||
void loadPbTrack(Track* pbTrack, const std::vector<uint8_t>& gid);
|
||||
void loadPbEpisode(Episode* pbEpisode, const std::vector<uint8_t>& gid);
|
||||
};
|
||||
|
||||
class QueuedTrack {
|
||||
public:
|
||||
QueuedTrack(TrackReference& ref, std::shared_ptr<cspot::Context> ctx,
|
||||
uint32_t requestedPosition = 0);
|
||||
~QueuedTrack();
|
||||
|
||||
enum class State {
|
||||
QUEUED,
|
||||
PENDING_META,
|
||||
KEY_REQUIRED,
|
||||
PENDING_KEY,
|
||||
CDN_REQUIRED,
|
||||
READY,
|
||||
FAILED
|
||||
};
|
||||
|
||||
std::shared_ptr<bell::WrappedSemaphore> loadedSemaphore;
|
||||
|
||||
State state = State::QUEUED; // Current state of the track
|
||||
TrackReference ref; // Holds GID, URI and Context
|
||||
TrackInfo trackInfo; // Full track information fetched from spotify, name etc
|
||||
|
||||
uint32_t requestedPosition;
|
||||
std::string identifier;
|
||||
|
||||
// Will return nullptr if the track is not ready
|
||||
std::shared_ptr<cspot::CDNAudioFile> getAudioFile();
|
||||
|
||||
// --- Steps ---
|
||||
void stepLoadMetadata(
|
||||
Track* pbTrack, Episode* pbEpisode, std::mutex& trackListMutex,
|
||||
std::shared_ptr<bell::WrappedSemaphore> updateSemaphore);
|
||||
|
||||
void stepParseMetadata(Track* pbTrack, Episode* pbEpisode);
|
||||
|
||||
void stepLoadAudioFile(
|
||||
std::mutex& trackListMutex,
|
||||
std::shared_ptr<bell::WrappedSemaphore> updateSemaphore);
|
||||
|
||||
void stepLoadCDNUrl(const std::string& accessKey);
|
||||
|
||||
void expire();
|
||||
|
||||
private:
|
||||
std::shared_ptr<cspot::Context> ctx;
|
||||
|
||||
uint64_t pendingMercuryRequest = 0;
|
||||
uint32_t pendingAudioKeyRequest = 0;
|
||||
|
||||
std::vector<uint8_t> trackId, fileId, audioKey;
|
||||
std::string cdnUrl;
|
||||
};
|
||||
|
||||
class TrackQueue : public bell::Task {
|
||||
public:
|
||||
TrackQueue(std::shared_ptr<cspot::Context> ctx,
|
||||
std::shared_ptr<cspot::PlaybackState> playbackState);
|
||||
~TrackQueue();
|
||||
|
||||
enum class SkipDirection { NEXT, PREV };
|
||||
|
||||
std::shared_ptr<bell::WrappedSemaphore> playableSemaphore;
|
||||
std::atomic<bool> notifyPending = false;
|
||||
|
||||
|
||||
void runTask() override;
|
||||
void stopTask();
|
||||
|
||||
bool hasTracks();
|
||||
bool isFinished();
|
||||
bool skipTrack(SkipDirection dir, bool expectNotify = true);
|
||||
void 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);
|
||||
|
||||
private:
|
||||
static const int MAX_TRACKS_PRELOAD = 3;
|
||||
|
||||
std::shared_ptr<cspot::AccessKeyFetcher> accessKeyFetcher;
|
||||
std::shared_ptr<PlaybackState> playbackState;
|
||||
std::shared_ptr<cspot::Context> ctx;
|
||||
std::shared_ptr<bell::WrappedSemaphore> processSemaphore;
|
||||
|
||||
std::deque<std::shared_ptr<QueuedTrack>> preloadedTracks;
|
||||
std::vector<TrackReference> currentTracks;
|
||||
std::mutex tracksMutex, runningMutex;
|
||||
|
||||
// PB data
|
||||
Track pbTrack;
|
||||
Episode pbEpisode;
|
||||
|
||||
std::string accessKey;
|
||||
|
||||
int16_t currentTracksIndex = -1;
|
||||
|
||||
bool isRunning = false;
|
||||
|
||||
void processTrack(std::shared_ptr<QueuedTrack> track);
|
||||
bool queueNextTrack(int offset = 0, uint32_t positionMs = 0);
|
||||
};
|
||||
} // namespace cspot
|
||||
Reference in New Issue
Block a user