mirror of
https://github.com/esphome/esphome.git
synced 2025-07-24 20:26:35 +00:00
[speaker] Bugfix: Fix rapidly adding items to playlist (#8466)
Co-authored-by: Keith Burzinski <kbx81x@gmail.com>
This commit is contained in:
parent
8fcbd57f2f
commit
ea4b573f9a
@ -138,77 +138,48 @@ void SpeakerMediaPlayer::watch_media_commands_() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
MediaCallCommand media_command;
|
MediaCallCommand media_command;
|
||||||
esp_err_t err = ESP_OK;
|
|
||||||
|
|
||||||
if (xQueueReceive(this->media_control_command_queue_, &media_command, 0) == pdTRUE) {
|
if (xQueueReceive(this->media_control_command_queue_, &media_command, 0) == pdTRUE) {
|
||||||
bool new_url = media_command.new_url.has_value() && media_command.new_url.value();
|
bool enqueue = media_command.enqueue.has_value() && media_command.enqueue.value();
|
||||||
bool new_file = media_command.new_file.has_value() && media_command.new_file.value();
|
|
||||||
|
|
||||||
if (new_url || new_file) {
|
if (media_command.url.has_value() || media_command.file.has_value()) {
|
||||||
bool enqueue = media_command.enqueue.has_value() && media_command.enqueue.value();
|
PlaylistItem playlist_item;
|
||||||
|
if (media_command.url.has_value()) {
|
||||||
|
playlist_item.url = *media_command.url.value();
|
||||||
|
delete media_command.url.value();
|
||||||
|
}
|
||||||
|
if (media_command.file.has_value()) {
|
||||||
|
playlist_item.file = media_command.file.value();
|
||||||
|
}
|
||||||
|
|
||||||
if (this->single_pipeline_() || (media_command.announce.has_value() && media_command.announce.value())) {
|
if (this->single_pipeline_() || (media_command.announce.has_value() && media_command.announce.value())) {
|
||||||
// Announcement playlist/pipeline
|
|
||||||
|
|
||||||
if (!enqueue) {
|
if (!enqueue) {
|
||||||
// Clear the queue and ensure the loaded next item doesn't start playing
|
// Ensure the loaded next item doesn't start playing, clear the queue, start the file, and unpause
|
||||||
this->cancel_timeout("next_ann");
|
this->cancel_timeout("next_ann");
|
||||||
this->announcement_playlist_.clear();
|
this->announcement_playlist_.clear();
|
||||||
}
|
if (media_command.file.has_value()) {
|
||||||
|
|
||||||
PlaylistItem playlist_item;
|
|
||||||
if (new_url) {
|
|
||||||
playlist_item.url = this->announcement_url_;
|
|
||||||
if (!enqueue) {
|
|
||||||
// Not adding to the queue, so directly start playback and internally unpause the pipeline
|
|
||||||
this->announcement_pipeline_->start_url(playlist_item.url.value());
|
|
||||||
this->announcement_pipeline_->set_pause_state(false);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
playlist_item.file = this->announcement_file_;
|
|
||||||
if (!enqueue) {
|
|
||||||
// Not adding to the queue, so directly start playback and internally unpause the pipeline
|
|
||||||
this->announcement_pipeline_->start_file(playlist_item.file.value());
|
this->announcement_pipeline_->start_file(playlist_item.file.value());
|
||||||
this->announcement_pipeline_->set_pause_state(false);
|
} else if (media_command.url.has_value()) {
|
||||||
|
this->announcement_pipeline_->start_url(playlist_item.url.value());
|
||||||
}
|
}
|
||||||
|
this->announcement_pipeline_->set_pause_state(false);
|
||||||
}
|
}
|
||||||
this->announcement_playlist_.push_back(playlist_item);
|
this->announcement_playlist_.push_back(playlist_item);
|
||||||
} else {
|
} else {
|
||||||
// Media playlist/pipeline
|
|
||||||
|
|
||||||
if (!enqueue) {
|
if (!enqueue) {
|
||||||
// Clear the queue and ensure the loaded next item doesn't start playing
|
// Ensure the loaded next item doesn't start playing, clear the queue, start the file, and unpause
|
||||||
this->cancel_timeout("next_media");
|
this->cancel_timeout("next_media");
|
||||||
this->media_playlist_.clear();
|
this->media_playlist_.clear();
|
||||||
}
|
if (media_command.file.has_value()) {
|
||||||
|
|
||||||
this->is_paused_ = false;
|
|
||||||
PlaylistItem playlist_item;
|
|
||||||
if (new_url) {
|
|
||||||
playlist_item.url = this->media_url_;
|
|
||||||
if (!enqueue) {
|
|
||||||
// Not adding to the queue, so directly start playback and internally unpause the pipeline
|
|
||||||
this->media_pipeline_->start_url(playlist_item.url.value());
|
|
||||||
this->media_pipeline_->set_pause_state(false);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
playlist_item.file = this->media_file_;
|
|
||||||
if (!enqueue) {
|
|
||||||
// Not adding to the queue, so directly start playback and internally unpause the pipeline
|
|
||||||
this->media_pipeline_->start_file(playlist_item.file.value());
|
this->media_pipeline_->start_file(playlist_item.file.value());
|
||||||
this->media_pipeline_->set_pause_state(false);
|
} else if (media_command.url.has_value()) {
|
||||||
|
this->media_pipeline_->start_url(playlist_item.url.value());
|
||||||
}
|
}
|
||||||
|
this->media_pipeline_->set_pause_state(false);
|
||||||
}
|
}
|
||||||
this->media_playlist_.push_back(playlist_item);
|
this->media_playlist_.push_back(playlist_item);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (err != ESP_OK) {
|
|
||||||
ESP_LOGE(TAG, "Error starting the audio pipeline: %s", esp_err_to_name(err));
|
|
||||||
this->status_set_error();
|
|
||||||
} else {
|
|
||||||
this->status_clear_error();
|
|
||||||
}
|
|
||||||
|
|
||||||
return; // Don't process the new file play command further
|
return; // Don't process the new file play command further
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -429,12 +400,10 @@ void SpeakerMediaPlayer::play_file(audio::AudioFile *media_file, bool announceme
|
|||||||
|
|
||||||
MediaCallCommand media_command;
|
MediaCallCommand media_command;
|
||||||
|
|
||||||
media_command.new_file = true;
|
media_command.file = media_file;
|
||||||
if (this->single_pipeline_() || announcement) {
|
if (this->single_pipeline_() || announcement) {
|
||||||
this->announcement_file_ = media_file;
|
|
||||||
media_command.announce = true;
|
media_command.announce = true;
|
||||||
} else {
|
} else {
|
||||||
this->media_file_ = media_file;
|
|
||||||
media_command.announce = false;
|
media_command.announce = false;
|
||||||
}
|
}
|
||||||
media_command.enqueue = enqueue;
|
media_command.enqueue = enqueue;
|
||||||
@ -456,14 +425,8 @@ void SpeakerMediaPlayer::control(const media_player::MediaPlayerCall &call) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (call.get_media_url().has_value()) {
|
if (call.get_media_url().has_value()) {
|
||||||
std::string new_uri = call.get_media_url().value();
|
media_command.url = new std::string(
|
||||||
|
call.get_media_url().value()); // Must be manually deleted after receiving media_command from a queue
|
||||||
media_command.new_url = true;
|
|
||||||
if (this->single_pipeline_() || (call.get_announcement().has_value() && call.get_announcement().value())) {
|
|
||||||
this->announcement_url_ = new_uri;
|
|
||||||
} else {
|
|
||||||
this->media_url_ = new_uri;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (call.get_command().has_value()) {
|
if (call.get_command().has_value()) {
|
||||||
if (call.get_command().value() == media_player::MEDIA_PLAYER_COMMAND_ENQUEUE) {
|
if (call.get_command().value() == media_player::MEDIA_PLAYER_COMMAND_ENQUEUE) {
|
||||||
|
@ -24,8 +24,8 @@ struct MediaCallCommand {
|
|||||||
optional<media_player::MediaPlayerCommand> command;
|
optional<media_player::MediaPlayerCommand> command;
|
||||||
optional<float> volume;
|
optional<float> volume;
|
||||||
optional<bool> announce;
|
optional<bool> announce;
|
||||||
optional<bool> new_url;
|
optional<std::string *> url; // Must be manually deleted after receiving this struct from a queue
|
||||||
optional<bool> new_file;
|
optional<audio::AudioFile *> file;
|
||||||
optional<bool> enqueue;
|
optional<bool> enqueue;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -109,15 +109,11 @@ class SpeakerMediaPlayer : public Component, public media_player::MediaPlayer {
|
|||||||
|
|
||||||
optional<media_player::MediaPlayerSupportedFormat> media_format_;
|
optional<media_player::MediaPlayerSupportedFormat> media_format_;
|
||||||
AudioPipelineState media_pipeline_state_{AudioPipelineState::STOPPED};
|
AudioPipelineState media_pipeline_state_{AudioPipelineState::STOPPED};
|
||||||
std::string media_url_{}; // only modified by control function
|
|
||||||
audio::AudioFile *media_file_{}; // only modified by play_file function
|
|
||||||
bool media_repeat_one_{false};
|
bool media_repeat_one_{false};
|
||||||
uint32_t media_playlist_delay_ms_{0};
|
uint32_t media_playlist_delay_ms_{0};
|
||||||
|
|
||||||
optional<media_player::MediaPlayerSupportedFormat> announcement_format_;
|
optional<media_player::MediaPlayerSupportedFormat> announcement_format_;
|
||||||
AudioPipelineState announcement_pipeline_state_{AudioPipelineState::STOPPED};
|
AudioPipelineState announcement_pipeline_state_{AudioPipelineState::STOPPED};
|
||||||
std::string announcement_url_{}; // only modified by control function
|
|
||||||
audio::AudioFile *announcement_file_{}; // only modified by play_file function
|
|
||||||
bool announcement_repeat_one_{false};
|
bool announcement_repeat_one_{false};
|
||||||
uint32_t announcement_playlist_delay_ms_{0};
|
uint32_t announcement_playlist_delay_ms_{0};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user