Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[chromecast] Fix thing go offline after stop command #14158

Merged
merged 3 commits into from
Jan 7, 2023
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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);
lsiepel marked this conversation as resolved.
Show resolved Hide resolved
} catch (final IOException e) {
logger.debug("Failed playing media: {}", e.getMessage());
statusUpdater.updateStatus(ThingStatus.OFFLINE, COMMUNICATION_ERROR, e.getMessage());
logger.info("Failed starting app: {}. Message: {}", appId, e.getMessage());
lsiepel marked this conversation as resolved.
Show resolved Hide resolved
}
}

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());
lsiepel marked this conversation as resolved.
Show resolved Hide resolved

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