Skip to content

Commit

Permalink
[chromecast] Fix thing go offline after stop command (openhab#14158)
Browse files Browse the repository at this point in the history
* Restructure commander
* Improve thing status handling on error

Signed-off-by: lsiepel <leosiepel@gmail.com>
  • Loading branch information
lsiepel authored and nemerdaud committed Feb 28, 2023
1 parent a316d49 commit 62e8419
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 41 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public void process(@Nullable AudioStream audioStream) throws UnsupportedAudioFo
// in case the audioStream is null, this should be interpreted as a request to end any currently playing
// stream.
logger.trace("Stop currently playing stream.");
commander.handleStop(OnOffType.ON);
commander.handleCloseApp(OnOffType.ON);
} else {
final String url;
if (audioStream instanceof URLAudioStream) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ public void handleCommand(final ChannelUID channelUID, final Command command) {
handleControl(command);
break;
case CHANNEL_STOP:
handleStop(command);
handleCloseApp(command);
break;
case CHANNEL_VOLUME:
handleVolume(command);
Expand Down Expand Up @@ -117,7 +117,7 @@ public void handleRefresh() {
if (mediaStatus != null && mediaStatus.playerState == MediaStatus.PlayerState.IDLE
&& mediaStatus.idleReason != null
&& mediaStatus.idleReason != MediaStatus.IdleReason.INTERRUPTED) {
stopMediaPlayerApp();
closeApp(MEDIA_PLAYER);
}
}
} catch (IOException ex) {
Expand All @@ -126,6 +126,12 @@ public void handleRefresh() {
}
}

public void handleCloseApp(final Command command) {
if (command == OnOffType.ON) {
closeApp(MEDIA_PLAYER);
}
}

private void handlePlayUri(Command command) {
if (command instanceof StringType) {
playMedia(null, command.toString(), null);
Expand Down Expand Up @@ -163,7 +169,6 @@ private void handleControl(final Command command) {
if (command instanceof NextPreviousType) {
// Next is implemented by seeking to the end of the current media
if (command == NextPreviousType.NEXT) {

Double duration = statusUpdater.getLastDuration();
if (duration != null) {
chromeCast.seek(duration.doubleValue() - 5);
Expand All @@ -182,18 +187,6 @@ private void handleControl(final Command command) {
}
}

public void handleStop(final Command command) {
if (command == OnOffType.ON) {
try {
chromeCast.stopApp();
statusUpdater.updateStatus(ThingStatus.ONLINE);
} catch (final IOException ex) {
logger.debug("{} command failed: {}", command, ex.getMessage());
statusUpdater.updateStatus(ThingStatus.OFFLINE, COMMUNICATION_ERROR, ex.getMessage());
}
}
}

public void handleVolume(final Command command) {
if (command instanceof PercentType) {
setVolumeInternal((PercentType) command);
Expand Down Expand Up @@ -229,44 +222,69 @@ private void handleMute(final Command command) {
}
}

public void playMedia(@Nullable String title, @Nullable String url, @Nullable String mimeType) {
public void startApp(@Nullable String appId) {
if (appId == null) {
return;
}
try {
if (chromeCast.isAppAvailable(MEDIA_PLAYER)) {
if (!chromeCast.isAppRunning(MEDIA_PLAYER)) {
final Application app = chromeCast.launchApp(MEDIA_PLAYER);
if (chromeCast.isAppAvailable(appId)) {
if (!chromeCast.isAppRunning(appId)) {
final Application app = chromeCast.launchApp(appId);
statusUpdater.setAppSessionId(app.sessionId);
logger.debug("Application launched: {}", app);
}
if (url != null) {
// If the current track is paused, launching a new request results in nothing happening, therefore
// resume current track.
MediaStatus ms = chromeCast.getMediaStatus();
if (ms != null && MediaStatus.PlayerState.PAUSED == ms.playerState && url.equals(ms.media.url)) {
logger.debug("Current stream paused, resuming");
chromeCast.play();
} else {
chromeCast.load(title, null, url, mimeType);
}
logger.debug("Application launched: {}", appId);
}
} else {
logger.warn("Missing media player app - cannot process media.");
logger.warn("Failed starting app, app probably not installed. Appid: {}", appId);
}
statusUpdater.updateStatus(ThingStatus.ONLINE);
} catch (final IOException e) {
logger.debug("Failed playing media: {}", e.getMessage());
statusUpdater.updateStatus(ThingStatus.OFFLINE, COMMUNICATION_ERROR, e.getMessage());
logger.warn("Failed starting app: {}. Message: {}", appId, e.getMessage());
}
}

private void stopMediaPlayerApp() {
public void closeApp(@Nullable String appId) {
if (appId == null) {
return;
}

try {
Application app = chromeCast.getRunningApp();
if (app.id.equals(MEDIA_PLAYER) && app.sessionId.equals(statusUpdater.getAppSessionId())) {
chromeCast.stopApp();
logger.debug("Media player app stopped");
if (chromeCast.isAppRunning(appId)) {
Application app = chromeCast.getRunningApp();
if (app.id.equals(appId) && app.sessionId.equals(statusUpdater.getAppSessionId())) {
chromeCast.stopApp();
logger.debug("Application closed: {}", appId);
}
}
} catch (final IOException e) {
logger.debug("Failed stopping media player app", e);
logger.debug("Failed stopping media player app: {} with message: {}", appId, e.getMessage());
}
}

public void playMedia(@Nullable String title, @Nullable String url, @Nullable String mimeType) {
startApp(MEDIA_PLAYER);
try {
if (url != null && chromeCast.isAppRunning(MEDIA_PLAYER)) {
// If the current track is paused, launching a new request results in nothing happening, therefore
// resume current track.
MediaStatus ms = chromeCast.getMediaStatus();
if (ms != null && MediaStatus.PlayerState.PAUSED == ms.playerState && url.equals(ms.media.url)) {
logger.debug("Current stream paused, resuming");
chromeCast.play();
} else {
chromeCast.load(title, null, url, mimeType);
}
} else {
logger.warn("Missing media player app - cannot process media.");
}
statusUpdater.updateStatus(ThingStatus.ONLINE);
} catch (final IOException e) {
if ("Unable to load media".equals(e.getMessage())) {
logger.warn("Unable to load media: {}", url);
} else {
logger.debug("Failed playing media: {}", e.getMessage());
statusUpdater.updateStatus(ThingStatus.OFFLINE, COMMUNICATION_ERROR,
"IOException while trying to play media: " + e.getMessage());
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ public void connectionEventReceived(final @NonNullByDefault({}) ChromeCastConnec

@Override
public void spontaneousEventReceived(final @NonNullByDefault({}) ChromeCastSpontaneousEvent event) {
logger.trace("Received an {} event (class={})", event.getType(), event.getData());

switch (event.getType()) {
case CLOSE:
statusUpdater.updateMediaStatus(null);
Expand All @@ -66,6 +68,9 @@ public void spontaneousEventReceived(final @NonNullByDefault({}) ChromeCastSpont
case STATUS:
statusUpdater.processStatusUpdate(event.getData(Status.class));
break;
case APPEVENT:
logger.debug("Received an 'APPEVENT' event, ignoring");
break;
case UNKNOWN:
logger.debug("Received an 'UNKNOWN' event (class={})", event.getType().getDataClass());
break;
Expand Down

0 comments on commit 62e8419

Please sign in to comment.