Qik Push Engine API: приглашаем разработчиков

qik_logo Qik - это сервис стриминга (вещания) и загрузки видео с мобильных телефонов. Загруженное видео можно посмотреть на сайте или на его специальной версии с мобильного телефона. Доступна интеграция с другими сервисами, такими как Twitter, Facebook и другие. Клиенты для практически всех современных моделей телефонов: iPhone, Windows Mobile, Symbian, Android, Blackberry и другие.

Qik Push Engine - это механизм, который позволяет получать мгновенные оповещения о новых/изменившихся Qik-видео. Например, можно посмотреть постоянно обновляющийся список live-видео, все видео из района Новопеределкино или все видео со словом "кошка". На основе Qik Push Engine API можно построить интересные приложения, интегрированные с Qik, или добавить функциональность в уже существующие. Можно написать собственную систему нотификации, desktop-widget

или что-то еще.

Сегодня мы открываем API для работы c Qik Push Engine. Это первая ласточка в большом списке API, открывающих доступ к платформе стриминга Qik. Если вам интересно посмотреть Qik Push Engine в действии, заходите на одну из страниц примеров.

Основы работы с API

Qik Push Engine API доступно в виде набора удаленных процедур по протоколу JSON-RPC (over HTTP). В ближайшее время будет открыт REST-подобный интерфейс. Точкой входа для JSON-RPC является http://engine.qik.com/api/jsonrpc. Пока проект находится в закрытом бета-тестировании для доступа к API необходимо указать ключ разработчика, добавив параметр apikey: http://engine.qik.com/api/jsonrpc?apikey=xxxxxxx. Ключ разработчика можно получить, отправив письмо с запросом на api@qik.com.

Пример HTTP-сессии:


POST /api/jsonrpc

Host : engine.stage.qik.com

Content-Type:  application/json; charset=UTF-8

Content-Length: 46



{"method": "qik.session.create", "params": []}

Ответ:


Content-Type: text/json 



["a56c1603-1fbb-4140-8b35-8c36abbd8b27"]

Пример подписки на поток событий

Здесь и далее я буду использовать простую запись вызова команд, которая похожа на вызов обычных функций, опуская детали JSON-RPC взаимодействия. Итак, пусть мы хотим подписаться на список всех live-стримов, которые есть данный момент.

Первым делом создадим сессию:


qik.session.create() -> "a56c1603-1fbb-4140-8b35-8c36abbd8b27"

Подписываемся в рамках сессии на view всех публичных live-стримов, при этом указываем максимальное количество элементов во view (limit). Элементы view будут упорядочены в порядке убывания даты начала стрима (самые новые первыми):


qik.stream.subscribe\_public_live("a56c1603-1fbb-4140-8b35-8c36abbd8b27", 10) -> 
 [ "174/('PublicLiveStreamView', 'Stream', [('stoptime', None)], 'alllive;limit=10')", [ ... ] ]

В ответ на запрос мы получаем массив из двух элементов: первым является ключ подписки (длинная строка, начинающаяся с "174/.."). Не ищите смысла в ключе подписки, его необходимо просто сохранить, он потребуется в дальнейшем.

Вторым элементом является начальное состояние view, то есть текущий список live-стримов в нашем случае. Мы получим не больше 10 элементов (так как указали limit 10 при вызове метода qik.stream.subscribe_public_live). Состояние view выглядит примерно следующим образом:


[
   {"url": "http://qik.com/video/2158468", 
    "live": true, 
    "user_id": 340699, 
    "small_thumbnail_url": "http://media.qik.com/media.thumbnails.128/c8ad8fe065ad4ad7ac8491874c043eac.jpg", 
    "title": "Untitled", "duration": 0,
    "created_at": "2009-07-11 15:56:03", 
    "views": 0, 
    "id": 2158468}, 

   {"url": "http://qik.com/video/2158466", 
    "live": true, 
    "user_id": 340119, 
    "small_thumbnail_url": "http://media.qik.com/media.thumbnails.128/984c33e1ead441038f315e1fff109fc5.jpg", 
     "title": "Testando!", 
     "duration": 0, "created_at": "2009-07-11 15:55:34", 
     "views": 0, 
     "id": 2158466}
]

Смысл большинства полей очевиден, приведу лишь некоторые комментарии:

  • все даты приведены в UTC;
  • поле duration хранит длительность видео в секундах.

Так как мы подписались на live-стримы, у всех видео live == true.

Теперь нам необходимо получать новые события для тех view, на которые мы подписались. Для этого используются HTTP long polling-запросы. Клиент отправляет запрос серверу, а сервер отправляет ответ, когда появляются события или когда истечет таймаут, если событий не появилось.

Для реализации long polling в цикле вызываем метод qik.session.get_events, указывая желаемый таймаут (не рекомендуется использовать таймаут более 90 секунд).


qik.session.get_events("a56c1603-1fbb-4140-8b35-8c36abbd8b27", 60) -> 
  [ {...} ,{...} ]

В ответ мы можем получить пустой массив событий, если истек таймаут, или некоторый набор событий следующего вида:


[
   {
     "action": "update", 
     "old": {"id": 104252, "title": "Untitled", "views": 0, ...}, 
     "obj": {"id": 104252, "title": "driving to key largo", "views": 5, ...}, 
     "key": "175/('PublicRecentStreamView', 'Stream', [], 'allrecent;limit=50')"
    },
] 

В каждом событии обязательно передается следующая инормация:

  • key - ключ подписки, это то же самое значение, которое мы получили при подписке на view, ключ позволяет отличать события для разных view в рамках одной сессии;
  • action - действие (изменение), произошедшее с view:
    • ping - ничего не произошло, просто view сообщает, что все хорошо :)
    • update - элемент view изменился (как в примере выше), передается старое и новое состояние объекта в полях old и obj
    • insert - во view добавился новый элемент, его состояние будет записано в поле obj
    • delete - элемент исчез из view (может быть, видео было удалено, или просто перестало удовлетворять критериям view, или ушло за границу "limit"), последнее состояние объекта будет записано в поле obj.

В ответ на события мы можем обновить информацию на экране для пользователя, выполнить какие-либо еще действия. Но обязательно надо отправить новый запрос qik.session.get_events, чтобы получить новые события.

В конце работы не забываем "убраться" за собой, убиваем сессию:


qik.session.destroy("a56c1603-1fbb-4140-8b35-8c36abbd8b27") 

Замечания:

  • В рамках одной сессии можно подписаться на произвольное количество view.
  • Если это необходимо, можно авторизовать сессию от имени пользователя с помощью qik.session.authorize.
  • Существует большое количество вспомогательных запросов, которым сессия вообще не требуется, например qik.user.public_profile.
  • Можно отписаться от view при помощи конмадыqik.session.unsubscribe.

Reference JS-клиент

Для демонстрации возможностей Qik Push Engine и проверки его работы был реализован легкий JavaScript-клиент. Его можно увидеть в работе на примерах, полный список которых приведен ниже.

Если вы запустите пример в Firefox с включенным Firebug, в консоли Firebug будет появляться подробная информация о выполняемых запросах к Qik Push Engine API, полученных ответах и т.п.

Исходный код клиента доступен в необфусцированном виде, со всеми комментариями. Код предоставляет по принципам public domain, то есть можете делать с ним все, что захотите - использовать в своих приложениях, модифицировать, переписывать на другие языкаи программирования и т.п.

Пробежимся быстро по компонентам JS-клиента.

prototype.js

Совершенно стандартный Prototype, ничего интересного.

deferred.js

Deferred - это одна из основных концепций Twisted Framework (http://twistedmatrix.com). Deferred не является обязательным для взаимодействия с Qik Push Engine API, но позволяет сильно упростить сложные взаимодействия в асинхронном коде.

В качестве дополнительного материала о Deferred можно почитать про основы работы с Deferred, более сложные случаи использования Deferred, данную реализацию Deferred для Prototype, а также взглянуть на Deferred в других JS-фреймворках: MochiKit, Dojo.

DeferredManager - простая конструкция на основе Deferred, позволяет запускать не более N асинхронных действий в один момент времени.

core.js

Ядро клиента, объявляется namespace QikEngine, отладочные функции, определение конфигурации, создания объекта для доступа к API и т.п.

api.js

QikEngine.API - простая обертка JSON-RPC API Qik Push Engine, возвращающая Deferred в качестве результата любого обращения к API. Через Deferred же отправляются ошибки и результаты выполнения методов.

QikEngine.Session - класс, оборачивающий понятие сессии, создание, уничтожение, авторизация в рамках сессии.

events.js

QikEngine.Events - получение новых событий с помощью HTTP long polling, технология, похожая на BOSH/Comet. Распределение событий подписчикам (конкретным view).

view.js

QikEngine.View - абстрактный класс, представляющий view на стороне клиента. Обслуживание обновлений, отображение в элементах HTML, обработка событий и т.п. Списки элементов хранятся прямо в DOM-контейнере в виде HTML-узлов.

Потомки QikEngine.View для реализации конкретных view: QikEngine.PublicUserStreamView, QikEngine.PublicRecentStreamsView и т.д.

updater.js

Очень простой интерфейс между данными, полученными из Qik Push Engine (например, информацией о стримах) и HTML-элементами. Адаптация данных, например, перевод дат из UTC в локальный формат, форматирование значений и т.п.

usercache.js

QikEngine.UserCache - механизм загрузки информации о пользователях (по их ID). Использует DeferredManager для ограничения количества параллельных запросов.

Что делать дальше?

  • смотрите описание API;
  • пишите письмо на api@qik.com, расскажите о своем проекте и получайте ключ для доступа к API.

Полный список примеров

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

Comments

Comments powered by Disqus
Contents © 2015 Andrey - Powered by Nikola