Тайм-аут пользовательского приемника Google Cast
Используя Google CAF Receiver SDK, как мы можем предотвратить тайм-аут приемника и автоматически убить сеанс приведения, когда мы не используем проигрыватель приемника?
Стандартный вариант использования Google Cast - отправка мультимедиа с устройства на приемник, и приемник воспроизводит мультимедиа с помощью проигрывателя. CAF-приемник SDK обеспечивает эту функциональность красивым и простым способом, используя элемент cast-media-player
,
Но для тех случаев, когда мы хотим преобразовывать данные с устройства и отображать контент, когда использование cast-media-player
(например, панель инструментов HTML), как мы можем поддерживать работу приемника?
Например, следующий пользовательский получатель (HAML для краткости) приводит к автоматическому завершению сеанса приведения через 5 минут...
!!! 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();
Журнал получателя показывает строку cast.framework.common.IdleTimeoutManager] timer expired
а затем выключается. Пример журнала получателя показан здесь.
Я пробовал:
- Увеличение cast.framework.CastReceiverOptions#maxInactivity до очень большого числа
- Периодическая загрузка новых данных от отправителя
- Периодическая отправка пользовательских сообщений от получателя отправителю
- Периодическая отправка пользовательских сообщений от отправителя к получателю
Любая помощь очень ценится!
4 ответа
Я столкнулся с той же проблемой при разработке пользовательского приложения для приемника, которое не воспроизводит мультимедиа. Вот решение, которое я реализовал:
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();
}
}
С CastReveiverOptions я отключаю время ожидания простоя, которое в соответствии с документацией: "Если true, получатель не будет устанавливать время простоя для закрытия получателя, если нет активности. Должно использоваться только для приложений, не относящихся к мультимедиа". https://developers.google.com/cast/docs/reference/caf_receiver/cast.framework.CastReceiverOptions
Так как у меня "не медиа приложение", я считаю, что это правильное использование. Затем я устанавливаю свое собственное время, основываясь на 5 минутах бездействия в моем пользовательском канале.
Я нашел альтернативный способ остановить это, который более эффективен, чем периодическая отправка тихого клипа, но он кажется грязным. В основном мы должны остановить Chromecast setTimeout
от запуска и закрытия соединения из-за отсутствия носителя. Самое быстрое решение - просто повторно объявить setTimeout
как фиктивная неактивная функция перед загрузкой сценария приемника Chromecast. Похоже, что он не нарушает ничего, связанного с Chromecast, в этом сценарии, потому что похоже, что таймауты Chromecast все связаны с видео, которые не имеют отношения к этому варианту использования.
window._setTimeout = window.setTimeout;
window.setTimeout = function(a, b) {
// disable setTimeout so chromecast won't kill us after 5 minutes...
};
Затем в нашем собственном приложении, если нам нужно использовать тайм-аут, который мы называем _setTimeout
вместо.
Мне было бы интересно, если бы кто-нибудь нашел лучший способ добиться этого, кроме ручного хостинга cast_receiver_framework.js
с закомментированной строкой (которая находится внутри Wn(a, b)
функция) или отправка тихого клипа каждые несколько минут. Но сам хостинг не рекомендуется Google.
Лучшим решением может быть копаться в минимизированном коде, чтобы понять, как Xn(a)
вызывается так, что отключает тайм-аут при воспроизведении мультимедиа, а затем находит способ вызвать его из приложения Chromecast.
Загрузка короткого неслышимого аудиоклипа от отправителя к получателю каждые 4 минуты, похоже, помогает. Это не должно сильно влиять на производительность, если файл небольшой. Вот немного кода Android.
MediaMetadata metadata = new MediaMetadata(MediaMetadata.MEDIA_TYPE_MUSIC_TRACK);
MediaInfo mediaInfo = new MediaInfo.Builder("https://some-inaudible-clip.mp3")
.setStreamType(MediaInfo.STREAM_TYPE_BUFFERED)
.setContentType("audio/mpeg")
.setMetadata(metadata)
.build();
RemoteMediaClient remoteMediaClient = castSession.getRemoteMediaClient();
remoteMediaClient.load(mediaInfo, true);
Можно отправить пользовательское сообщение пространства имен от получателя отправителю. Это должно поддерживать сердцебиение. Однако ваш вариант использования напрямую не поддерживается Cast SDK, поэтому вам придется экспериментировать с решением.