1

I am writing a Cast application for a shop that needs to perform two tasks:

  • Show some ads (static images) in the background (possibly with a smooth image transition);
  • Show the "We are serving" number in a corner.

I have already developed the application (both a custom receiver and an Android sender). The ads are provided by the server and therefore embedded in the receiver application, while the sender application is used to control the "We are serving" number.

Everything works like a charm, but after some minutes the sender disconnects and the receiver exits, leaving the screen with the Google Chromecast backdrop images.

While I can accept the sender disconnection (even if I would like to avoid it), the receiver app exiting is not acceptable.

I tried sending keep-alive messages through the CastSession.sendMessage(), but it didn't work.

I thought about playing some content in a hidden cast-media-player to trick it in thinking that I am playing something, but I think this is quite a dirty solution.

Is it possible to achieve what I am trying to do in a better way?

Andrea Carron
  • 1,001
  • 13
  • 22

3 Answers3

2

An easier solution is to set disableIdleTimeout: true in the CastReceiverOptions passed to CastReceiverContext.start(). This will keep your receiver running.

Sample (code with inline construction of CastReceiverOptions):

const context = cast.framework.CastReceiverContext.getInstance(); ... context.start({disableIdleTimeout: true});

1

I made further investigation on the issue and I find out that the problem is that the Player in the receiver is in IDLE state for too long and therefore close the application and any connection with the sender.

AFAIK, there is no way to avoid this behavior in a clean way, so I opted for the dirty solution. I put an hidden cast-media-player in the receiver and I send it a non-existent image. It tries to load the image (going in state BUFFERING), but it fails. In this way It reset the IDLE timer and the application doesn't quit anymore.

I hope this will be helpful to someone else in the future.

EDIT: Added longer explanation

In order to make the workaround, I had to add the cast-media-player tag and hide it through the CSS in the receiver application:

<head>
    <style>
        cast-media-player {
            display: none;
        }   
    </style>
</head>
<body>
    <!-- My content -->
    <cast-media-player></cast-media-player>
</body>

After that I added to the Android sender application a loop that each 30 seconds (probably it would work even with a longer timeout) ask the player to display a given image:

private void playFakeContent() {
    final String addr = "http://your.domain.here/404image.png"; 

    CastSession session = mSessionManager.getCurrentCastSession();
    if (null != session) {
        MediaInfo.Builder builder = new MediaInfo.Builder(addr)
                    .setStreamType(MediaInfo.STREAM_TYPE_BUFFERED)
                    .setContentType("image/png")
                    .setMetadata(new MediaMetadata(MediaMetadata.MEDIA_TYPE_PHOTO));
        session.getRemoteMediaClient().load(builder.build(), true);
    }
}

I also put a service on my application in foreground to ensure that Android won't kill my application on the phone.

There should probably be some room for improvements, for example playing an actual image for a given amount of time to avoid a useless HTTP request and a listener on the Player state to request the image only when it goes in IDLE state, but I didn't have enough time to try it right now. If I ever will, I'll update my answer.

I am not able to share the full application code at this moment, but I have intention to do release it on GitHub in the future. I'll update my answer as soon as the project is ready.

Andrea Carron
  • 1,001
  • 13
  • 22
  • I am also rendering custom content in a custom receiver (hiding/ignoring the receiver player) and looking to keep the connection alive. Could you share some more details of your workaround Andrea? Did you attempt to load the non-existent image once and that was enough to keep everything alive indefinitely? Did you have to periodically attempt to load non-existing images? If periodically, did you send those requests from the sender or handle everything in the receiver? Could you share your code with us? – Elliott Oct 07 '17 at 11:29
  • Unfortunatly I've not managed to replicate your results Andrea. I'm using the iOS Cast SDK but it was very easy to translate the calls you posted. I'm 3 weeks into a task and this is the final roadblock to releasing the hard work. Is there anything you could share that may help me? The receiver code? The receiver console output so I know what mine should look like? I appreciate any and all help you can provide – Elliott Oct 10 '17 at 17:17
  • Raised a question in case you would also like to chime in there Andrea :) https://stackoverflow.com/questions/46673152/google-cast-custom-receiver-timing-out – Elliott Oct 10 '17 at 18:05
0

Have a look at

cast.framework.CastReceiverOptions.maxInactivity

mimo
  • 937
  • 12
  • 19