diff --git a/app/android/app/src/main/java/com/thejeffcooper/hassmic/BackgroundTaskService.java b/app/android/app/src/main/java/com/thejeffcooper/hassmic/BackgroundTaskService.java
index c5fa69a..e32b127 100644
--- a/app/android/app/src/main/java/com/thejeffcooper/hassmic/BackgroundTaskService.java
+++ b/app/android/app/src/main/java/com/thejeffcooper/hassmic/BackgroundTaskService.java
@@ -109,32 +109,61 @@ public void onEvents(Player p, Player.Events events) {
// Loop over each media player event in this tick and fire it back
// to JS
+ //
+ // We don't want to send duplicate messages, so keep track of
+ // the types we might need to deduplicate
+ boolean hasPlaybackStateChangedEvent = false;
+ boolean hasIsPlayingChangedEvent = false;
+ for (int i = 0; i < events.size(); i++) {
+ hasPlaybackStateChangedEvent |=
+ events.get(i) == Player.EVENT_PLAYBACK_STATE_CHANGED;
+ hasIsPlayingChangedEvent |= events.get(i) == Player.EVENT_IS_PLAYING_CHANGED;
+ }
+
for (int i = 0; i < events.size(); i++) {
@Player.Event int e = events.get(i);
ClientEvent.Builder protob = ClientEvent.newBuilder();
+ // some common info
+ @Player.Event int playbackState = p.getPlaybackState();
+ boolean isPlaying = p.isPlaying();
+
+ // Don't send duplicate messages:
+ // - If we have both IS_PLAYING_CHANGED and
+ // PLAYBACK_STATE_CHANGED events, ignore one or the
+ // other.
+ if (hasIsPlayingChangedEvent && hasPlaybackStateChangedEvent) {
+ if ((isPlaying && e == Player.EVENT_PLAYBACK_STATE_CHANGED)
+ || (!isPlaying && e == Player.EVENT_IS_PLAYING_CHANGED)) {
+ continue;
+ }
+ }
+
switch (e) {
case Player.EVENT_PLAYBACK_STATE_CHANGED:
+ case Player.EVENT_IS_PLAYING_CHANGED:
ClientEvent.MediaPlayerStateChange.Builder b =
ClientEvent.MediaPlayerStateChange.newBuilder().setPlayer(which_player);
- switch (p.getPlaybackState()) {
- case Player.STATE_IDLE:
- b.setNewState(MediaPlayerState.STATE_IDLE);
- break;
- case Player.STATE_BUFFERING:
- b.setNewState(MediaPlayerState.STATE_BUFFERING);
- break;
- case Player.STATE_READY:
- if (p.isPlaying()) {
- b.setNewState(MediaPlayerState.STATE_PLAYING);
- } else {
- b.setNewState(MediaPlayerState.STATE_PAUSED);
- }
- break;
- case Player.STATE_ENDED:
- b.setNewState(MediaPlayerState.STATE_ENDED);
- break;
+
+ MediaPlayerState newState = null;
+
+ if (playbackState == Player.STATE_READY) {
+ newState =
+ (isPlaying)
+ ? MediaPlayerState.STATE_PLAYING
+ : MediaPlayerState.STATE_PAUSED;
+ } else if (playbackState == Player.STATE_BUFFERING) {
+ newState = MediaPlayerState.STATE_BUFFERING;
+ } else if (playbackState == Player.STATE_IDLE
+ || playbackState == Player.STATE_ENDED) {
+ newState = MediaPlayerState.STATE_IDLE;
+ } else {
+ Log.w(
+ "HassmicBackgroundTaskService",
+ "Unhandled playback state: " + playbackState);
}
+
+ b.setNewState(newState);
protob.setMediaPlayerStateChange(b.build());
break;
}
diff --git a/app/android/app/src/main/java/com/thejeffcooper/hassmic/proto/MediaPlayerState.java b/app/android/app/src/main/java/com/thejeffcooper/hassmic/proto/MediaPlayerState.java
index 8435fcc..7ef4e6d 100644
--- a/app/android/app/src/main/java/com/thejeffcooper/hassmic/proto/MediaPlayerState.java
+++ b/app/android/app/src/main/java/com/thejeffcooper/hassmic/proto/MediaPlayerState.java
@@ -19,14 +19,10 @@ public enum MediaPlayerState implements com.google.protobuf.Internal.EnumLite {
STATE_IDLE(1),
/** STATE_BUFFERING = 2;
*/
STATE_BUFFERING(2),
- /** STATE_READY = 3;
*/
- STATE_READY(3),
- /** STATE_ENDED = 4;
*/
- STATE_ENDED(4),
- /** STATE_PLAYING = 5;
*/
- STATE_PLAYING(5),
- /** STATE_PAUSED = 6;
*/
- STATE_PAUSED(6),
+ /** STATE_PLAYING = 3;
*/
+ STATE_PLAYING(3),
+ /** STATE_PAUSED = 4;
*/
+ STATE_PAUSED(4),
UNRECOGNIZED(-1),
;
@@ -39,17 +35,11 @@ public enum MediaPlayerState implements com.google.protobuf.Internal.EnumLite {
/** STATE_BUFFERING = 2;
*/
public static final int STATE_BUFFERING_VALUE = 2;
- /** STATE_READY = 3;
*/
- public static final int STATE_READY_VALUE = 3;
+ /** STATE_PLAYING = 3;
*/
+ public static final int STATE_PLAYING_VALUE = 3;
- /** STATE_ENDED = 4;
*/
- public static final int STATE_ENDED_VALUE = 4;
-
- /** STATE_PLAYING = 5;
*/
- public static final int STATE_PLAYING_VALUE = 5;
-
- /** STATE_PAUSED = 6;
*/
- public static final int STATE_PAUSED_VALUE = 6;
+ /** STATE_PAUSED = 4;
*/
+ public static final int STATE_PAUSED_VALUE = 4;
@java.lang.Override
public final int getNumber() {
@@ -79,12 +69,8 @@ public static MediaPlayerState forNumber(int value) {
case 2:
return STATE_BUFFERING;
case 3:
- return STATE_READY;
- case 4:
- return STATE_ENDED;
- case 5:
return STATE_PLAYING;
- case 6:
+ case 4:
return STATE_PAUSED;
default:
return null;
diff --git a/app/app/proto/hassmic.ts b/app/app/proto/hassmic.ts
index 9856816..c89659a 100644
--- a/app/app/proto/hassmic.ts
+++ b/app/app/proto/hassmic.ts
@@ -219,21 +219,13 @@ export enum MediaPlayerState {
*/
STATE_BUFFERING = 2,
/**
- * @generated from protobuf enum value: STATE_READY = 3;
+ * @generated from protobuf enum value: STATE_PLAYING = 3;
*/
- STATE_READY = 3,
+ STATE_PLAYING = 3,
/**
- * @generated from protobuf enum value: STATE_ENDED = 4;
+ * @generated from protobuf enum value: STATE_PAUSED = 4;
*/
- STATE_ENDED = 4,
- /**
- * @generated from protobuf enum value: STATE_PLAYING = 5;
- */
- STATE_PLAYING = 5,
- /**
- * @generated from protobuf enum value: STATE_PAUSED = 6;
- */
- STATE_PAUSED = 6
+ STATE_PAUSED = 4
}
/**
* The different media players available
diff --git a/custom_components/hassmic/hassmic.py b/custom_components/hassmic/hassmic.py
index aa00931..0cf28bd 100644
--- a/custom_components/hassmic/hassmic.py
+++ b/custom_components/hassmic/hassmic.py
@@ -145,7 +145,7 @@ def _handle_connection_state_change(self, new_state: bool):
def _handle_client_event(self, event: ClientEvent):
"""Handle a state change from the connection manager."""
- _LOGGER.debug("Got connection change to state: %s", repr(event))
+ _LOGGER.debug("Got client event: %s", repr(event))
for e in self._entities:
hce = getattr(e, "handle_client_event", None)
if hce is not None and callable(hce):
@@ -175,7 +175,6 @@ async def handle_incoming_message(self, reader) -> ClientInfo:
_LOGGER.debug("Got client info: %s", repr(val))
case "client_event":
- _LOGGER.debug("Got client event: %s", repr(val))
self._handle_client_event(val)
case "ping":
diff --git a/custom_components/hassmic/media_player/player.py b/custom_components/hassmic/media_player/player.py
index 2c088a3..b27e788 100644
--- a/custom_components/hassmic/media_player/player.py
+++ b/custom_components/hassmic/media_player/player.py
@@ -92,10 +92,8 @@ def handle_client_event(self, event: proto.ClientEvent):
self._attr_state = MediaPlayerState.PLAYING
case proto.MediaPlayerState.STATE_PAUSED:
self._attr_state = MediaPlayerState.PAUSED
- case proto.MediaPlayerState.STATE_ENDED | proto.MediaPlayerState.STATE_IDLE:
+ case proto.MediaPlayerState.STATE_IDLE:
self._attr_state = MediaPlayerState.IDLE
- case proto.MediaPlayerState.STATE_READY:
- pass
case _:
_LOGGER.warning(
"Got unhandled media player state %s", val.new_state
diff --git a/custom_components/hassmic/proto/hassmic.py b/custom_components/hassmic/proto/hassmic.py
index af0214c..87908e0 100644
--- a/custom_components/hassmic/proto/hassmic.py
+++ b/custom_components/hassmic/proto/hassmic.py
@@ -14,10 +14,8 @@ class MediaPlayerState(betterproto.Enum):
STATE_UNKNOWN = 0
STATE_IDLE = 1
STATE_BUFFERING = 2
- STATE_READY = 3
- STATE_ENDED = 4
- STATE_PLAYING = 5
- STATE_PAUSED = 6
+ STATE_PLAYING = 3
+ STATE_PAUSED = 4
class MediaPlayerId(betterproto.Enum):
diff --git a/proto/hassmic.proto b/proto/hassmic.proto
index 5a29a95..d5417b7 100644
--- a/proto/hassmic.proto
+++ b/proto/hassmic.proto
@@ -26,10 +26,8 @@ enum MediaPlayerState {
STATE_UNKNOWN = 0;
STATE_IDLE = 1;
STATE_BUFFERING = 2;
- STATE_READY = 3;
- STATE_ENDED = 4;
- STATE_PLAYING = 5;
- STATE_PAUSED = 6;
+ STATE_PLAYING = 3;
+ STATE_PAUSED = 4;
}
// The different media players available