diff --git a/esphome/components/speaker/media_player/audio_pipeline.cpp b/esphome/components/speaker/media_player/audio_pipeline.cpp index 73ec5a3334..b49cf3ddda 100644 --- a/esphome/components/speaker/media_player/audio_pipeline.cpp +++ b/esphome/components/speaker/media_player/audio_pipeline.cpp @@ -182,13 +182,21 @@ AudioPipelineState AudioPipeline::process_state() { if (event_bits & EventGroupBits::PIPELINE_COMMAND_STOP) { // Stop command is fully processed, so clear the command bit xEventGroupClearBits(this->event_group_, EventGroupBits::PIPELINE_COMMAND_STOP); + this->hard_stop_ = true; } if (!this->is_playing_) { // The tasks have been stopped for two ``process_state`` calls in a row, so delete the tasks if ((this->read_task_handle_ != nullptr) || (this->decode_task_handle_ != nullptr)) { this->delete_tasks_(); - this->speaker_->stop(); + if (this->hard_stop_) { + // Stop command was sent, so immediately end of the playback + this->speaker_->stop(); + this->hard_stop_ = false; + } else { + // Decoded all the audio, so let the speaker finish playing before stopping + this->speaker_->finish(); + } } } this->is_playing_ = false; diff --git a/esphome/components/speaker/media_player/audio_pipeline.h b/esphome/components/speaker/media_player/audio_pipeline.h index c382e1eebe..722d9cbb2a 100644 --- a/esphome/components/speaker/media_player/audio_pipeline.h +++ b/esphome/components/speaker/media_player/audio_pipeline.h @@ -112,6 +112,7 @@ class AudioPipeline { uint32_t playback_ms_{0}; + bool hard_stop_{false}; bool is_playing_{false}; bool pause_state_{false}; bool task_stack_in_psram_;