ESPHome 2026.3.0-dev
Loading...
Searching...
No Matches
media_source.h
Go to the documentation of this file.
1#pragma once
2
5
6#include <cstdint>
7#include <string>
8
10
11enum class MediaSourceState : uint8_t {
12 IDLE, // Not playing, ready to accept play_uri
13 PLAYING, // Currently playing media
14 PAUSED, // Playback paused, can be resumed
15 ERROR, // Error occurred during playback; sources are responsible for logging their own error details
16};
17
19enum class MediaSourceCommand : uint8_t {
20 // All sources should support these basic commands.
21 PLAY,
22 PAUSE,
23 STOP,
24
25 // Only sources with internal playlists will handle these; simple sources should ignore them.
26 NEXT,
32 SHUFFLE,
34};
35
38 public:
39 virtual ~MediaSourceListener() = default;
40
41 // Callbacks that all sources use to send data and state changes to the orchestrator.
43 virtual size_t write_audio(const uint8_t *data, size_t length, uint32_t timeout_ms,
44 const audio::AudioStreamInfo &stream_info) = 0;
47
48 // Callbacks from smart sources requesting the orchestrator to change volume, mute, or start a new URI.
49 // Simple sources never invoke these.
51 virtual void request_volume(float volume) {}
53 virtual void request_mute(bool is_muted) {}
55 virtual void request_play_uri(const std::string &uri) {}
56};
57
62 public:
63 virtual ~MediaSource() = default;
64
65 // === Playback Control ===
66
72 virtual bool play_uri(const std::string &uri) = 0;
73
76 virtual void handle_command(MediaSourceCommand command) = 0;
77
80 virtual bool has_internal_playlist() const { return false; }
81
82 // === State Access ===
83
86 MediaSourceState get_state() const { return this->state_; }
87
88 // === URI Matching ===
89
94 virtual bool can_handle(const std::string &uri) const = 0;
95
96 // === Listener: Source -> Orchestrator ===
97
100 void set_listener(MediaSourceListener *listener) { this->listener_ = listener; }
101
103 bool has_listener() const { return this->listener_ != nullptr; }
104
111 size_t write_output(const uint8_t *data, size_t length, uint32_t timeout_ms,
112 const audio::AudioStreamInfo &stream_info) {
113 if (this->listener_ != nullptr) {
114 return this->listener_->write_audio(data, length, timeout_ms, stream_info);
115 }
116 return 0;
117 }
118
119 // === Callbacks: Orchestrator -> Source ===
120
124 virtual void notify_volume_changed(float volume) {}
125
129 virtual void notify_mute_changed(bool is_muted) {}
130
136 virtual void notify_audio_played(uint32_t frames, int64_t timestamp) {}
137
138 protected:
144 if (this->state_ != state) {
145 this->state_ = state;
146 if (this->listener_ != nullptr) {
147 this->listener_->report_state(state);
148 }
149 }
150 }
151
152 private:
153 // Private to enforce the invariant that listener notifications always fire on state changes.
154 // All state transitions must go through set_state_() which couples the update with notification.
156 MediaSourceListener *listener_{nullptr};
157};
158
159} // namespace esphome::media_source
Abstract base class for media sources MediaSource provides audio data to an orchestrator via the Medi...
virtual void notify_audio_played(uint32_t frames, int64_t timestamp)
Notify the source about audio that has been played Called when the speaker reports that audio frames ...
virtual bool has_internal_playlist() const
Whether this source manages its own playlist internally Smart sources that handle next/previous/repea...
void set_listener(MediaSourceListener *listener)
Set the listener that receives callbacks from this source.
virtual void handle_command(MediaSourceCommand command)=0
Handle playback commands (pause, stop, next, etc.)
void set_state_(MediaSourceState state)
Update state and notify listener (must only be called from the main loop) This is the only way to cha...
virtual void notify_mute_changed(bool is_muted)
Notify the source that mute state changed Simple sources ignore this.
virtual bool can_handle(const std::string &uri) const =0
Check if this source can handle the given URI Each source must override this to match its supported U...
virtual void notify_volume_changed(float volume)
Notify the source that volume changed Simple sources ignore this.
MediaSourceState get_state() const
Get current playback state (must only be called from the main loop)
size_t write_output(const uint8_t *data, size_t length, uint32_t timeout_ms, const audio::AudioStreamInfo &stream_info)
Write audio data to the listener.
virtual bool play_uri(const std::string &uri)=0
Start playing the given URI Sources should validate the URI and state, returning false if the source ...
bool has_listener() const
Check if a listener has been registered.
Callbacks from a MediaSource to its orchestrator.
virtual void request_mute(bool is_muted)
Request the orchestrator to change mute state.
virtual void request_volume(float volume)
Request the orchestrator to change volume.
virtual void request_play_uri(const std::string &uri)
Request the orchestrator to play a new URI.
virtual size_t write_audio(const uint8_t *data, size_t length, uint32_t timeout_ms, const audio::AudioStreamInfo &stream_info)=0
Send audio data to the listener.
virtual void report_state(MediaSourceState state)=0
Notify listener of state changes.
bool state
Definition fan.h:2
MediaSourceCommand
Commands that are sent from the orchestrator to a media source.
uint16_t length
Definition tt21100.cpp:0
uint16_t timestamp
Definition tt21100.cpp:2