xaker

Знакомимся с особенностями разработки под Smart TV и учимся делать приложение для телевизора

  • понедельник, 27 октября 2014 г. в 02:11:04

Разговоры про Smart TV в последнее время участились, продаются умные телевизоры чаще, чем обычные, их аудитория постоянно растет, но вот магазины приложений пустуют. Почему так? Ведь, казалось бы, разработка под Smart TV не отличается от front-end’а: привычные JavaScript, HTML, CSS и браузер. Все дело в том, что кодинг под Smart TV имеет свои специфические особенности, о которых лучше знать еще при проектировании приложения.

Что такое Smart TV и зачем нужны приложения в телевизорах?

Представь, что ты заходишь на кухню. Холодильник сообщает, что можно приготовить из имеющихся продуктов, а затем перекидывает выбранный рецепт на мультиварку. Безумие? Таким же безумием казались приложения в телевизорах еще лет двадцать назад.

Что же такое Smart TV? Это интернет и интерактивные сервисы в телевизоре или телевизионном ресивере, или, вкратце, компьютер в форм-факторе «зомбоящика». Первую попытку реализовать подобие Smart TV предприняла компания Microsoft в далеком 1997 году, но идея провалилась из-за dial-up-соединения и CRT-телевизоров. Позднее возник другой способ сделать телевизор «умным»: в 2000 году стали появляться устройства Set Top Box (STB) различных производителей, расширяющие функционал стандартного (кабельного, спутникового) ТВ. STB — это обычная телевизионная приставка, принимающая сигнал цифрового телевидения, декодирующая и преобразующая его в аналоговый сигнал для вывода через разъемы RCA или SCART либо выводящая сигнал через разъем HDMI на телевизор. Но с ростом скорости соединения и новыми технологиями экранов стали появляться телевизоры со встроенным функционалом Smart TV, и с 2009 года началась сертификация таких устройств. В настоящий момент технология Smart TV внедряется в различные устройства: телевизоры, ресиверы цифрового телевидения, Blu-ray-проигрыватели, игровые консоли и аналогичные им девайсы.

Приложения умного ТВ позволяют просматривать различный видеоконтент: фильмы, сериалы, записи и трансляции передач и спортивных событий, музыкальные клипы, видеоролики; дают возможность читать новости, просматривать социальные сети и общаться по Skype или другому VoIP. Существуют развивающие приложения для детей и игры.

AuraInt 3

Если ты знаком с front-end-разработкой, то уже можешь приступать к созданию приложения, ничего нового учить не придется. Правда, необходимо учитывать особенности телевизоров:

  • Если планируешь разработку для моделей 2011 года и старше, то не рассчитывай на помощь CSS3. Вспоминай, как делать спрайты, и приготовься к интересным особенностям CSS, которые не встречаются в браузерах на компьютере и редко поддаются логичному объяснению.
  • Мощность вычислительного модуля телевизора в разы слабее компьютера, не удивляйся, что анимации в старых моделях будут отнюдь не плавными, а при измерении скорости исполнения кода окажется, что он в десятки и сотни раз медленнее, чем в браузере.
  • Слабая документация у некоторых производителей, а иногда и полное ее отсутствие могут привести тебя в отчаяние и заставят проводить часы на форумах разработчиков.
  • Для тестирования придется использовать реальные телевизоры. Эмуляторы не повторяют полного функционала устройств и часто содержат свои собственные, не возникающие на реальных устройствах баги.
  • В телевизорах полностью отсутствуют средства отладки, придется использовать свои «велосипеды» при разработке.
  • Непривычное взаимодействие пользователя с приложением. Учитывай, что, скорее всего, передвигаться по приложению тебе придется с помощью одного пальца руки, нажимая на кнопки пульта управления (правда, можно еще управлять голосом, жестами и гироскопическим пультом, как, например, у LG, но такое встречается далеко не во всех моделях и не у каждого производителя). На этапе проектирования приложения необходимо учитывать не только навигацию внутри приложения, но и ввод данных в инпуты.
  • Необходимо прорабатывать ситуацию потери соединения. Небольшая подсказка: тестировщики Samsung в процессе премодерации для своего магазина любят при проигрывании видео отключить сетевой кабель из разъема и смотреть, как эта ситуация отрабатывается в приложении :).
  • Разнообразие JavaScript API платформ усложнит кросс-платформенную разработку в разы, каждый производитель предоставляет свой API для взаимодействия с внутренним функционалом (проигрывание видео, отображение клавиатуры и прочее).

Ниже краткое описание популярных платформ, чтобы ты знал, с чем придется работать.

Samsung

Сайт для разработчиков

Samsung сейчас занимает наибольшую долю среди всех телевизоров с поддержкой технологии Smart TV. В моделях 2010 и 2011 года в качестве движка браузера используется MAPLE — сильно измененная версия Gecko, который был в Firefox 3.0. К счастью разработчиков, компания отказалась продолжать изобретать свой велосипед и с 2012 года в телевизорах Samsung Smart TV используется WebKit.

Помимо управления с пульта ДУ, в этой платформе можно использовать управление голосом и жестами (начиная с моделей 2012 года), а также подключать привычную мышь и клавиатуру.

Для разработчиков Samsung предоставляет SDK с эмуляторами и своей средой разработки на базе Eclipse. На сайте есть документация с множеством примеров и возможность удаленного тестирования на реальных устройствах модельного ряда 2013-го и выпущенных позднее (очень полезная для тестирования возможность). Есть недокументированный функционал, поэтому ответ порой придется искать на форуме, к счастью русскоязычном.

Ключевые возможности API: управление звуком из приложения, получение данных сети и модели, широкие возможности управления плеером.

samsung 

LG

Сайт для разработчиков

Отличительная черта этой платформы — возможность использовать Magic Remote, гироскопический анатомический пульт управления. Движение пульта в пространстве сопровождается движением курсора на экране, что очень сильно упрощает навигацию внутри приложений.

Из других способов управления — многокнопочный пульт и распознавание голоса. Во всех моделях LG Smart TV используется WebKit, что значительно сокращает количество «специфичных» багов.

LG предоставляет для разработчиков подробную документацию и SDK с эмуляторами и средой разработки, построенной на основе Eclipse. У платформы LG есть еще одна особенность — приложение необходимо зашифровать на сайте перед выгрузкой на устройство.

Компания LG является учредителем Smart TV Alliance — это проект, созданный в 2012 году совместными усилиями с TP Vision (компанией, производящей телевизоры под брендом Philips) в целях создания унифицированной платформы приложений для умных телевизоров.

untitled 

Philips

Сайт для разработчика

Достаточно своеобразная платформа. Вторая по объемам продаж в России, но, несмотря на это, разработка для Philips конкретно прокачивает навыки логического мышления, так как документация невероятно скудная :).

Вот что известно про эту платформу:

  • До моделей 2012 года вместо HTML необходимо было использовать CE-HTML (специально разработанный стандарт для телевизоров и мобильных устройств на основе XHTML).
  • Нет структурированной документации, зато есть примеры и немного статей, из которых можно крупицами собирать информацию.
  • Очень плохой эмулятор и отсутствие возможности запустить приложение полноценно в телевизоре. Для тестирования приходится открывать приложение во встроенном в устройство браузере.

40PFL8007T_12_smarty+ 

Разработка кросс-платформенного приложения при помощи Smartbox

Как ты понял, в разработке приложения для Smart TV очень много особенностей. Недолго думая, мы с командой решили создать библиотеку, основываясь на опыте кросс-платформенной разработки для умных телевизоров. Вот список того, чем наши наработки могут упростить тебе жизнь:

  • возможность написать абстрактный код, основываясь на API библиотеки, а не каждого TV или приставки;
  • добавление новой поддерживаемой платформы без изменения кода самого приложения;
  • плагин навигации, позволяющий переключать фокус внутри приложения без лишних проблем;
  • инпуты и виртуальная мультиязычная клавиатура;
  • плагин для использования возможности управления голосом;
  • плагин легенды (подсказки по клавишам внизу экрана);
  • абстракция LocalStorage — хранение данных на конечных устройствах;
  • абстракция над функциями плеера;
  • удобная замена console.log в телевизоре.

На данный момент библиотека позволяет запускать приложение на трех мажорных платформах:

  • Samsung;
  • LG;
  • Philips.

Кроме того, Smartbox без проблем запускается и на приставке STB Mag 200/250.

INFO

Добавить новую платформу в Smartbox не составит труда, в репозитории ты сможешь найти документацию, как это сделать. Код библиотеки мы выложили на GitHub.

LET’S GO!

Но довольно теории, давай попробуем написать кросс-платформенное приложение для ТВ, используя Smartbox. Наше приложение будет иметь меню, список видео из внешнего файла, демонстрацию навигации и примеры полей ввода с виртуальной клавиатурой. Приложение будет в трендовом Flat-дизайне.

demo

Накидаем HTML для меню:

<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>

Самое важное, что стоит тут отметить, — атрибуты data-* и класс nav-item. Атрибут data-nav_type="vbox" служит для оптимизации навигации, при его использовании фокус начинает перемещаться от одного sibling-элемента к другому. Атрибут data-nav_loop="true"позволяет зацикливать навигацию в рамках своего элемента. Все видимые элементы с классом nav-item могут получить на себя фокус и позже инициировать события (focus, click, etc). Атрибут data-content будем использовать для отображения сцен приложения.

Добавим HTML для сцен.

<div class="scenes-wrapper">
  <!—- Список видео будем генерировать из внешнего файла -->
  <div class="scene scene_video js-scene-video" data-nav_type="vbox" data-nav_loop="true"></div>

  <!—- Сцена для демонстрации инпутов -->
  <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>

  <!—- Сцена для демонстрации навигации -->
  <div class="scene js-scene-navigation">
    <ul class="navigation-items">
      <li class="navigation-item nav-item">1</li>
      //...
      <li class="navigation-item nav-item">8</li>
    </ul>
    <p class="navigation-info"></p>
  </div>
</div>

Теперь HTML нашего приложения готов, приступим к написанию главного JS-файла приложения app.js. После инициализации самого Smartbox происходит старт приложения.

  //     SB() — главная функция Smartbox, вызывается после инициализации всех плагинов и запуска платформы
  SB(function(){
        App.initialize();
    });

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

App.initialize = function () {
  this.$wrap = $('.wrap');

  // Показываем легенду
  $$legend.show();

  this.setEvents();

  // Запускаем навигацию (в фокусе будет первый видимый элемент с классом nav-item)
  $$nav.on();
};

App.setEvents = function () {
  var self = this;

  // Отображаем сцену при клике на элементе меню
  $('.menu').on('click', '.menu-item', function ( e ) {

    // Именно здесь и нужен атрибут data-content
    var scene = e.currentTarget.getAttribute('data-content');
    self.showContent(scene);
  });

  $(document.body).on({
    // Скрываем/отображаем интерфейс при клике по синей кнопке пульта или клавише D на клавиатуре
    'nav_key:blue': function() {
      self.toggleView();
        },
    // remote events
    'nav_key:stop': function () {
      Player.stop();
    },
    'nav_key:pause': function () {
      Player.togglePause();
    },
    'nav_key:exit': function(){
      SB.exit();
    }
  });
};

Метод showContent будет скрывать текущую сцену и отображать новую. Каждая сцена будет иметь три метода — init для разовой инициализации и show/hide для управления отображением. Реализация методов отображения будет одинаковой во всех сценах:

show: function () {
  if (!_inited) {
    // Отложенная инициализация сцены
    this.init();
    _inited = true;
  }
  this.$el.show();
},
hide: function () {
  this.$el.hide();
}

Ну а теперь приступаем к реализации сцен, я буду приводить код без методов show/hide. Но для начала вынесем список видео в отдельный файл:

window.App.videos = [
  {
      title: 'Elephants Dream',
      url: 'https://archive.org/download/ElephantsDream/ed_1024_512kb.mp4',
      type: 'vod'
  },
  {
      title: 'Redbull',
      url: 'http://live.iphone.redbull.de.edgesuite.net/webtvHD.m3u8',
      type: 'hls'
  },
  //...
];

Можно приступать к реализации сцены со списком видео.

Сцена со списком видео

Сцена со списком видео

init: function () {
  // В this.$el сохраняем элемент сцены 
  this.$el = $('.js-scene-video');

  // Устанавливаем обработчик для клика по элементу списка
  this.$el.on('click', '.video-item', this.onItemClick);


  this.renderItems(App.videos);
},

// Генерация списка видео
renderItems: function (items) {
  var html = '',
      itemHtml = _.template('<div class="video-item nav-item">{{title}}</div>');

   // console.log(items, itemHtml.toString())
  for ( var i = 0, len = items.length; i < len; i++ ) {
    html += itemHtml(items[i]);
  }

  this.$el
    .empty()
    .html(html);
},

// Обработчик клика по элементу
onItemClick: function (e) {
  var index=$(e.currentTarget).index();

  // window.Player — плагин Smartbox. Видео запускается передачей объекта c URL и type в метод play
  Player.play(App.videos[index]);
},

Сцена со списком готова, можно запускать видео и добавлять новые элементы. Создадим возможность использовать инпуты в Smart TV, в методе init сцены с полями ввода впишем код:

init: function () {
  this.$el = $('.js-scene-input');

  var $valueText = this.$el.find('.js-input-1-val');

  this.$el.find('.js-input-1')
    // text_change — событие плагина SBInput, вызывается при изменении текста инпута
    .on('text_change',function () {
      $valueText.html(this.value);
    })
    // Плагин SBInput — обычный плагин jQuery
    .SBInput({
      keyboard: {
        // Для первого инпута клавиатура будет русская с возможностью отображения цифр
        type: 'fulltext_ru_nums'
      }
    });

  this.$el.find('.js-input-2').SBInput({
    keyboard: {
      // Специальный layout клавиатуры для ввода электронной почты
      type: 'email'
    }
  });

  this.$el.find('.js-input-3').SBInput({
    keyboard: {
      // layout только с девятью цифрами
      type: 'num'
    },
    // Максимальное количество символов в инпуте
    max: 4
  });
}
input

Сцена с инпутами и виртуальной клавиатурой

Теперь можно вводить данные в поля ввода, отображать и скрывать клавиатуру. Остается добавить код для сцены с примером навигации. На элементе с классом nav-item вызывается событие nav_focus при попадании фокуса на него и nav_blur при потере фокуса. Добавим обработчики для этих событий в сцене.

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('');
        }
      });
}
Сцена с примером навигации

Сцена с примером навигации

Основной код для сцен готов, приложение функционирует, остается только добавить подсказки для клавиш в плагине легенды. Все возможные кнопки в легенде представлены на рис. 1, а пользоваться клавишами несложно:

$('.menu-item').on({
  'nav_focus': function () {
    // Отображаем в легенде Enter 
    $$legend.keys.enter('Show content')
  },
  'nav_blur': function () {
    // Скрываем Enter из легенды
    $$legend.keys.enter('')
  }
});
Рис. 1. Возможные подсказки плагина легенды

Рис. 1. Возможные подсказки плагина легенды

Готовый код приложения ты можешь найти тут. Также можешь посмотреть на приложение в действии. В браузере навигация осуществляется с помощью мыши или стрелок клавиатуры, а кнопки пульта RED, YELLOW, GREEN, BLUE заменяются на клавиши A, B, C, D.

Заключение

Теперь ты подготовлен к встрече со Smart TV в боевых условиях разработки. Надеюсь, наша библиотека поможет избежать хождения по граблям и ты сможешь быстро разработать и выложить свое творение в магазин приложений на телевизорах.

Если хочешь поучаствовать в разработке Smartbox — мы всегда рады pull request’ам на GitHub. А если возникли вопросы по разработке под Smart TV — пиши мне.

Хороших идей и отличных приложений!