Одной из важных особенностей экосистемы Android всегда было большое разнообразие устройств. Android работает в смартфонах и планшетах, автомобилях и умных часах, домашней технике и телевизорах. На нынешнем I/O были анонсированы и новинки - умная колонка Home, платформа виртуальной реальности Daydream. Android все больше проникает во все сферы цифровой жизни, помогая управлять любыми устройствами.
Этой статьей мы начинаем цикл, в котором хотим рассказать о том, как использовать разные устройства экосистемы Android в своих приложениях: как транслировать видео на Chromecast, как создавать приложения для Android TV или как использовать мир "физического веба" в маячками Eddystone.

Самое главное - не забывайте про сам конкурс - Device Lab от Google. Вы сможете взять любые из этих устройств и начать разрабатывать свои приложения, тестируя функционал вживую.

Добро пожаловать в будущее Android.
Android и Media
В этой статье мы рассмотрим вопросы работы и создания приложений для медиа-устройств - Chromecast и Chromecast Audio. В рамках нашего проекта все они доступны для разработчиков - оставьте заявку и начните работу с ними прямо сейчас.
Chromecast Audio
Chromecast Audio - миниатюрное устройство для трансляции аудио-потока на любое устройство с AUX входом, вышедшее в продажу в конце 2015 года. Идеальный подход Chromecast Audio как раз в том, что вы можете транслировать вашу любимую музыку практически на любое устройство с таким входом - ваш старый музыкальный центр получит интеграцию с Google Play Music благодаря подключению к Chromecast Audio и через него уже к вашему смартфону или планшету. Недорогой гаджет - ответ на все чаяния тех, кому не хочется обновлять свои аудиосистемы, но хочется сделать их умными и получить все возможности современных приложений у себя дома.
Поставляется Chromecast Audio в миниатюрной коробке, в комплекте у него блок питания с выходом microUSB (фактически вы можете подключить его к любому устройству с таким шнуром, не привязываясь к розетке), собственно сам Chromecast Audio и кабель-переходник. Подключение его к аудиосистеме очень простое - вы втыкаете кабель в Chromecast Audio, скачиваете приложение в Google Play для управления и все работает - на подключение к колонкам у меня ушло около 5 минут с обновлением прошивки (вы также можете подключить Chromecast Audio к своей Wi-Fi сети и устройство сможет работать в ней автономно).

После этого в приложениях, которые поддерживают трансляцию (есть на официальном сайте Chromecast), вы сможете выбрать нужное устройство. Каждое из них можно назвать по-своему и организовать передачи звука в разные комнаты своей квартиры или дома, таким образом зонировать и «перемещать» трансляции. Точно так же - управлять трансляциями голосом при помощи только что анонсированного на I/O Google Home: «Включи музыку в гостиной - Переключи в спальню - Выключи».

Посмотрим на примере Google Play Музыки, как в два шага открывается трансляция на Chromecast Audio:
Пожалуй, главная проблема Chromecast Audio в том, что трансляция не работает "по умолчанию" в любом приложении. Хотя их несколько десятков уже подключенных, все же, если вы Spotify, скажем, предпочитаете Zvooq, то завести его на Chromecast Audio у вас не получится - последнее приложение пока, к сожалению, не поддерживает такую трансляцию.

Но ведь затем мы здесь и собрались - чтобы расширить набор приложений, работающих с удобными устройствами.
Chromecast
Chromecast - старшее устройство, цифровой медиаплеер от Google, предназначенный уже для потокового воспроизведения видео контента (кстати, Сундар Пичаи в ходе открывающего I/O выступления отметил, что всего в мире продано уже более 25 миллионов устройств Chromecast). Chromecast работает на упрощенной версии Chrome OS. Для передачи медиа-контента Chromecast использует протокол DIAL, разработанный совместными усилиями компаний Netflix и YouTube. Главная его особенность в том, что, в отличие от других подобных технологий, устройство пользователя не участвует в обработке потока, оно фактически инициирует передачу, а дальше весь контент Chromecast (как в случае аудио, так и видео) берет с удаленного сервера сам. Таким образом телефон или планшет исключается из процесса обработки, не тратя свои ресурсов, не выжигая батарею и не нагружая сеть, он может заниматься другими задачами.
Большой Chromecast подключается уже не к аудиопорту, как Chromecast Audio, а к стандартному HDMI, то есть его можно "повесить" на телевизор, даже не подключенный к Сети, и передавать контент на него. Если Chromecast Audio это улучшение аудио систем, то Chromecast очевидно предназначен для видео-систем и создания из них современных мультимедийных центров, переноса новых приложений и трансляции веб-контента на экранах домашних телевизоров.

Настройка Chromecast происходит через то же самое приложение Google Cast - оно подключается к брелоку, и вы можете задать параметры доступа к Wi-Fi сети. После этого Chromecast сам скачает все обновления и вы сможете начать работу с ним.

Для этого вам снова понадобится приложение, которое умеет транслировать контент на Chromecast. Для примера возьмем YouTube для iOS, в нем появляется иконка, при нажатии на которую начинается трансляция:
При этом вы сможете продолжить работу с другими приложениями, так как трансляция идёт в фоновом режиме:
Вы также можете транслировать содержимое браузера на ТВ, для Chrome есть расширение Google Cast. Хотите изучать Хабр на большом экране? Да пожалуйста!

Единственное «но», как и в случае с Chromecast Audio - приложение должно поддерживать трансляцию на экран, с любым приложением по умолчанию это не работает. Но, надо сказать, приложений таких уже достаточно много, есть TED, Амедиатека, ivi.ru и Zoombye, не говоря уж о «стандартных» YouTube, Google Play Фильмах и т.п.
Есть также некоторые простые игры, вроде Angry Birds Go. Список весь вы можете найти тут. Для Android начиная с версии 4.4.2 доступна трансляция всего экрана устройства на Chromecast (зеркалирование), для этого в меню приложения есть специальный пункт.
Мне, правда, заставить эту функцию работать удалось лишь на мгновенье, но я отношу это к недостаткам моего тестового смартфона.

Кстати, в режиме простоя Chromecast транслирует на экран какие-то фантастически красивые фотографии природы, так что выключать его даже не хочется (вместо них на заставку можно поставить и свои собственные фотографии, все тоже через приложение).
Google Cast SDK
Начало вашей интеграции - Google Cast SDK с библиотеками и примерами кода для Android, iOS или Chrome.

Компоненты, которые вам нужно создать:

В общем виде вам понадобится отправляющее поток приложение (sender application). Обычно это приложение на мобильном устройстве, в котором ведется трансляция.

Примеры:

Обратите внимание, что в конкурсе разработчиков участвуют только Android и Web-приложения

Принимающее поток приложение (receiver application). Оно управляет коммуникациями между отправляющим приложением и сами устройством. В случае аудио вам принимающее приложение не нужно, в случае видео у вас есть несколько вариантов действия. Вы можете использовать:

  • Default Media Receiver со стандартным брендингом Google Cast;
  • cвой собственный Styled Media Receiver, отличающийся дизайном;
  • кастомный ресивер, опирающийся на Receiver API и обрабатывающий специальные сообщения от вашего отправляющего приложения.

Обратите внимание, что вам понадобится дополнительная регистрация вашего аккаунта и устройств в Google для работе с Cast SDK. Стоит она 5 долларов. После регистрации вам выдадут ID, который можно будет использовать в вашем приложении для работы с устройствами.

Также настоятельно рекомендуем вам ознакомиться со списком проверки, который необходимо пройти каждому Cast-приложению. В нем перечислены все важные пункты, касающиеся дизайна и юзабилити приложений, транслирующих видео или аудио на устройства Chromecast.

Отправка

Рассмотрим обычную процедуру работы приложения с Cast-устройством:

  • Приложение начинает обнаружение MediaRouter: MediaRouter.addCallback
  • MediaRouter информирует посылающее приложение о выбранном пользователем устройстве: MediaRouter.Callback.onRouteSelected
  • Приложение получает инстанс CastDevice: CastDevice.getFromBundle
  • Приложение создает GoogleApiClient: GoogleApiClient.Builder
  • Приложение подключается к GoogleApiClient: GoogleApiClient.connect
  • SDK подтверждает, что GoogleApiClient подключен: GoogleApiClient.ConnectionCallbacks.onConnected
  • Транслирующее приложение запускает принимающее приложение: Cast.CastApi.launchApplication
  • SDK подтверждает, что принимающее приложение подключено: ResultCallback<Cast.ApplicationConnectionResult>
  • Транслирующее приложение создает коммуникационный канал: Cast.CastApi.setMessageReceivedCallbacks
  • Транслирующее приложение отправляет сообщение на ресивер через коммуникационный канал: Cast.CastApi.sendMessage
Более подробно с примерами кода по каждому из пунктов вы можете прочитать на официальной странице.

Пример приложения: https://github.com/ckurtm/LocalCast

Инициализируем конфигурацию:

CastConfiguration options =new CastConfiguration.Builder("84B70D9D")
	.enableAutoReconnect()
.enableDebug()
.build(); 
DataCastManager.initialize(this,options);
Делаем Cast-кнопку:
<item android:id="@+id/action_cast" 
android:title="@string/action_cast" app:actionProviderClass="android.support.v7.app.MediaRouteActionProvider" app:showAsAction="always"/> 

@Override 
public boolean onCreateOptionsMenu(Menu menu)
{ 
super.onCreateOptionsMenu(menu); 
getMenuInflater().inflate(R.menu.menu,menu); DataCastManager.getInstance().addMediaRouterButton(menu,R.id.action_cast); 
return true; 
}
Отправляем данные:
JSONObject obj = new JSONObject(); 
String url = "http://"+ info.ip + ":" + info.port + "/" + item.getFile().getAbsolutePath(); 
Log.d(TAG, "casting: " + url); 
try
{ 
obj.put("url",url); 
DataCastManager.getInstance().sendDataMessage(obj.toString(),"urn:x- cast:com.peirr.localcast");
 } 
catch (JSONException|IOException e) 
{ 
e.printStackTrace(); 
}
Приём

Приложение-приемник это HTML5/JavaScript-приложение (это справедливо для Chromecast, отличие Android TV в том, что там как раз работают полноценные приложения, а тут используется тонкий веб-клиент), которое запускается на целевом устройстве (Chromecast) и предоставляет интерфейс для показа контента на экране ТВ, обеспечивает обработку сообщений для управления контентом и специальных сообщений, которые может посылать клиент.

Решений у вас, соответственно, всего два - стилизовать стандартный Media Receiver (вам понадобится собственный CSS-файл) или разработать собственный с нуля. Последнее может понадобиться, если вы хотите показывать нестандартный контент, который не поддерживает стандартный ресивер.

Как выбрать? Google разработал превосходную схему:
Простой кастомный ресивер:
<head> 
<title>LocalCast</title> 
<script src="cast_receiver.js"></script>
<link rel="stylesheet" href="receiver.css"/>
</head>

<script> 

function process(json)
{
console.log('received: ' + json.url);
document.getElementById("image").src= json.url;
 } 

window.castReceiverManager = cast.receiver.CastReceiverManager.getInstance(); castReceiverManager.onSenderDisconnected = function(event)
{ 
console.log('disconnected: ' + event.data); 
if (window.castReceiverManager.getSenders().length == 0) { //close the app if we have no more connected devices window.close(); }
}; 

window.messageBus = window.castReceiverManager.getCastMessageBus('urn:x-cast:com.peirr.localcast'); 
window.messageBus.onMessage = function(event)
{ 
var json = JSON.parse(event['data']); //decode the request from sender app 
window.sender = event.senderId; process(json); 
} 

window.castReceiverManager.start(); 

</script>
Дополнительные материалы
Бесплатный курс на Udacity "Разработка для Android TV и Google Cast":

https://www.udacity.com/course/android-tv-and-google-cast-development--ud875B

Плагин для Unity:

https://www.assetstore.unity3d.com/en/#!/content/50168

Репозиторий Chromecast на GitHub:

https://github.com/googlecast/

Разработка игр для Google Cast:
Разработка для Chromecast, презентация Курта Мбанье, ведущего Android разработчика в DStv Online:

http://www.slideshare.net/ckurtm/developing-for-chromecast-on-android-61200612
Советы от разработчика
Илья Манин
разработчик SPB TV
— Как у вас работает трансляция на Chromecast?

— Мы используем стандартную технологию трансляции видео для Chromecast, которая не так давно получила название Google Cast. Эта технология интересна тем, что непосредственно сам видео-контент не транслируется с мобильного устройства на Chromecast. Мобильное устройство передает только ссылку на поток, а загрузкой видео и декодированием занимается уже само Chromecast устройство. Причем, такой метод трансляции работает не только с Chromecast, но и с любым устройством, поддерживающим Google Cast технологию. На текущий момент это все устройства на базе Android TV - STB-приставки, например Nexus Player или NVidia Shield и Smart TV телевизоры от Sony и Philips.

Такой подход позволяет освободить вычислительные мощности мобильного устройства, оно не будет перегреваться и разряжать аккумулятор. Трансляция будет продолжаться даже при выключенном телефоне. Более того, можно продолжить управлять этой трансляцией с любого другого Android или iOS-устройства или из настольного браузера Chrome.

Другие технологии, такие, как Miracast или WiDi, используют «зеркалирование» экрана, т.е. на устройстве в реальном времени происходит захват видеопотока с экрана устройства, кодирование видео и трансляция по Wi-Fi на приемные устройства. По нашему опыту, такие технологии требовательны к ресурсам мобильных устройств и нагружают локальную Wi-Fi сеть. Для «зеркалирования» онлайн-трансляций поток сначала скачивается на мобильное устройство, там декодируется и выводится на экран, затем снова кодируется и передается на приемник по той же Wi-Fi сети, на приемнике видеопоток снова декодируется и выводится на экран. Недостатки такого подхода особенно явно проявляются при трансляции тяжелого HD-контента.

Строго говоря, Google Cast приемники также поддерживают «зеркалирование». Но необходимо учитывать, что этот режим долгое время был в состоянии бета версии, Google не советует использовать его для видеовещания, и работа в таком режиме возможна не со всех мобильных устройств.

«Зеркалирование» может использоваться для вещания игр или для приложений, не поддерживающих основной режим работы Google Cast, однако, в этом случае могут возникать задержки (latency), вызывающие дискомфорт в динамичных играх.

Во всех остальных случаях мы советуем использовать трансляцию Google Cast, а разработчикам советуем адаптировать приложения для полноценной поддержки этой технологии.

— Вызвала ли какие-нибудь проблемы интеграция?

— Для реализации минимальной функциональности никаких проблем не возникает. По этой технологии Google подготовил очень подробную документацию, доступно много рабочих примеров и библиотек. Некоторые сложности проявляются, когда мобильные программисты понимают, что приложение-приемник пишется на JavaScript. Но для простых задач можно использовать готовый приемник от Google, тогда необходимость программировать на JS и поддерживать свое Web-приложение полностью отпадает.

Также могут возникнуть сложности, когда стоит задача реализовать полную функциональность по всем Guidelines от Google. В таких случаях приходится учитывать большой объем различных факторов, особенно по UI. Нужно интегрировать Сast компонент в лайауты всех экранов, обеспечить работу на экране блокировки и в области нотификации, необходимо вовремя получать события от приемника, грамотно их обрабатывать и обновлять UI.

К счастью, уже появились библиотеки, частично решающие эти задачи, например, CastCompanionLibrary (https://github.com/googlecast/CastCompanionLibrary-android).

Однако пока подобные библиотеки не охватывают все возможные случаи, и во многом требуют доработки.

Вот пример кода, который запускает трансляцию на Chromecast:
import com.google.android.gms.cast.MediaInfo;
import com.google.android.gms.cast.MediaMetadata;
import com.google.android.gms.common.images.WebImage;
import com.google.android.libraries.cast.companionlibrary.cast.VideoCastManager;
...
private final VideoCastManager mVideoCastManager = VideoCastManager.getInstance();
...
public void play() {
MediaMetadata contentMetadata = new MediaMetadata(MediaMetadata.MEDIA_TYPE_GENERIC);
// название видео, будет отображаться на ТВ
contentMetadata.putString(MediaMetadata.KEY_TITLE, "Тестовый HLS поток");
// постер для видео (например постер фильма)
String posterUrl = "http://.../link_to_poster_image.jpg";
// небольшой логотип (например логотип ТВ канала)
String logoUrl = "http://.../link_to_logo_image.jpg";
WebImage poster = new WebImage(posterUrl);
WebImage logo = new WebImage(logoUrl);
contentMetadata.addImage(poster);
contentMetadata.addImage(logo);
// будем смотреть живое вещание
int streamType = MediaInfo.STREAM_TYPE_LIVE;
// ссылка на демо поток
String streamUrl = "https://devimages.apple.com.edgekey.net/streaming/examples/bipbop_4x3/bipbop_4x3_variant.m3u8";
MediaInfo info = new MediaInfo.Builder(streamUrl).setContentType("application/x-mpegURL")
.setStreamType(streamType)
.setMetadata(contentMetadata)
.build();
boolean autoplay = true;
int position = 0;
mVideoCastManager.loadMedia(info, autoplay, 0);
}
— Какими ресурсами вы пользовались при разработке?

— Основной ресурс, где собрано все, что нужно для программирования на ChromeCast - UI-гайды, чеклисты, документация для разработчиков, подробные описания и примеры: https://developers.google.com/cast/

Подборка примеров и библиотек на GitHub: https://github.com/googlecast/
Будущее
На самом деле, медиа-устройства Google оказались намного интереснее и функциональнее, чем казалось изначально. Они решают насущные проблемы, причем удобными и простыми способами. Используйте их в разработке - и ваши приложения приобретут новую аудиторию и новых благодарных пользователей.

Участвуйте в конкурсе Device Lab от Google, внедряйте поддержу новых устройств в ваши приложения, это и есть будущее, к которому вы уже можете прикоснуться.

А в следующей статье лаборатории мы рассмотрим Android TV.
Комментарии 9
  • +1
    Спасибо за статью, хоть она и насквозь рекламная.
    Одна просьба: пользуйте, пожалуйста, стандартное оформление статей вместо этого «модного», а то за один только дурацкий эффект «меееедленное появление текста при прокрутке» хочется убивать, ведь на него тратися время и он сбивает фокус. В итоге, уже к середине статьи хочется взять адблок и вырезать к чертовой бабушке весь джаваскрипт со страницы. И шрифт слишком крупный, и текст зажат между пустыми белыми полями, и изображение сверху не несет никакой нагрузки… Пожалейте читателей, иначе их очень быстро не станет совсем.
    • 0
      Почему что Chromecast, что Miracast Receiver нельзя запустить на планшете, часто возникает желание запустить видео с ноута на планшете, и снова, по старинке, через dlna, который вечно работает нестабильно и криво, да раз уж Chromecast приложение — фактически веб приложение, что мешет добавить их поддержку в Chrome и мобильный, и десктопный?
      • 0
        В десктопном Chrome конечно есть плагин для трансляции — Google Cast: https://chrome.google.com/webstore/detail/google-cast/boadgeojelhgndaghljhdicfkmllpafd?hl=ru
        • 0
          Из описания расширения: «Чтобы использовать Google Cast, вам необходимо устройство Chromecast.»

          Т. е. оно позволяет только отправить контент на Chromecast, использовать PC как Chromecast устройство нельзя, как и планшет на Android с приложением Google Cast.

          С Miracast вообще странно, мало того, что его прибили гвоздями к Wifi(может у меня телевизор по ethernet подключен), так еще и имея ноут с Win 10 с поддержкой Miracast и планшет на Android с поддержкой Miracast не могут друг с другом работать, 20-й век, ты где? Я хочу в 2 тапа подключить планшет как второй монитор или вывести mirror экрана с телефона на десктоп(на котором обычно нет Wifi, потому, что он станционарный).

          P. S. Мой комментарий был про искуственные ограничения, но я не буду спорить, мои юзкейсы далеко не самые приоритетные.
        • 0
          В десктопном оно с самого начала было как расширение — google cast.
        • 0
          Еще один минус Хромкаста это то, что он требует постоянно подключения к интернету. То есть скачать фильм на планшет, отключиться от инета и запустить трансляцию на экран не получится.
          • 0
            Получится, по крайней мере на Android. В стандартном приложении настройки chromecast есть «зеркалирование» экрана.
            • 0
              Пробовал (но правда только для первого хромкаста). Все равно требовал интернет. По крайней мере полгода назад.
          • 0
            Пробовал писать пару совсем простых примеров, если кому интересно — git

            Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.