Тайм-аут пользовательского приемника 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, поэтому вам придется экспериментировать с решением.

Другие вопросы по тегам