- PVSM.RU - https://www.pvsm.ru -
Ввиду живого интереса к прошлой статье [1] о библиотеке Smartbox [2], которая призвана стать основой для любого кроссплатформенного SmartTv приложения, я решили описать, как же создать такое приложение разом для трёх вендоров SmartTv устройств:
Итак, в этой статье вы найдёте много полезного, если вы:
Статья получилась «пухлой» и с кучей спойлеров — потому оглавление:
* Из-за того что, эта статья предназначена не только для разработчиков — первыми и, как показалось нашей команде, более интересными, идут пункты о запуске приложений в эмуляторах и конечных устройствах.
Окунувшись в разработку SmartTv приложений, вы в конечном итоге будите вынужденны так или иначе тестировать своё творение. Дао [9] тестирования для SmartTv состоит из последовательных пунктов:
Далее мы рассмотрим, два последних шага на пути тестировщика. Первый пункт не является специфичным, а потому Вы сами найдете много интересного, просто запустив приложение и нажав клавишу F12
в браузере. Еще одним «хаком» в тестировании является автоматизация этого процесса. В библиотеке, например, используется jasmine [10] для тестов [11] в среде запуска.
Далеко, как мы выяснили, не соответствующее реальности — это эмуляторы, поставляемые с каждым SDK. (Samsung [12], LG [13], Philips [14]) В конечном итоге, запуски на эмуляторах должны стать для Вас не более чем самопроверкой. И работоспособное приложение в эмуляторе не может считаться заведомо работоспособным на устройстве. И напротив, если у Вас что-то не работает в эмуляторе, не факт что это фиаско.
Apps
с соблюдением регистра. На скриншотах вы найдёте пояснения.
Дальнейший шаг в тестировании приложений сделала компания Samsung, запустив лабораторию на удалённых устройствах. Фактически, это реальные девайсы, позволяющие проверить все функции вашего детища, которые невозможно лицезреть в эмуляторах (например, работа плеера со всеми форматами, взаимодействие с системами DRM).
Для запуска нашего приложения, необходимо выбрать устройство на сайте лаборатории [27] и следовать инструкциям:
Мы рассмотрим самый простой, на мой взгляд, способ установки и проверки приложений на конечных пользовательских устройствах. Для этого нам понадобится:
demo/demoApp
[32];Можно использовать адрес публичного демо http://immosmart.github.io/smartbox/demo/demoApp/ [33], если у вас по какой-то причине нет HTTP сервера для публикации приложения. Однако, хочу заметить, что для возможности экспериментирования, и разработки приложения HTTP сервер необходим (если вы, конечно, не будите использовать альтернативные методы инсталляции, описанные в документации вендоров)
13 платформа:
* В ряде случаев для TV требуется разрешение на установку сторонних приложений, что обеспечивается ключём разработчика, который можно получить обратившись в RND Samsung (http://samsungdforum.com/ [34]) Сделано вендером для пресечения нелегального распространения приложений
Для того чтобы запустить приложение на TV/BD Samsung. Необходимо создать widgetlist.xml
в корне сервера на который можно обратиться по IP адресу. Например, http://xxx.xxx.xxx.xxx/widgetlist.xml. Я разместил файл по адресу http://82.146.41.200/widgetlist.xml [37].Файл, напросто, является списком приложений для установки. В списке виджетов главным элементом является узел download
, где указывается ссылка на zip-архив вашего приложения. Остальные параметры не имеют значения, даже размер. Как видно из нашего виджет-листа своё приложение я зазиповал и сложил по адресу http://paunin.com/content/smartbox.zip [38].
Теперь всё что осталось это сообщить устройству адрес вашего IP c widgetlist.xml
и обновить приложения. Это делается средствами устройства в зависимости от модели:
Наверное, самый захватывающий квест из всех рассматриваемых устройств. Для установки приложения LG его необходимо зарегистрировать на странице разработчика [39](требуется регистрация/авторизация).
Заполняем всё, как указано на картинках и скачиваем получившийся файлик.
Если кому-то понадобится, я свой файлик разместил по адресу http://paunin.com/content/lg_wrapper.zip [35].
И теперь всё что осталось — доставить приложение (точнее его подпись, само приложение находится в интернете) на телевизор:
Для запуска на Philips SmartTv устройствах приложения, нам понадобится всего лишь запустить его в браузере путём указания адреса HTTP.В нашем случае используем адрес http://paunin.com/content/demoApp/index.html [31]. Однако, сразу после старта браузера, вы заметите нативные рамки вокруг элементов в фокусе, что не приемлемо для боевого приложения, и чего в действительности не будет при размещении приложения в LG хабе.
Всё решается указанием при ответе с сервера необходимых заголовков, а именно "application/ce-html+xml
". Этим занимается присутствующий а приложении php скриптик philips.php
. Соответственно получаем адрес типа http://paunin.com/content/demoApp/philips.php [42]. Для ускорения набора адреса с пульта телевизора, можете воспользоваться сервисом сокращения ссылок, например, http://goo.gl/ [43]. У меня получился адрес http://goo.gl/o93keD [36]
Я рассмотрю, исключительно, разработку приложения на базе библиотеки Smartbox. Если вы решите, что функционала библиотеки недостаточно для задач, стоящих перед вами, вы всегда можете использовать нативные методы платформ, изучив документацию вендора устройств. [7] Также, вы можете поучаствовать в развитии и доработках проекта на gitHub'е [2].
Для нетерпеливых — готовое приложение [44]
Конфиги приложения должны храниться в нескольких файлах, и все они в относятся к Samsung платформе:
Screen Resolution
, который определяет разрешение для которого написано ваше приложение, рекомендуемый на текущий момент это HD 1280x720
. Допустимы: SD 960x540
и FullHD 1920x1080
Use Alpha Blending = Yes
Screen Resolution = 1280x720
<?xml version="1.0" encoding="UTF-8"?>
<widget>
<voice>y</voice> <!-- Использовать ли управление голосом -->
<mouse>y</mouse> <!-- Использовать ли управление жестами или мышь -->
<previewjs itemtype="string"></previewjs>
<preicon itemtype="string"></preicon>
<cpname itemtype="string"></cpname>
<cplogo itemtype="string"></cplogo>
<cpauthjs itemtype="string"></cpauthjs>
<ver itemtype="string">0.1</ver> <!-- Версия сборки -->
<mgrver itemtype="string"></mgrver>
<fullwidget itemtype="boolean">y</fullwidget>
<srcctl itemtype="boolean">y</srcctl>
<ticker itemtype="boolean">n</ticker>
<childlock itemtype="boolean">n</childlock>
<audiomute itemtype="boolean">y</audiomute> <!-- разрешить на фоне играть музыку от сигнала с антены или других -->
<videomute itemtype="boolean">y</videomute> <!-- разрешить на фоне видео от сигнала с антены или других -->
<dcont itemtype="boolean">y</dcont>
<widgetname itemtype="string">SmartBox DemoApp</widgetname> <!-- Имя виджета/приложения, показывается в телевизоре после инсталляции -->
<description itemtype="string"></description> <!-- Описание виджета/приложения -->
<width itemtype="number">1280</width> <!-- разрешение виджета - ширина -->
<height itemtype="number">720</height> <!-- разрешение виджета - высота -->
<author itemtype="group"> <!-- Описание автора -->
<name itemtype="string">Smart</name>
<email itemtype="string">info@example.com</email>
<link itemtype="string">https://github.com/immosmart/smartbox</link>
<organization itemtype="string">Smart</organization>
</author>
<!-- блок путей до иконок (размеры видны из имён файлов), показывается в телевизоре в разных местах после инсталляции -->
<ThumbIcon itemtype="string">icon/sb_demo_115x95.png</ThumbIcon>
<BigThumbIcon itemtype="string">icon/sb_demo_115x95.png</BigThumbIcon>
<BigListIcon itemtype="string">icon/sb_demo_95x78.png</BigListIcon>
<ListIcon itemtype="string">icon/sb_demo_85x70.png</ListIcon>
</widget>
При запуске нашего приложения всегда открывается файл index.html
, в котором и подключаются все библиотеки и наши скрипты, а также задаётся начальная вёрстка.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; Charset=UTF-8"/>
<title>Smartbox demo</title>
<!--Стили для отдельных сцен-->
<link rel="stylesheet" href="css/input.css"/>
<link rel="stylesheet" href="css/keyboard.css"/>
<link rel="stylesheet" href="css/legend.css"/>
<!--Общие стили-->
<link rel="stylesheet" href="css/style.css"/>
<!--Библиотеки требуемые Smartbox-->
<script type="text/javascript" src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
<script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/lodash.js/2.4.1/lodash.js"></script>
<script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.1.0/backbone-min.js"></script>
<!--Сама библиотека Smartbox-->
<script type="text/javascript" src="js/lib/smartbox.js"></script>
<!--Главный объект приложения-->
<script type="text/javascript" src="js/app.js"></script>
<!--Подгрузка модели для сцены с видео-->
<script type="text/javascript" src="videos.js"></script>
<!--Сцены-->
<script type="text/javascript" src="js/scenes/videos.js"></script>
<script type="text/javascript" src="js/scenes/navigation.js"></script>
<script type="text/javascript" src="js/scenes/input.js"></script>
<!--Тригеры для обработки событий и отрисовки легенды в подвале экрана-->
<script type="text/javascript" src="js/legendTriggers.js"></script>
</head>
<body>
<!--for better view in browser-->
<div class="bg"></div>
<div class="wrap">
<!--Боковое меню с логотипом-->
<div class="menu">
<div class="logo"></div>
<ul class="menu-items" data-nav_type="vbox" data-nav_loop="true">
<li data-content='video' class="menu-item menu-item_green nav-item">Videos</li>
<li data-content='input' class="menu-item menu-item_blue nav-item">Inputs</li>
<li data-content='navigation' class="menu-item menu-item_red nav-item">Navigation</li>
</ul>
</div>
<!--//Боковое меню с логотипом-->
<!--Сцены-->
<div class="scenes-wrapper">
<!--Сцена демонстрации видео (контент подгрузится при инициализации сцены scenes/videos.js )-->
<div class="scene scene_video js-scene-video" data-nav_type="vbox" data-nav_loop="true">
<!--<div data-url="http://smartimmo.ru/uploaded/big_buck_bunny_480p_h264.mp4" data-type="vod" class="video-item nav-item">Big Buck Bunny</div>
<div data-url="https://archive.org/download/ElephantsDream/ed_1024_512kb.mp4" data-type="vod" class="video-item nav-item">Elephants Dream</div>
<div data-url="http://europaplus.cdnvideo.ru/europaplus-live/eptv_main.sdp/playlist.m3u8" data-type="hls" class="video-item nav-item">HLS test</div>
<div data-url="http://phone.pik-tv.com/live/mp4:piktv3pik3tv/playlist.m3u8" data-type="hls" class="video-item nav-item">HLS test 2</div>
<div data-url="http://live.iphone.redbull.de.edgesuite.net/webtvHD.m3u8" data-type="hls" class="video-item nav-item focus">HLS test 3</div>-->
</div>
<!--//Сцена демонстрации видео-->
<!--Сцена демонстрации input'ов-->
<div class="scene scene_input js-scene-input">
<div class="input-example">
<h2>Standart input</h2>
<input class="input-item js-input-1 nav-item"/>
<div class="input-val">
Input value: <span class="js-input-1-val"></span>
</div>
</div>
<div class="input-example">
<h2>Input with email keyboard</h2>
<input class="input-item js-input-2 nav-item"/>
</div>
<div class="input-example">
<h2>Input with num keyboard and maximum 4 signs</h2>
<input class="input-item js-input-3 nav-item"/>
</div>
</div>
<!--//Сцена демонстрации input'ов-->
<!--Сцена демонстрации навигации-->
<div class="scene js-scene-navigation">
<ul class="navigation-items">
<li class="navigation-item nav-item">1</li>
<li class="navigation-item nav-item">2</li>
<li class="navigation-item nav-item">3</li>
<li class="navigation-item nav-item">4</li>
<li class="navigation-item nav-item">5</li>
<li class="navigation-item nav-item">6</li>
<li class="navigation-item nav-item">7</li>
<li class="navigation-item nav-item">8</li>
</ul>
<p class="navigation-info"></p>
</div>
<!--//Сцена демонстрации навигации-->
</div>
<!--//Сцены-->
</div>
</body>
</html>
Самое важное, что стоит тут отметить — организация навигации. Все видимые элементы с классом nav-item
могут получить на себя фокус и позже инициировать события (focus
, click
, etc). Для оптимизации навигации, в боковом меню и на сцене видео используется data-nav_type="vbox"
, что говорит плагину навигации " перестать использовать поиск направления согласно положению элементов на странице, и фокус начинает перемещаться от одного sibling элемента к другому, что гораздо быстрее" (с) Документация по навигации [46]. Другой хак — это аттрибут data-nav_loop="true"
, что позволяет зацикливать навигацию в рамках данного элемента.
Заглянем в файл js/app.js
[47] После инициализации самого Smartbox происходит инициализация приложения SB.ready(_.bind(App.initialize, App));
, запуская тем самым показ легенды $$legend.show();
и добавление обработчиков событий this.setEvents();
от элементов меню, плеера, клавиш пульта. Дополнительные комментарии в самом файле.
Во время работы приложения, мы хотим показывать пользователю подсказки по использованию тех или иных клавиш пульта. Самый простой способ — это обновлять легенду в зависимости от произошедшего события. Этим собственно и занимается файл js/legendTriggers.js
[48]. При фокусе nav_focus
или потери фокуса nav_blur
мы задаем элементам легенды window.$$legend.keys
различные значения, которые тот час же выводятся с соответствующим значком.
Как и любое приложение, наше должно иметь источник данных для отображения, взаимодействия с пользователем или внутренней настройки. Все наши данные для сцены videos
хранятсяв файлике videos.js
. Это лишь пример, а потому реальное приложение, вероятно, будет получать данные иным способом. Всё что делает этот кусок кода — сохраняет массив объектов (со ссылками на потоки и их назвния) в глобальный объект приложения window.App.videos = [...]
. Далее, в файле сцены, этот массив будет развёрнут и вставлен в html в div.scene_video
.
Сцены это всего навсего объекты одной структуры, хранящиеся в глобальном объекте window.App
, которые показываются и скрываются в зависимости от того, на какой элемент меню был сделан click
//js/app.js
$('.menu').on('click', '.menu-item', function ( e ) {
var scene = e.currentTarget.getAttribute('data-content');
self.showContent(scene);
});)
Метод инициирующий отображение сцен:
//js/app.js
showContent: function ( scene ) {
var cur = this.currentScene,
newScene = this.scenes[scene];
if ( cur !== newScene ) {
if ( !newScene ) {
$$error('Scene ' + scene + ' doesn't exist');
} else {
if ( cur ) {
cur.hide();
}
newScene.show();
this.currentScene = newScene;
}
}
}
Не буду подробно останавливаться на реализации сцен, а опишу лишь специфику относящуюся к библиотеке Smartbox.
Как и говорилось выше, коллекция видео-потоков, после разворачивания в html this.renderItems(App.videos);
, становится доступной для навигации за счёт класса в элементе nav-item
. При инициализации сцены, все видео-потоки получают обработчик события this.$el.on('click', '.video-item', this.onItemClick);
, где и происходит запуск потока Player.play(...)
. Документация по плееру [49].
Для демонстрации работы клавиатуры в сцене input
, каждому отдельному полю ввода подключается клавиатура через метод SBInput
. Документация по клавиатуре [50] также содержит информацию о способах добавления своих языков и раскладок.
js-input-2
, естественно, после события click
:
//js/scene/input.js
this.$el.find('.js-input-2').SBInput({
keyboard: {
type: 'email'
}
});
Сцена, демонстрирующая события nav_focus
и nav_blur
для элементов с классом navigation-item
, не отличается спецификой навигации и просто реализует подмену информационного блока при смени элемента в фокусе.
//js/scene/navigation.js
init: function () {
var $info;
this.$el = $('.js-scene-navigation');
$info = this.$el.find('.navigation-info');
this.$el
.find('.navigation-item')
.on(
{
'nav_focus': function () {
$info.html('Item with text "' + this.innerHTML + '" focused');
},
'nav_blur': function () {
$info.html('');
}
});
_inited = true;
}
Всем спасибо и хорошей недели!
Разработчикам, желающим поучаствовать в проекте и расширить библиотеку, мы всегда рады и ждём pull request'ов
Автор: ZmeeeD
Источник [58]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/javascript/54652
Ссылки в тексте:
[1] прошлой статье: http://habrahabr.ru/post/211236/
[2] Smartbox: https://github.com/immosmart/smartbox
[3] Тестирование приложения: #test
[4] Запуск в эмуляторах вендоров(и удалённых устройствах): #starte
[5] Запуск на SmartTv телевизорах: #startd
[6] Разработка приложения: #develop
[7] Ссылки на ресурсы для разработчиков: #see
[8] Библиотека Smartbox: #lib
[9] Дао: http://ru.wikipedia.org/wiki/%D0%94%D0%B0%D0%BE
[10] jasmine: http://pivotal.github.io/jasmine/
[11] тестов: http://immosmart.github.io/smartbox/
[12] Samsung: http://www.samsungdforum.com/Devtools/SdkDownload
[13] LG: http://developer.lge.com/resource/tv/RetrieveSdktools.dev
[14] Philips: http://www.yourappontv.com/sdk/download
[15] VirtualBox: https://www.virtualbox.org/
[16] Image: http://habr.habrastorage.org/post_images/73c/8c9/2b0/73c8c92b0dcc3f48967957ecb8e641c6.jpg
[17] Image: http://habr.habrastorage.org/post_images/632/e6a/ad3/632e6aad30e7bb5cf7b996399f997986.jpg
[18] Image: http://habr.habrastorage.org/post_images/9a2/a8d/7af/9a2a8d7af82d9d6d258d2d40ab8c1eeb.jpg
[19] Image: http://habr.habrastorage.org/post_images/173/cd5/4d7/173cd54d7a8e12cf0d40c3bc0f3a784e.jpg
[20] Image: http://habr.habrastorage.org/post_images/978/58b/c6c/97858bc6c7dcefed0a641b65e47019db.jpg
[21] Image: http://habr.habrastorage.org/post_images/e7a/113/3ec/e7a1133ec9db5d0867ac6a627d2c39da.jpg
[22] Image: http://habr.habrastorage.org/post_images/f27/967/626/f279676263da90c01b78456c25ef3b3c.jpg
[23] Image: http://habr.habrastorage.org/post_images/81d/961/1dd/81d9611dde9d385c6b5702764e2cd168.jpg
[24] Image: http://habr.habrastorage.org/post_images/743/eb8/e43/743eb8e4306e937202b91a8cfae7fb82.png
[25] Image: http://habr.habrastorage.org/post_images/478/2c5/598/4782c5598558c05bb6df803d5e616913.png
[26] Image: http://habr.habrastorage.org/post_images/df2/964/def/df2964defe0e1477820fa1284efaee1f.jpg
[27] лаборатории: https://rts.samsungdforum.com
[28] Image: http://habr.habrastorage.org/post_images/af4/2f9/92e/af42f992ed634d547a406ddee99f9f37.jpg
[29] Image: http://habr.habrastorage.org/post_images/92a/393/612/92a3936121e54624d81b8e9bc25e4b9e.jpg
[30] Image: http://www.kinopoisk.ru/film/602727/
[31] http://paunin.com/content/demoApp/index.html: http://paunin.com/content/demoApp/index.html
[32] demo/demoApp
: https://github.com/immosmart/smartbox/tree/master/demo/demoApp
[33] http://immosmart.github.io/smartbox/demo/demoApp/: http://immosmart.github.io/smartbox/demo/demoApp/
[34] http://samsungdforum.com/: http://samsungdforum.com/
[35] http://paunin.com/content/lg_drm.zip: http://paunin.com/content/lg_drm.zip
[36] http://goo.gl/o93keD: http://goo.gl/o93keD
[37] http://82.146.41.200/widgetlist.xml: http://82.146.41.200/widgetlist.xml
[38] http://paunin.com/content/smartbox.zip: http://paunin.com/content/smartbox.zip
[39] странице разработчика: http://developer.lge.com/apptest/retrieveApptestReg.dev
[40] Image: http://habr.habrastorage.org/post_images/fc8/9aa/063/fc89aa063d5a1c473c4254ec81c83eb3.png
[41] Image: http://habr.habrastorage.org/post_images/6de/06e/2b2/6de06e2b21f6ca1740813d0afa736027.png
[42] http://paunin.com/content/demoApp/philips.php: http://paunin.com/content/demoApp/philips.php
[43] http://goo.gl/: http://goo.gl/
[44] готовое приложение: http://paunin.com/content/demoApp/
[45] Полная дока: http://www.samsungdforum.com/Guide/art00011/index.html
[46] (с) Документация по навигации: https://github.com/immosmart/smartbox/blob/master/docs/ru_nav.md
[47] js/app.js
: https://github.com/immosmart/smartbox/blob/master/demo/demoApp/js/app.js
[48] js/legendTriggers.js
: https://github.com/immosmart/smartbox/blob/master/demo/demoApp/js/legendTriggers.js
[49] Документация по плееру: https://github.com/immosmart/smartbox/blob/master/docs/ru_player.md
[50] Документация по клавиатуре: https://github.com/immosmart/smartbox/blob/master/docs/ru_keyboard.md
[51] Samsung: http://www.samsungdforum.com
[52] LG: http://developer.lge.com/main/Intro.dev
[53] Philips: http://www.yourappontv.com/home
[54] Zmeeed: http://habrahabr.ru/users/zmeeed/
[55] PLoginoff: http://habrahabr.ru/users/ploginoff/
[56] melkov: http://habrahabr.ru/users/melkov/
[57] Таск трекер: https://github.com/immosmart/smartbox/issues
[58] Источник: http://habrahabr.ru/post/188294/
Нажмите здесь для печати.