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

Running Apps throw unexpected errors #2

Open
lsiepel opened this issue Jan 4, 2023 · 6 comments
Open

Running Apps throw unexpected errors #2

lsiepel opened this issue Jan 4, 2023 · 6 comments

Comments

@lsiepel
Copy link

lsiepel commented Jan 4, 2023

Working around the issue of not having a list of apps. I'm caching the apps. Just fiddling around, i found that several apps give this error. As far as i can see i cannot control this.

2023-01-04 00:59:45.470 [DEBUG] [omecast.internal.ChromecastCommander] - Failed to request media status for app: Application [appId=Netflix, displayName=Netflix, iconUrl=, isIdleScreen=false, launchedFromCloud=false, namespaces=[], sessionId=801bc1fc-c175-4233-9d72-dd69777a5f18, statusText=Netflix, universalAppId=Netflix] with message : application.getTransportId() cannot be null or blank

java.lang.IllegalArgumentException: application.getTransportId() cannot be null or blank
	at org.digitalmediaserver.cast.Util.requireNotBlank(Util.java:149) ~[?:?]
	at org.digitalmediaserver.cast.Channel.startSession(Channel.java:789) ~[?:?]
	at org.digitalmediaserver.cast.CastDevice.startSession(CastDevice.java:803) ~[?:?]
	at org.openhab.binding.chromecast.internal.ChromecastCommander.handleRefresh(ChromecastCommander.java:121) ~[?:?]
	at org.openhab.binding.chromecast.internal.handler.ChromecastHandler$Coordinator.refresh(ChromecastHandler.java:348) ~[?:?]
	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) ~[?:?]
	at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) ~[?:?]
	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) ~[?:?]
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) [?:?]
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) [?:?]
	at java.lang.Thread.run(Thread.java:833) [?:?]

Calling code:

runningApp = status.getRunningApplication()
Session session = chromeCast.startSession(SENDER_ID, runningApp);
MediaStatus mediaStatus = session.getMediaStatus();

Started the apps from the cast device itself and not from the sender. Could it be related to the sourceId param of startsession? I have that set to a static string SENDER_ID = "myVeryFirstCastController" :-)

Edit:
With Amazone prime i get this:

2023-01-04 01:45:37.888 [WARN ] [org.digitalmediaserver.cast.Channel ] - Error while processing JSON message from Unidentified cast device: Cannot construct instance of `org.digitalmediaserver.cast.MediaStatus`, problem: volume cannot be null
 at [Source: UNKNOWN; byte offset: #UNKNOWN]
2023-01-04 01:45:41.788 [ERROR] [org.digitalmediaserver.cast.Channel ] - Received unhandled "MEDIA_STATUS" message from Unidentified cast device, this should not happen: {"requestId":4403,"responseType":"MEDIA_STATUS","status":[{"mediaSessionId":25,"currentItemId":1,"playerState":"PLAYING","currentTime":298.566,"playbackRate":1,"supportedMediaCommands":13,"repeatMode":"REPEAT_OFF"}]}
2023-01-04 01:45:41.788 [DEBUG] [ast.internal.ChromecastEventReceiver] - Received an 'UNKNOWN' event (class=class com.fasterxml.jackson.databind.JsonNode)
2023-01-04 01:45:43.628 [ERROR] [org.digitalmediaserver.cast.Channel ] - Received unhandled "MEDIA_STATUS" message from Unidentified cast device, this should not happen: {"requestId":4364,"responseType":"MEDIA_STATUS","status":[{"mediaSessionId":25,"currentItemId":1,"playerState":"PLAYING","currentTime":300.417,"playbackRate":1,"supportedMediaCommands":13,"repeatMode":"REPEAT_OFF"}]}
2023-01-04 01:45:43.629 [DEBUG] [ast.internal.ChromecastEventReceiver] - Received an 'UNKNOWN' event (class=class com.fasterxml.jackson.databind.JsonNode)

From that i see two problems.

  1. the volume cannot be null, but it is. Does the lib assume it is not null while it it might be null form the api?
  2. something is wrong handling the "MEDIA_STATUS" message leading to a 'UNKNOWN' event in the registered eventhandler. (lib consumer)
@lsiepel lsiepel changed the title Netflix throwing error App Netflix throwing error Jan 4, 2023
@lsiepel lsiepel changed the title App Netflix throwing error Running Apps throw unexpected errors Jan 4, 2023
@Nadahar
Copy link
Contributor

Nadahar commented Jan 4, 2023

I'm afraid I don't know why you don't get a transportId for the application, but it's obvious that you can't "communicate" with an application whose transportId is unknown. It is virtually the "address" used to communicate, so it's necessary.

Sadly, I don't remember all the details of this now, but I would start with debugging the message that is returned for getReceiverStatus() to make sure that the transportId is really missing in the returned JSON. It would reveal if there's a problem with this library or if the ChromeCast doesn't reveal it.

I know nothing about "Google's logic" as to what information it shares with what "sender". It might be that they simply won't allow you to contact an "app" that you haven't started, but I think that's a bit strange to be honest. That would mean that you couldn't communicate with "your own app" if you had to reconnect for some reason. Maybe it's somehow tied to the sender ID, or maybe there's some other reason. I would first make sure that this isn't just some parsing error by this library though.

While all this ChromeCast stuff is a bit of a "black box" with a lot of guessing involved, and my memory on this isn't exactly fresh, please forgive me if I'm wrong, but I do seem to remember that there are "two generations" of "apps" for the ChromeCast. They had a completely different system initially, which were based on UPnP discovery and a different way of communication. It has been deprecated for years, but I think they still allow the "apps" which were already using it to keep using it. I even think that the YouTube "app" still use the old framework. It could be that Netflix were one of the early implementers, and that they have stayed on that framework. If so, it could be that it isn't possible to communicate with it from "this API" and thus wouldn't have a transportId.

Fun fact: I'm actually running openHAB3 with the ChromeCast binding at my home. Small world 😉

@lsiepel
Copy link
Author

lsiepel commented Jan 4, 2023

Small world ;-)
Updated the post with some more errors. I'll check if i can get the raw json response to determijn if it is the the lib or the api regarding the missing transportid. If that is the cause, it might be usefull to construct something with a 'NotSupportedException' instead of the IllegalArgumentException.

@Nadahar
Copy link
Contributor

Nadahar commented Jan 4, 2023

Generally, there are probably lots and lots of things that should be improved with the lib. I was just frustrated with all the problems with the lib it is based on, and made a pretty extensive "refactoring". But, I've primarily refined the things I've needed myself, which has been about controlling the "default media player". Many things are guesses, I can't even say why volume is defined as not being allowed to be null. It might be from some documentation somewhere, it might be a "best guess".

I'd have to dig in to try to figure out why it is defined that way, but that might not be the most important point. More important might be if it should be allowed to be null or not. There's also the question of to what degree other "apps" respect whatever rules are made by Google's API - even if they define that it cannot be null.

Regarding the exception when the transportId is missing, yeah, maybe - but I'd like some more light on the issue before deciding if it needs a fix, and what that fix might be. It's pretty obvious that you need the transportId to poll the application, not having it is like having a URL without the address part. In that sense, the argument is invalid - it just might not be so logical for the user.

@Nadahar
Copy link
Contributor

Nadahar commented Jan 4, 2023

As I suspected, the non-null requirement for volume is directly from Google's documentation: https://developers.google.com/cast/docs/reference/web_receiver/cast.framework.messages.MediaStatus

That doesn't mean that this lib would have to enforce it, obviously, but the potential consequences of accepting it without would have to be evaluated.

@Nadahar
Copy link
Contributor

Nadahar commented Jan 4, 2023

After taking a quick look in the code, I can't see any obvious problem with allowing volume to be null. The same requirement applies to playerState which probably isn't respected by everybody either.

In general I'm in favor of preferring successful parsing over "sticking to the spec". Allowing them to be null might burden user code with some extra checks, but it would make the parsing much more likely to succeed. When dealing with a "jungle" like this, where you newer know who adheres to which rules, it might be better to accept/parse "invalid" messages rather than to reject them.

@lsiepel
Copy link
Author

lsiepel commented Jan 4, 2023

Thanks for some background details. I hope to improve the Chromecast binding, but it is a though one as not every app sticks to the specs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants