mirror of
https://github.com/sle118/squeezelite-esp32.git
synced 2025-12-09 13:07:03 +03:00
updated CSpot
This commit is contained in:
@@ -24,20 +24,18 @@ PlayerState::PlayerState(std::shared_ptr<TimeProvider> timeProvider)
|
||||
innerFrame.state.repeat = false;
|
||||
innerFrame.state.has_repeat = true;
|
||||
|
||||
innerFrame.device_state.has_sw_version = true;
|
||||
pbPutCharArray(swVersion, innerFrame.device_state.sw_version);
|
||||
innerFrame.device_state.sw_version = strdup(swVersion);
|
||||
|
||||
innerFrame.device_state.is_active = false;
|
||||
innerFrame.device_state.has_is_active = true;
|
||||
|
||||
|
||||
innerFrame.device_state.can_play = true;
|
||||
innerFrame.device_state.has_can_play = true;
|
||||
|
||||
innerFrame.device_state.volume = configMan->volume;
|
||||
innerFrame.device_state.has_volume = true;
|
||||
|
||||
innerFrame.device_state.has_name = true;
|
||||
pbPutString(configMan->deviceName, innerFrame.device_state.name);
|
||||
innerFrame.device_state.name = strdup(configMan->deviceName.c_str());
|
||||
|
||||
// Prepare player's capabilities
|
||||
addCapability(CapabilityType_kCanBePlayer, 1);
|
||||
@@ -55,33 +53,32 @@ PlayerState::PlayerState(std::shared_ptr<TimeProvider> timeProvider)
|
||||
}
|
||||
|
||||
PlayerState::~PlayerState() {
|
||||
pb_release(Frame_fields, &innerFrame);
|
||||
pb_release(Frame_fields, &remoteFrame);
|
||||
// do not destruct inner frame as it is never allocated
|
||||
// pb_release(Frame_fields, &innerFrame);
|
||||
}
|
||||
|
||||
void PlayerState::setPlaybackState(const PlaybackState state)
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
case PlaybackState::Loading:
|
||||
// Prepare the playback at position 0
|
||||
innerFrame.state.status = PlayStatus_kPlayStatusPause;
|
||||
innerFrame.state.position_ms = 0;
|
||||
innerFrame.state.position_measured_at = timeProvider->getSyncedTimestamp();
|
||||
break;
|
||||
case PlaybackState::Playing:
|
||||
innerFrame.state.status = PlayStatus_kPlayStatusPlay;
|
||||
innerFrame.state.position_measured_at = timeProvider->getSyncedTimestamp();
|
||||
break;
|
||||
case PlaybackState::Stopped:
|
||||
break;
|
||||
case PlaybackState::Paused:
|
||||
// Update state and recalculate current song position
|
||||
innerFrame.state.status = PlayStatus_kPlayStatusPause;
|
||||
uint32_t diff = timeProvider->getSyncedTimestamp() - innerFrame.state.position_measured_at;
|
||||
this->updatePositionMs(innerFrame.state.position_ms + diff);
|
||||
break;
|
||||
case PlaybackState::Loading:
|
||||
// Prepare the playback at position 0
|
||||
innerFrame.state.status = PlayStatus_kPlayStatusPause;
|
||||
innerFrame.state.position_ms = 0;
|
||||
innerFrame.state.position_measured_at = timeProvider->getSyncedTimestamp();
|
||||
break;
|
||||
case PlaybackState::Playing:
|
||||
innerFrame.state.status = PlayStatus_kPlayStatusPlay;
|
||||
innerFrame.state.position_measured_at = timeProvider->getSyncedTimestamp();
|
||||
break;
|
||||
case PlaybackState::Stopped:
|
||||
break;
|
||||
case PlaybackState::Paused:
|
||||
// Update state and recalculate current song position
|
||||
innerFrame.state.status = PlayStatus_kPlayStatusPause;
|
||||
uint32_t diff = timeProvider->getSyncedTimestamp() - innerFrame.state.position_measured_at;
|
||||
this->updatePositionMs(innerFrame.state.position_ms + diff);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -139,9 +136,8 @@ void PlayerState::updatePositionMs(uint32_t position)
|
||||
void PlayerState::updateTracks()
|
||||
{
|
||||
CSPOT_LOG(info, "---- Track count %d", remoteFrame.state.track_count);
|
||||
strcpy(innerFrame.state.context_uri, remoteFrame.state.context_uri);
|
||||
|
||||
std::copy(std::begin(remoteFrame.state.track), std::end(remoteFrame.state.track), std::begin(innerFrame.state.track));
|
||||
std::swap(innerFrame.state.context_uri, remoteFrame.state.context_uri);
|
||||
std::swap(innerFrame.state.track, remoteFrame.state.track);
|
||||
innerFrame.state.track_count = remoteFrame.state.track_count;
|
||||
innerFrame.state.has_playing_track_index = true;
|
||||
innerFrame.state.playing_track_index = remoteFrame.state.playing_track_index;
|
||||
@@ -170,17 +166,13 @@ void PlayerState::setShuffle(bool shuffle)
|
||||
if (shuffle)
|
||||
{
|
||||
// Put current song at the begining
|
||||
auto tmp = innerFrame.state.track[0];
|
||||
innerFrame.state.track[0] = innerFrame.state.track[innerFrame.state.playing_track_index];
|
||||
innerFrame.state.track[innerFrame.state.playing_track_index] = tmp;
|
||||
std::swap(innerFrame.state.track[0], innerFrame.state.track[innerFrame.state.playing_track_index]);
|
||||
|
||||
// Shuffle current tracks
|
||||
for (int x = 1; x < innerFrame.state.track_count - 1; x++)
|
||||
{
|
||||
auto j = x + (std::rand() % (innerFrame.state.track_count - x));
|
||||
tmp = innerFrame.state.track[j];
|
||||
innerFrame.state.track[j] = innerFrame.state.track[x];
|
||||
innerFrame.state.track[x] = tmp;
|
||||
std::swap(innerFrame.state.track[j], innerFrame.state.track[x]);
|
||||
}
|
||||
innerFrame.state.playing_track_index = 0;
|
||||
}
|
||||
@@ -199,16 +191,14 @@ std::shared_ptr<TrackReference> PlayerState::getCurrentTrack()
|
||||
|
||||
std::vector<uint8_t> PlayerState::encodeCurrentFrame(MessageType typ)
|
||||
{
|
||||
free(innerFrame.ident);
|
||||
free(innerFrame.protocol_version);
|
||||
|
||||
// Prepare current frame info
|
||||
innerFrame.version = 1;
|
||||
|
||||
pbPutCharArray(deviceId, innerFrame.ident);
|
||||
innerFrame.has_ident = true;
|
||||
|
||||
innerFrame.ident = strdup(deviceId);
|
||||
innerFrame.seq_nr = this->seqNum;
|
||||
pbPutCharArray(protocolVersion, innerFrame.protocol_version);
|
||||
innerFrame.has_protocol_version = true;
|
||||
|
||||
innerFrame.protocol_version = strdup(protocolVersion);
|
||||
innerFrame.typ = typ;
|
||||
innerFrame.state_update_id = timeProvider->getSyncedTimestamp();
|
||||
innerFrame.has_version = true;
|
||||
@@ -241,10 +231,9 @@ void PlayerState::addCapability(CapabilityType typ, int intValue, std::vector<st
|
||||
|
||||
for (int x = 0; x < stringValue.size(); x++)
|
||||
{
|
||||
stringValue[x].copy(this->innerFrame.device_state.capabilities[capabilityIndex].stringValue[x], stringValue[x].size());
|
||||
this->innerFrame.device_state.capabilities[capabilityIndex].stringValue[x][stringValue[x].size()] = '\0';
|
||||
pbPutString(stringValue[x], this->innerFrame.device_state.capabilities[capabilityIndex].stringValue[x]);
|
||||
}
|
||||
|
||||
this->innerFrame.device_state.capabilities[capabilityIndex].stringValue_count = stringValue.size();
|
||||
this->capabilityIndex += 1;
|
||||
}
|
||||
}
|
||||
@@ -56,7 +56,7 @@ void SpircController::disconnect(void) {
|
||||
state->setActive(false);
|
||||
notify();
|
||||
// Send the event at the end at it might be a last gasp
|
||||
sendEvent(CSpotEventType::DISC);
|
||||
sendEvent(CSpotEventType::DISC);
|
||||
}
|
||||
|
||||
void SpircController::playToggle() {
|
||||
@@ -103,6 +103,7 @@ void SpircController::prevSong() {
|
||||
}
|
||||
|
||||
void SpircController::handleFrame(std::vector<uint8_t> &data) {
|
||||
pb_release(Frame_fields, &state->remoteFrame);
|
||||
pbDecode(state->remoteFrame, Frame_fields, data);
|
||||
|
||||
switch (state->remoteFrame.typ) {
|
||||
|
||||
@@ -53,18 +53,18 @@ bool SpotifyTrack::countryListContains(std::string countryList, std::string coun
|
||||
|
||||
bool SpotifyTrack::canPlayTrack()
|
||||
{
|
||||
// for (int x = 0; x < trackInfo.restriction_count; x++)
|
||||
// {
|
||||
// if (strlen(trackInfo.restriction[x].countries_allowed) > 0)
|
||||
// {
|
||||
// return countryListContains(std::string(trackInfo.restriction[x].countries_allowed), manager->countryCode);
|
||||
// }
|
||||
//
|
||||
// if (strlen(trackInfo.restriction[x].countries_forbidden) > 0)
|
||||
// {
|
||||
// return !countryListContains(std::string(trackInfo.restriction[x].countries_forbidden), manager->countryCode);
|
||||
// }
|
||||
// }
|
||||
for (int x = 0; x < trackInfo.restriction_count; x++)
|
||||
{
|
||||
if (trackInfo.restriction[x].countries_allowed != nullptr)
|
||||
{
|
||||
return countryListContains(std::string(trackInfo.restriction[x].countries_allowed), manager->countryCode);
|
||||
}
|
||||
|
||||
if (trackInfo.restriction[x].countries_forbidden != nullptr)
|
||||
{
|
||||
return !countryListContains(std::string(trackInfo.restriction[x].countries_forbidden), manager->countryCode);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -77,39 +77,37 @@ void SpotifyTrack::trackInformationCallback(std::unique_ptr<MercuryResponse> res
|
||||
|
||||
pb_release(Track_fields, &trackInfo);
|
||||
pbDecode(trackInfo, Track_fields, response->parts[0]);
|
||||
//
|
||||
// CSPOT_LOG(info, "Track name: %s", trackInfo.name);
|
||||
// CSPOT_LOG(info, "Track duration: %d", trackInfo.duration);
|
||||
// CSPOT_LOG(debug, "trackInfo.restriction.size() = %d", trackInfo.restriction_count);
|
||||
// int altIndex = 0;
|
||||
// while (!canPlayTrack())
|
||||
// {
|
||||
// auto src = trackInfo.alternative[altIndex].restriction;
|
||||
//// std::copy(std::begin(src), std::end(src), std::begin(trackInfo.restriction));
|
||||
//// trackInfo.restriction_count = trackInfo.alternative[altIndex].restriction_count;
|
||||
////
|
||||
//// free(trackInfo.gid);
|
||||
// trackInfo.gid = trackInfo.alternative[altIndex].gid;
|
||||
// altIndex++;
|
||||
// CSPOT_LOG(info, "Trying alternative %d", altIndex);
|
||||
// }
|
||||
|
||||
auto trackId = std::vector(trackInfo.gid.bytes, trackInfo.gid.bytes + trackInfo.gid.size);
|
||||
CSPOT_LOG(info, "Track name: %s", trackInfo.name);
|
||||
CSPOT_LOG(info, "Track duration: %d", trackInfo.duration);
|
||||
CSPOT_LOG(debug, "trackInfo.restriction.size() = %d", trackInfo.restriction_count);
|
||||
int altIndex = 0;
|
||||
while (!canPlayTrack())
|
||||
{
|
||||
std::swap(trackInfo.restriction, trackInfo.alternative[altIndex].restriction);
|
||||
std::swap(trackInfo.restriction_count, trackInfo.alternative[altIndex].restriction_count);
|
||||
std::swap(trackInfo.file, trackInfo.alternative[altIndex].file);
|
||||
std::swap(trackInfo.file_count, trackInfo.alternative[altIndex].file_count);
|
||||
std::swap(trackInfo.gid, trackInfo.alternative[altIndex].gid);
|
||||
|
||||
CSPOT_LOG(info, "Trying alternative %d", altIndex);
|
||||
}
|
||||
|
||||
auto trackId = pbArrayToVector(trackInfo.gid);
|
||||
this->fileId = std::vector<uint8_t>();
|
||||
|
||||
for (int x = 0; x < trackInfo.file_count; x++)
|
||||
{
|
||||
if (trackInfo.file[x].format == configMan->format)
|
||||
{
|
||||
this->fileId = std::vector(trackInfo.file[x].file_id.bytes, trackInfo.file[x].file_id.bytes + trackInfo.file[x].file_id.size);
|
||||
this->fileId = pbArrayToVector(trackInfo.file[x].file_id);
|
||||
break; // If file found stop searching
|
||||
}
|
||||
}
|
||||
|
||||
if (trackInfoReceived != nullptr)
|
||||
{
|
||||
auto imageIdBytes = trackInfo.album.cover_group.image[0].file_id;
|
||||
auto imageId = std::vector(imageIdBytes.bytes, imageIdBytes.bytes + imageIdBytes.size);
|
||||
auto imageId = pbArrayToVector(trackInfo.album.cover_group.image[0].file_id);
|
||||
TrackInfo simpleTrackInfo = {
|
||||
.name = std::string(trackInfo.name),
|
||||
.album = std::string(trackInfo.album.name),
|
||||
@@ -143,15 +141,14 @@ void SpotifyTrack::episodeInformationCallback(std::unique_ptr<MercuryResponse> r
|
||||
{
|
||||
if (episodeInfo.audio[x].format == AudioFormat_OGG_VORBIS_96)
|
||||
{
|
||||
this->fileId = std::vector(episodeInfo.audio[x].file_id.bytes, episodeInfo.audio[x].file_id.bytes + episodeInfo.audio[x].file_id.size);
|
||||
this->fileId = pbArrayToVector(episodeInfo.audio[x].file_id);
|
||||
break; // If file found stop searching
|
||||
}
|
||||
}
|
||||
|
||||
if (trackInfoReceived != nullptr)
|
||||
{
|
||||
auto imageFileId = episodeInfo.covers.image[0].file_id;
|
||||
auto imageId = std::vector(imageFileId.bytes, imageFileId.bytes + imageFileId.size);
|
||||
auto imageId = pbArrayToVector(episodeInfo.covers->image[0].file_id);
|
||||
TrackInfo simpleTrackInfo = {
|
||||
.name = std::string(episodeInfo.name),
|
||||
.album = "",
|
||||
@@ -164,7 +161,7 @@ void SpotifyTrack::episodeInformationCallback(std::unique_ptr<MercuryResponse> r
|
||||
trackInfoReceived(simpleTrackInfo);
|
||||
}
|
||||
|
||||
this->requestAudioKey(std::vector(episodeInfo.gid.bytes, episodeInfo.gid.bytes + episodeInfo.gid.size), this->fileId, episodeInfo.duration, position_ms, isPaused);
|
||||
this->requestAudioKey(pbArrayToVector(episodeInfo.gid), this->fileId, episodeInfo.duration, position_ms, isPaused);
|
||||
}
|
||||
|
||||
void SpotifyTrack::requestAudioKey(std::vector<uint8_t> fileId, std::vector<uint8_t> trackId, int32_t trackDuration, uint32_t position_ms, bool isPaused)
|
||||
|
||||
@@ -3,11 +3,11 @@
|
||||
|
||||
TrackReference::TrackReference(TrackRef *ref)
|
||||
{
|
||||
if (ref->gid.size > 0)
|
||||
if (ref->gid != nullptr)
|
||||
{
|
||||
gid = std::vector(ref->gid.bytes, ref->gid.bytes + ref->gid.size);
|
||||
gid = pbArrayToVector(ref->gid);
|
||||
}
|
||||
else if (strlen(ref->uri) > 0)
|
||||
else if (ref->uri != nullptr)
|
||||
{
|
||||
auto uri = std::string(ref->uri);
|
||||
auto idString = uri.substr(uri.find_last_of(":") + 1, uri.size());
|
||||
|
||||
Reference in New Issue
Block a user