mirror of
https://github.com/esphome/esphome.git
synced 2026-06-24 13:27:14 +00:00
[speaker] Add off on capability to media player (#9295)
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> Co-authored-by: Kevin Ahrendt <kevin.ahrendt@openhomefoundation.org>
This commit is contained in:
@@ -15,6 +15,8 @@ from esphome.const import (
|
||||
CONF_FORMAT,
|
||||
CONF_ID,
|
||||
CONF_NUM_CHANNELS,
|
||||
CONF_ON_TURN_OFF,
|
||||
CONF_ON_TURN_ON,
|
||||
CONF_PATH,
|
||||
CONF_RAW_DATA_ID,
|
||||
CONF_SAMPLE_RATE,
|
||||
@@ -401,6 +403,9 @@ FINAL_VALIDATE_SCHEMA = cv.All(
|
||||
|
||||
|
||||
async def to_code(config):
|
||||
if CONF_ON_TURN_OFF in config or CONF_ON_TURN_ON in config:
|
||||
cg.add_define("USE_SPEAKER_MEDIA_PLAYER_ON_OFF", True)
|
||||
|
||||
var = await media_player.new_media_player(config)
|
||||
await cg.register_component(var, config)
|
||||
|
||||
|
||||
@@ -51,7 +51,11 @@ static const UBaseType_t ANNOUNCEMENT_PIPELINE_TASK_PRIORITY = 1;
|
||||
static const char *const TAG = "speaker_media_player";
|
||||
|
||||
void SpeakerMediaPlayer::setup() {
|
||||
#ifdef USE_SPEAKER_MEDIA_PLAYER_ON_OFF
|
||||
state = media_player::MEDIA_PLAYER_STATE_OFF;
|
||||
#else
|
||||
state = media_player::MEDIA_PLAYER_STATE_IDLE;
|
||||
#endif
|
||||
|
||||
this->media_control_command_queue_ = xQueueCreate(MEDIA_CONTROLS_QUEUE_LENGTH, sizeof(MediaCallCommand));
|
||||
|
||||
@@ -128,6 +132,12 @@ void SpeakerMediaPlayer::watch_media_commands_() {
|
||||
bool enqueue = media_command.enqueue.has_value() && media_command.enqueue.value();
|
||||
|
||||
if (media_command.url.has_value() || media_command.file.has_value()) {
|
||||
#ifdef USE_SPEAKER_MEDIA_PLAYER_ON_OFF
|
||||
if (this->state == media_player::MEDIA_PLAYER_STATE_OFF) {
|
||||
this->state = media_player::MEDIA_PLAYER_STATE_ON;
|
||||
publish_state();
|
||||
}
|
||||
#endif
|
||||
PlaylistItem playlist_item;
|
||||
if (media_command.url.has_value()) {
|
||||
playlist_item.url = *media_command.url.value();
|
||||
@@ -184,6 +194,12 @@ void SpeakerMediaPlayer::watch_media_commands_() {
|
||||
if (media_command.command.has_value()) {
|
||||
switch (media_command.command.value()) {
|
||||
case media_player::MEDIA_PLAYER_COMMAND_PLAY:
|
||||
#ifdef USE_SPEAKER_MEDIA_PLAYER_ON_OFF
|
||||
if (this->state == media_player::MEDIA_PLAYER_STATE_OFF) {
|
||||
this->state = media_player::MEDIA_PLAYER_STATE_ON;
|
||||
publish_state();
|
||||
}
|
||||
#endif
|
||||
if ((this->media_pipeline_ != nullptr) && (this->is_paused_)) {
|
||||
this->media_pipeline_->set_pause_state(false);
|
||||
}
|
||||
@@ -195,10 +211,26 @@ void SpeakerMediaPlayer::watch_media_commands_() {
|
||||
}
|
||||
this->is_paused_ = true;
|
||||
break;
|
||||
#ifdef USE_SPEAKER_MEDIA_PLAYER_ON_OFF
|
||||
case media_player::MEDIA_PLAYER_COMMAND_TURN_ON:
|
||||
if (this->state == media_player::MEDIA_PLAYER_STATE_OFF) {
|
||||
this->state = media_player::MEDIA_PLAYER_STATE_ON;
|
||||
this->publish_state();
|
||||
}
|
||||
break;
|
||||
case media_player::MEDIA_PLAYER_COMMAND_TURN_OFF:
|
||||
this->is_turn_off_ = true;
|
||||
// Intentional Fall-through
|
||||
#endif
|
||||
case media_player::MEDIA_PLAYER_COMMAND_STOP:
|
||||
// Pipelines do not stop immediately after calling the stop command, so confirm its stopped before unpausing.
|
||||
// This avoids an audible short segment playing after receiving the stop command in a paused state.
|
||||
#ifdef USE_SPEAKER_MEDIA_PLAYER_ON_OFF
|
||||
if (this->single_pipeline_() || (media_command.announce.has_value() && media_command.announce.value()) ||
|
||||
(this->is_turn_off_ && this->announcement_pipeline_state_ != AudioPipelineState::STOPPED)) {
|
||||
#else
|
||||
if (this->single_pipeline_() || (media_command.announce.has_value() && media_command.announce.value())) {
|
||||
#endif
|
||||
if (this->announcement_pipeline_ != nullptr) {
|
||||
this->cancel_timeout("next_ann");
|
||||
this->announcement_playlist_.clear();
|
||||
@@ -366,7 +398,13 @@ void SpeakerMediaPlayer::loop() {
|
||||
}
|
||||
} else {
|
||||
if (this->is_paused_) {
|
||||
#ifdef USE_SPEAKER_MEDIA_PLAYER_ON_OFF
|
||||
if (this->state != media_player::MEDIA_PLAYER_STATE_OFF) {
|
||||
this->state = media_player::MEDIA_PLAYER_STATE_PAUSED;
|
||||
}
|
||||
#else
|
||||
this->state = media_player::MEDIA_PLAYER_STATE_PAUSED;
|
||||
#endif
|
||||
} else if (this->media_pipeline_state_ == AudioPipelineState::PLAYING) {
|
||||
this->state = media_player::MEDIA_PLAYER_STATE_PLAYING;
|
||||
} else if (this->media_pipeline_state_ == AudioPipelineState::STOPPED) {
|
||||
@@ -399,7 +437,13 @@ void SpeakerMediaPlayer::loop() {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
#ifdef USE_SPEAKER_MEDIA_PLAYER_ON_OFF
|
||||
if (this->state != media_player::MEDIA_PLAYER_STATE_OFF) {
|
||||
this->state = media_player::MEDIA_PLAYER_STATE_IDLE;
|
||||
}
|
||||
#else
|
||||
this->state = media_player::MEDIA_PLAYER_STATE_IDLE;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -409,6 +453,20 @@ void SpeakerMediaPlayer::loop() {
|
||||
this->publish_state();
|
||||
ESP_LOGD(TAG, "State changed to %s", media_player::media_player_state_to_string(this->state));
|
||||
}
|
||||
#ifdef USE_SPEAKER_MEDIA_PLAYER_ON_OFF
|
||||
if (this->is_turn_off_ && (this->state == media_player::MEDIA_PLAYER_STATE_PAUSED ||
|
||||
this->state == media_player::MEDIA_PLAYER_STATE_IDLE)) {
|
||||
this->is_turn_off_ = false;
|
||||
if (this->state == media_player::MEDIA_PLAYER_STATE_PAUSED) {
|
||||
this->state = media_player::MEDIA_PLAYER_STATE_IDLE;
|
||||
this->publish_state();
|
||||
ESP_LOGD(TAG, "State changed to %s", media_player::media_player_state_to_string(this->state));
|
||||
}
|
||||
this->state = media_player::MEDIA_PLAYER_STATE_OFF;
|
||||
this->publish_state();
|
||||
ESP_LOGD(TAG, "State changed to %s", media_player::media_player_state_to_string(this->state));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void SpeakerMediaPlayer::play_file(audio::AudioFile *media_file, bool announcement, bool enqueue) {
|
||||
@@ -481,6 +539,9 @@ media_player::MediaPlayerTraits SpeakerMediaPlayer::get_traits() {
|
||||
if (!this->single_pipeline_()) {
|
||||
traits.set_supports_pause(true);
|
||||
}
|
||||
#ifdef USE_SPEAKER_MEDIA_PLAYER_ON_OFF
|
||||
traits.set_supports_turn_off_on(true);
|
||||
#endif
|
||||
|
||||
if (this->announcement_format_.has_value()) {
|
||||
traits.get_supported_formats().push_back(this->announcement_format_.value());
|
||||
|
||||
@@ -144,6 +144,9 @@ class SpeakerMediaPlayer : public Component,
|
||||
|
||||
bool is_paused_{false};
|
||||
bool is_muted_{false};
|
||||
#ifdef USE_SPEAKER_MEDIA_PLAYER_ON_OFF
|
||||
bool is_turn_off_{false};
|
||||
#endif
|
||||
uint8_t unpause_media_remaining_{0};
|
||||
uint8_t unpause_announcement_remaining_{0};
|
||||
|
||||
|
||||
@@ -233,6 +233,7 @@
|
||||
#define USE_LWIP_FAST_SELECT
|
||||
#define USE_WAKE_LOOP_THREADSAFE
|
||||
#define USE_SPEAKER
|
||||
#define USE_SPEAKER_MEDIA_PLAYER_ON_OFF
|
||||
#define USE_SPI
|
||||
#define USE_VOICE_ASSISTANT
|
||||
#define USE_WEBSERVER
|
||||
|
||||
18
tests/components/speaker/common-media_player_off_on.yaml
Normal file
18
tests/components/speaker/common-media_player_off_on.yaml
Normal file
@@ -0,0 +1,18 @@
|
||||
<<: !include common.yaml
|
||||
|
||||
media_player:
|
||||
- platform: speaker
|
||||
id: speaker_media_player_id
|
||||
announcement_pipeline:
|
||||
speaker: speaker_id
|
||||
buffer_size: 1000000
|
||||
volume_increment: 0.02
|
||||
volume_max: 0.95
|
||||
volume_min: 0.0
|
||||
task_stack_in_psram: true
|
||||
on_turn_on:
|
||||
then:
|
||||
- logger.log: "Turn On Media Player"
|
||||
on_turn_off:
|
||||
then:
|
||||
- logger.log: "Turn Off Media Player"
|
||||
@@ -0,0 +1,9 @@
|
||||
substitutions:
|
||||
scl_pin: GPIO16
|
||||
sda_pin: GPIO17
|
||||
i2s_bclk_pin: GPIO27
|
||||
i2s_lrclk_pin: GPIO26
|
||||
i2s_mclk_pin: GPIO25
|
||||
i2s_dout_pin: GPIO23
|
||||
|
||||
<<: !include common-media_player_off_on.yaml
|
||||
Reference in New Issue
Block a user