Using the Google CAF Receiver SDK, how do we prevent the receiver from timing out and automatically killing the cast session when we're not using the receiver player?
The standard Google Cast use case is to send media from a device to the cast receiver and have the receiver render the media using a player. The CAF receiver SDK provides this functionality in a beautiful, simple way using the element cast-media-player
.
But for those instances when we want to cast from a device and render content where it's not relevant to use the cast-media-player
(e.g. an HTML dashboard), how do we keep the receiver alive?
The following custom receiver for example (HAML for brevity), results in the cast session automatically terminating after 5 minutes...
!!! 5
%html
%head
:css
cast-media-player {
display: none;
}
= javascript_include_tag 'https://www.gstatic.com/cast/sdk/libs/caf_receiver/v3/cast_receiver_framework.js'
%body
%cast-media-player
:javascript
const context = cast.framework.CastReceiverContext.getInstance();
const player = context.getPlayerManager();
player.setMessageInterceptor(cast.framework.messages.MessageType.LOAD, loadRequestData => {
...[load custom view]...
return false;
});
context.start();
The receiver log shows the line cast.framework.common.IdleTimeoutManager] timer expired
and then shuts down. Example receiver log shown here.
I've tried:
Any help is very much appreciated!
I ran into the same problem while developing a custom receiver app that does not play media. Here is the solution I implemented:
var idleTime = 0;
const context = cast.framework.CastReceiverContext.getInstance();
const CUSTOM_CHANNEL = '[MY CHANNEL HERE]';
context.addCustomMessageListener(CUSTOM_CHANNEL, function(customEvent) {
var eventData = customEvent.data;
parseCommand(eventData);
idleTime = 0;
});
const options = new cast.framework.CastReceiverOptions();
options.disableIdleTimeout = true;
context.start(options);
var idleInterval = setInterval(timerIncrement, 60000); // 1 minute
function timerIncrement() {
idleTime = idleTime + 1;
if (idleTime > 4) { // 5 minutes
context.stop();
}
}
With CastReveiverOptions I disable idle timeout, which according to the documentation: "If true, the receiver will not set an idle timeout to close receiver if there is no activity. Should only be used for non media apps." https://developers.google.com/cast/docs/reference/caf_receiver/cast.framework.CastReceiverOptions#constructor_1
Since mine is a "non media app," I believe this is correct usage. I then set my own time out based on 5 minutes of inactivity in my custom channel.
I figured out an alternative way to stop this which is more efficient than periodically sending a silent clip, but it feels dirty. Basically we have to stop Chromecast's setTimeout
from firing and closing the connection due to no media. The quickest solution is to simply re-declare setTimeout
as a dummy no-op function before loading the Chromecast receiver script. It does not seem to break anything Chromecast-related in this scenario because it looks like Chromecast's timeouts are all related to video which aren't relevant to this use case.
window._setTimeout = window.setTimeout;
window.setTimeout = function(a, b) {
// disable setTimeout so chromecast won't kill us after 5 minutes...
};
Then in our own app if we need to use a timeout we call _setTimeout
instead.
I would be interested if anyone has discovered a better way to achieve this, aside from manually hosting cast_receiver_framework.js
with the offending line commented out (which is inside the Wn(a, b)
function) or sending a silent clip every few minutes. But self-hosting isn't recommended by Google.
A better solution may be to dig deep in the minified code to work out how Xn(a)
is called as that disables the timeout whenever media is playing, and then find a way to call that from within the Chromecast app.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With