48static const uint32_t MEDIA_CONTROLS_QUEUE_LENGTH = 20;
50static const UBaseType_t MEDIA_PIPELINE_TASK_PRIORITY = 1;
51static const UBaseType_t ANNOUNCEMENT_PIPELINE_TASK_PRIORITY = 1;
53static const char *
const TAG =
"speaker_media_player";
56#ifdef USE_SPEAKER_MEDIA_PLAYER_ON_OFF
66 VolumeRestoreState volume_restore_state;
67 if (this->
pref_.
load(&volume_restore_state)) {
75#ifdef USE_OTA_STATE_LISTENER
81 ANNOUNCEMENT_PIPELINE_TASK_PRIORITY);
84 ESP_LOGE(TAG,
"Failed to create announcement pipeline");
93 ESP_LOGE(TAG,
"Failed to create media pipeline");
98 ESP_LOGI(TAG,
"Set up speaker media player");
102 switch (pipeline_type) {
131 MediaCallCommand media_command;
134 bool enqueue = media_command.enqueue.has_value() && media_command.enqueue.value();
136 if (media_command.url.has_value() || media_command.file.has_value()) {
137#ifdef USE_SPEAKER_MEDIA_PLAYER_ON_OFF
143 PlaylistItem playlist_item;
144 if (media_command.url.has_value()) {
145 playlist_item.url = *media_command.url.value();
146 delete media_command.url.value();
148 if (media_command.file.has_value()) {
149 playlist_item.file = media_command.file;
152 if (this->
single_pipeline_() || (media_command.announce.has_value() && media_command.announce.value())) {
158 if (media_command.file.has_value()) {
160 }
else if (media_command.url.has_value()) {
178 if (media_command.file.has_value()) {
180 }
else if (media_command.url.has_value()) {
193 if (media_command.volume.has_value()) {
198 if (media_command.command.has_value()) {
199 switch (media_command.command.value()) {
201#ifdef USE_SPEAKER_MEDIA_PLAYER_ON_OFF
218#ifdef USE_SPEAKER_MEDIA_PLAYER_ON_OFF
232#ifdef USE_SPEAKER_MEDIA_PLAYER_ON_OFF
233 if (this->
single_pipeline_() || (media_command.announce.has_value() && media_command.announce.value()) ||
236 if (this->
single_pipeline_() || (media_command.announce.has_value() && media_command.announce.value())) {
293 if (this->
single_pipeline_() || (media_command.announce.has_value() && media_command.announce.value())) {
300 if (this->
single_pipeline_() || (media_command.announce.has_value() && media_command.announce.value())) {
307 if (this->
single_pipeline_() || (media_command.announce.has_value() && media_command.announce.value())) {
324#ifdef USE_OTA_STATE_LISTENER
326 ota::OTAComponent *comp) {
357 ESP_LOGE(TAG,
"The media pipeline's file reader encountered an error.");
360 ESP_LOGE(TAG,
"The media pipeline's audio decoder encountered an error.");
370 ESP_LOGE(TAG,
"The announcement pipeline's file reader encountered an error.");
373 ESP_LOGE(TAG,
"The announcement pipeline's audio decoder encountered an error.");
400 if (playlist_item.url.has_value()) {
402 }
else if (playlist_item.file.has_value()) {
406 if (timeout_ms > 0) {
418#ifdef USE_SPEAKER_MEDIA_PLAYER_ON_OFF
446 if (playlist_item.url.has_value()) {
448 }
else if (playlist_item.file.has_value()) {
452 if (timeout_ms > 0) {
464#ifdef USE_SPEAKER_MEDIA_PLAYER_ON_OFF
476 if (this->state != old_state) {
480#ifdef USE_SPEAKER_MEDIA_PLAYER_ON_OFF
502 MediaCallCommand media_command;
504 media_command.file = media_file;
506 media_command.announce =
true;
508 media_command.announce =
false;
510 media_command.enqueue = enqueue;
520 MediaCallCommand media_command;
522 auto ann =
call.get_announcement();
524 media_command.announce =
true;
526 media_command.announce =
false;
529 const auto &media_url =
call.get_media_url();
530 if (media_url.has_value()) {
532 new std::string(*media_url);
534 auto cmd =
call.get_command();
535 if (cmd.has_value()) {
537 media_command.enqueue =
true;
545 auto vol =
call.get_volume();
546 if (vol.has_value()) {
547 media_command.volume = vol;
553 auto cmd =
call.get_command();
554 if (cmd.has_value()) {
555 media_command.command = cmd;
556 TickType_t ticks_to_wait = portMAX_DELAY;
567 auto traits = media_player::MediaPlayerTraits();
569 traits.set_supports_pause(
true);
571#ifdef USE_SPEAKER_MEDIA_PLAYER_ON_OFF
572 traits.set_supports_turn_off_on(
true);
579 traits.get_supported_formats().push_back(this->
media_format_.value());
584 traits.get_supported_formats().push_back(media_format);
591 VolumeRestoreState volume_restore_state;
592 volume_restore_state.volume = this->
volume;
593 volume_restore_state.is_muted = this->
is_muted_;
610 if (old_mute_state != mute_state) {
622 float bounded_volume = (
volume < SILENT_VOLUME_THRESHOLD)
void mark_failed()
Mark this component as failed.
bool cancel_interval(const char *name)
Cancel an interval function.
bool cancel_timeout(const char *name)
Cancel a timeout function.
void set_timeout(const char *name, uint32_t timeout, std::function< void()> &&f)
Set a timeout function with a const char* name.
void defer(const char *name, std::function< void()> &&f)
Defer a callback to the next loop() call with a const char* name.
void set_interval(const char *name, uint32_t interval, std::function< void()> &&f)
Set an interval function with a const char* name.
ESPPreferenceObject make_entity_preference(uint32_t version=0)
Create a preference object for storing this entity's state/settings.
void trigger(const Ts &...x) ESPHOME_ALWAYS_INLINE
Inform the parent automation that the event has triggered.
void add_global_state_listener(OTAGlobalStateListener *listener)
virtual void set_volume(float volume)
virtual void set_mute_state(bool mute_state)
FLAG_HAS_TRANSITION float
OTAGlobalCallback * get_global_ota_callback()
T remap(U value, U min, U max, T min_out, T max_out)
Remap value from the range (min, max) to (min_out, max_out).