[chromecast] Fix thing go offline after stop command (#14158)
* Restructure commander * Improve thing status handling on error Signed-off-by: lsiepel <leosiepel@gmail.com>
This commit is contained in:
parent
576be1455c
commit
de8d78403e
|
@ -52,7 +52,7 @@ public class ChromecastAudioSink {
|
|||
// 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) {
|
||||
|
|
|
@ -70,7 +70,7 @@ public class ChromecastCommander {
|
|||
handleControl(command);
|
||||
break;
|
||||
case CHANNEL_STOP:
|
||||
handleStop(command);
|
||||
handleCloseApp(command);
|
||||
break;
|
||||
case CHANNEL_VOLUME:
|
||||
handleVolume(command);
|
||||
|
@ -117,7 +117,7 @@ public class ChromecastCommander {
|
|||
if (mediaStatus != null && mediaStatus.playerState == MediaStatus.PlayerState.IDLE
|
||||
&& mediaStatus.idleReason != null
|
||||
&& mediaStatus.idleReason != MediaStatus.IdleReason.INTERRUPTED) {
|
||||
stopMediaPlayerApp();
|
||||
closeApp(MEDIA_PLAYER);
|
||||
}
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
|
@ -126,6 +126,12 @@ public class ChromecastCommander {
|
|||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
@ -163,7 +169,6 @@ public class ChromecastCommander {
|
|||
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);
|
||||
|
@ -182,18 +187,6 @@ public class ChromecastCommander {
|
|||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
@ -229,44 +222,69 @@ public class ChromecastCommander {
|
|||
}
|
||||
}
|
||||
|
||||
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);
|
||||
logger.debug("Application launched: {}", appId);
|
||||
}
|
||||
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);
|
||||
}
|
||||
} else {
|
||||
logger.warn("Failed starting app, app probably not installed. Appid: {}", appId);
|
||||
}
|
||||
statusUpdater.updateStatus(ThingStatus.ONLINE);
|
||||
} catch (final IOException e) {
|
||||
logger.warn("Failed starting app: {}. Message: {}", appId, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void closeApp(@Nullable String appId) {
|
||||
if (appId == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
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: {} 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) {
|
||||
logger.debug("Failed playing media: {}", e.getMessage());
|
||||
statusUpdater.updateStatus(ThingStatus.OFFLINE, COMMUNICATION_ERROR, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private void stopMediaPlayerApp() {
|
||||
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 ("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());
|
||||
}
|
||||
} catch (final IOException e) {
|
||||
logger.debug("Failed stopping media player app", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -56,6 +56,8 @@ public class ChromecastEventReceiver implements ChromeCastSpontaneousEventListen
|
|||
|
||||
@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);
|
||||
|
@ -66,6 +68,9 @@ public class ChromecastEventReceiver implements ChromeCastSpontaneousEventListen
|
|||
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;
|
||||
|
|
Loading…
Reference in New Issue