Changes

Jump to: navigation, search

Engine API

28,471 bytes added, 19:22, 8 February 2013
no edit summary
<tt>>>SHUTDOWN
<<SHUTDOWN</tt>
 
----
----
----
==Общие понятия==
ACE Stream Engine (далее - "движок") - приложение, которое обеспечивает весь функционал системы ACE Stream. Данное приложение работает в фоновом режиме и имеет минимальный графический интерфейс для
 
изменения различных настроек.
 
ACE Stream Engine API (далее - API) - программный интерфейс, позволяющий сторонним приложениям работать с движком. Под сторонними приложениями, как правило, подразумеваются медиа плееры, работающе
 
с системой ACE Stream.
 
Клиент - стороннее приложение, которое работает с движком посредством API.
 
==Схема работы API==
Обмен данными с движком происходит по протоколу TCP. Общая схема работы выглядит так:
* клиент устанавливает TCP-соединение с движком
* клиент и движок обмениваются рукопожатиями
* клиент и движок обмениваются сообщениями
* одна из сторон завершает соединение
 
===Установление соединения===
Для установления соединения клиент должен знать порт, на котором работает API движка. Методы определения порта зависят от операционной системы, на которой запущен движок.
 
На Linux используется фиксированный порт: 62062
 
На Windows используется динамический порт. Движок после запуска создает файл acestream.port в директории, в которой находится сам движок (файл tsengine.exe), и записывает в данный файл порт, на
 
котором работает API. Для того, чтобы узнать порт, клиент должен прочитать указанный файл. Отсутствие данного файла указывает на то, что движок в не запущен. Путь к папке, в которую устанавливается
 
движок, можно считать из реестра:
HKEY_CURRENT_USER\Software\TorrentStream\EnginePath
Ключ EnginePath содержит абсолютный путь к исполняемому файлу движка (tsengine.exe). По умолчанию это %APPDATA%\TorrentStream\engine\tsengine.exe
 
Алгоритм установления соединения (Windows):
# считать из реестра ключ <tt>HKEY_CURRENT_USER\Software\TorrentStream\EnginePath</tt>
## если ключ отсутствует - движок не установлен
## запомнить путь к исполняемому файлу движка (engine_path) и директории движка (engine_dir)
# считать содержимое файла engine_dir/acestream.port и запомнить порт
# если данный файл отсутствует - запустить движок, дождаться создания файла acestream.port и считать его содержимое
# установить TCP-соединение на localhost на указанный порт
# если не получилось установить соединение - движок не запущен и его нужно запустить
# обменяться рукопожатием и начать обмен сообщениями
 
Алгоритм установления соединения (Linux):
# установить TCP-соединение на localhost на порт 62062
# если не получилось установить соединение - движок не запущен и его нужно запустить (<tt>/usr/bin/acestreamengine-client-gtk</tt>)
# обменяться рукопожатием и начать обмен сообщениями
 
===Рукопожатие===
После установления соединения клиент и движок должны обменяться рукопожатием:
* клиент отсылает сообщение
HELLOBG version=<api_version>
* движок отсылает в ответ
HELLOTS version=<engine_version>
 
Каждое сообщение должна завершаться символами перевода строки CRLF (\r\n)
 
;<api_version>
: версия API, которую поддерживает клиент. Этот параметр служит для поддержки обратной совместимости новых версий движка со старыми клиентами. Текущая версия API - 3. Если клиент не указал версию,
 
по умолчанию используется версия 1. Для всех сообщений API в документации указано, начиная с какой версии они поддерживаются.
;<engine_version>
: версия движка (например, 2.0.8)
 
Если клиент в течение некоторого времени после отправки рукопожатия не получил ответ, соединение необходимо завершить.
 
===Обмен сообщениями===
Каждое сообщение представляет собой ASCII-строку, которая завершается символами перевода строки CRLF (\r\n)
 
Примерный алгоритм приема сообщений выглядит таким образом:
* клиент в цикле ждет поступления данных по TCP-соединению
* при получении данных они добавляются в буфер
* клиент проверяет, есть ли в буфере символы CRLF. Если есть, то из буфера вырезается сообщение (строка от начала буфера до символов CRLF) и отправляется в обработчик сообщений
* клиент должен учитывать возможность получения нескольких сообщений одновременно (т.е. повторять предыдущий шаг, пока в буфере не будет символов CRLF)
 
===Завершение соединения
Движок при завершении работы отправляет команду <tt>SHUTDOWN</tt> и закрывает сокет. При получении данной команды клиент должен прекратить обработку команд и закрыть свой сокет.
 
То же самое должен делаь клиент при закрытии - перед закрытием отослать движку команду <tt>SHUTDOWN</tt>
 
==Сообщения==
 
===Типы сообщений===
Все сообщения условно делятся на две группы: команды и события.
 
Команды подразумевают выполнение какого-либо действия от принимающей стороны. Например, командой <tt>START</tt> клиент просит движок начать пребуферизацию указанного контента.
 
События носят информационный характер. Например, событие <tt>STATUS</tt> информирует клиента о статусе загрузки (идет ли в данный момент пребуферизация, буферизация, какая скорость загрузки и т.д.)
 
===Синхронные команды===
Практически все команды являются асинхронными, т.е. не предполагают наличие ответа от другой стороны.
 
Исключением являются две команды:
* <tt>LOAD</tt> (сихронная загрузка информации о потоке)
* <tt>GETCID</tt> (получение Content ID для потока)
 
Для этих команд есть понятие ответа на команду. Ответ передается в виде строки, которая начинается на ##.
 
Алгоритм обработки синхронных команд такой:
* клиент отправляет движку синхронную команду (например, <tt>GETCID 4c78e1cf0df23b4f5a16a106829ebed710cb52e0 0 0 0</tt>) и ждет данных от движка
* когда от движка приходят данные, клиент проверяет, начинается ли полученный ответ на ## (например, <tt>##36ae4c89ab45b4010b1461c513da38d007356195</tt>)
* если это так, то строка от символов ## до CRLF является ответом на синхронную команду (причем ответ может быть пустой, т.е. выглядеть так: <tt>##</tt>)
* если нет, значит ответ на команду не может быть получен
 
Мы не рекомендуем использовать синхронную команду <tt>LOAD</tt>, так как она подразумевает блокирование потока на стороне клиента. Эта команда является устаревшей и вместо нее следует использовать
 
асинхронную версию <tt>LOADASYNC</tt>
 
Ответ на команду <tt>GETCID</tt> приходит практически мгновенно, поэтому ее использование не приводит к блокированию. Однако есть одно замечание по использованию данной команды:
Команду <tt>GETCID</tt> не следует отправлять, если движок находится в состоянии <tt>starting</tt>
 
===Список сообщений===
В примерах сообщения от клиента к движку отмечены >>, от движка к клиенту - <<
 
====Команды от клиента к движку====
 
=====<tt style="color: #009;">READY</tt>=====
;Версия API
:>= 1
 
;Описание
:Информирует движок о том, что клиент готов принимать команды. Это должна быть первая команда после рукопожатия.
 
;Синтаксис
<tt>READY</tt>
 
;Параметры
:нет
 
;Пример:
<tt><nowiki>>>READY</nowiki></tt>
 
=====<tt style="color: #009;">LOADASYNC</tt>=====
;Версия API
:>= 1
 
;Описание
:Получить описание контента по идентификатору. Идентификатором может быть content id, ссылка на транспортный файл (.torrent, .acelive), инфохеш транспортного файла и т.п. Описание представляет
 
собой список названий файлов либо потоков, которые содержатся в транспортном файле. Основное назначение этой команды - возможность сформировать и показать пользователю плейлист.
 
;Синтаксис
<tt>LOADASYNC ''request_id'' TORRENT ''url'' ''developer_id'' ''affiliate_id'' ''zone_id''
LOADASYNC ''request_id'' INFOHASH ''infohash'' ''developer_id'' ''affiliate_id'' ''zone_id''
LOADASYNC ''request_id'' RAW ''data'' ''developer_id'' ''affiliate_id'' ''zone_id''
LOADASYNC ''request_id'' PID ''content_id''</tt>
 
;Параметры
* <tt>''request_id''</tt>: случайное целое число - идентификатор запроса LOADASYNC; этот же идентификатор будет отослан клиенту в команде LOADRESP после того,как будет получен список файлов; данный
 
идентификатор служит для того, чтобы клиент в случае отправки нескольких запросов LOADASYNC точно знал, на какой из этих запросов получен ответ
* <tt>''url''</tt>: ссылка на транспортный файл
* <tt>''infohash''</tt>: инфохеш транспортного файла
* <tt>''data''</tt>: содержимое транспортного файла в кодировке base64
* <tt>''content_id''</tt>: идентификатор контента в системе ACE Stream (Content ID)
* <tt>''developer_id''</tt>: код разработчика (если неизвестно, необходимо передавать 0)
* <tt>''affiliate_id''</tt>: код партнера (если неизвестно, необходимо передавать 0)
* <tt>''zone_id''</tt>: код зоны партнера (если неизвестно, необходимо передавать 0)
 
;Формат ответа
:Ответ приходит в формате JSON со следующими полями:
* <tt>''status''</tt>:
** 0 - транспортный файл не содержит аудио/видео файлов
** 1 - транспортный файл содержит один аудио/видео файл
** 2 - транспортный файл содержит более одного аудио/видео файла
** 100 - ошибка получения данных
* <tt>''files''</tt>: список файлов/потоков; это массив, каждый элемент в котором состоит из массива из двух элементов: первый - название файла, второй - позиция в транспортном файле (эта позиция
 
должна отправляться в команде <tt>START</tt> для указания, какой именно файл необходимо загружать, если их несколько)
* <tt>''infohash''</tt>: инфохеш транспортного файла
* <tt>''checksum''</tt>: хешсумма транспортного файла
 
:Параметры <tt>''infohash''</tt> и <tt>''checksum''</tt> клиенту нужны для того, чтобы в дальнейшем получить Content ID с помощью команды <tt>GETCID</tt>
 
:Названия файлов возвращаются в виде urlencoded строк в кодировке UTF-8
 
;Пример:
<tt><nowiki>>>LOADASYNC 12345 TORRENT http://rutor.org/download/67346 0 0 0
<<LOADRESP 12345 {"status": 1, "files": [["Prey%202_%20E3%202011%20Official%20Trailer_2.mp4", 0]], "infohash": "4c78e1cf0df23b4f5a16a106829ebed710cb52e0"}</nowiki></tt>
 
=====<tt style="color: #009;">START</tt>=====
;Версия API
:>= 1
 
;Описание
:Начать проигрывание указанного контента
 
;Синтаксис
<tt>START TORRENT ''url'' ''file_indexes'' ''developer_id'' ''affiliate_id'' ''zone_id'' ''stream_id''
START INFOHASH <infohash> <file_indexes> <developer_id> <affiliate_id> <zone_id>
START PID <content_id> <file_indexes>
START RAW <data> <file_indexes> <developer_id> <affiliate_id> <zone_id>
START URL ''direct_url'' <file_indexes> <developer_id> <affiliate_id> <zone_id>
START EFILE ''efile_url''</tt>
 
;Параметры
* <tt>''url''</tt>: ссылка на транспортный файл
* <tt>''infohash''</tt>: инфохеш транспортного файла
* <tt>''content_id''</tt>: идентификатор контента в системе ACE Stream (Content ID)
* <tt>''data''</tt>: содержимое транспортного файла в кодировке base64
* <tt>''direct_url''</tt>: прямая http-ссылка на контент (для проигрывания без транспортного файла)
* <tt>''efile_url''</tt>: ссылка на .acemedia файл
* <tt>''file_indexes''</tt>: список индексов файлов из торрент-файла, которые необходимо загружать. Индексы файлов клиент получает в сообщении LOADRESP разделенных запятой. Индексы начинаются с
 
нуля и соответствуют списку файлов, который был получен в результате выполнения команды LOAD. Например, если в торрент-файле всего один видео-файл, то необходимо отправлять индекс 0.
* <tt>''developer_id''</tt>:
* <tt>''affiliate_id''</tt>:
* <tt>''zone_id''</tt>:
* <tt>''stream_id''</tt>:
 
Если необходимо в параметрах передать ссылку на файл, который находится в локальной файловой системе, следует использовать формат file:///path/to/file.
 
;Примеры:
<tt><nowiki>>>START TORRENT http://rutor.org/download/67346 0 0 0 0
START PID xxxxxx 0
START EFILE file:///c:\acestream\test.acemedia
</nowiki></tt>
 
=====<tt style="color: #009;">STOP</tt>=====
;Версия API
:>= 1
 
;Описание
:Остановить воспроизведение и загрузку
 
;Синтаксис
<tt>STOP</tt>
 
;Параметры
:нет
 
;Пример:
<tt><nowiki>>>STOP</nowiki></tt>
 
=====<tt style="color: #009;">GETPID</tt>=====
;Версия API
:1
Эта команда устарела и больше не используется. Вместо нее следует использовать команду <tt>GETCID</tt>
 
=====<tt style="color: #009;">GETCID</tt>=====
;Версия API
:>= 2
 
;Описание
:Получение кода плеера по набору параметров. Эта команда является синхронной командой (см.ниже). В ответ отправляется код плеера, либо пустая строка, если код плеера не может быть получен
 
;Синтаксис
<tt>GETCID checksum=''checksum'' infohash=''infohash'' developer=''developer_id'' affiliate=''affiliate_id'' zone=''zone_id''</tt>
 
;Параметры
* <tt>''checksum''</tt>: хешсумма транспортного файла (значение клиент из команды LOADRESP)
* <tt>''infohash''</tt>: инфохеш транспортного файла (значение клиент из команды LOADRESP)
* <tt>''developer_id''</tt>: код разработчика (если неизвестно, необходимо передавать 0 либо не передавать данный параметр)
* <tt>''affiliate_id''</tt>: код партнера (если неизвестно, необходимо передавать 0 либо не передавать данный параметр)
* <tt>''zone_id''</tt>: код зоны партнера (если неизвестно, необходимо передавать 0 либо не передавать данный параметр)
 
;Пример:
<tt><nowiki>>>GETCID checksum=xxxxx infohash=xxxxx
<<##xxxxxxxxx</nowiki></tt>
 
=====<tt style="color: #009;">GETADURL</tt>=====
Описание скоро будет
 
=====<tt style="color: #009;">USERDATA</tt>=====
Описание скоро будет
 
=====<tt style="color: #009;">SAVE</tt>=====
Описание скоро будет
 
=====<tt style="color: #009;">LIVESEEK</tt>=====
Описание скоро будет
 
=====<tt style="color: #009;">SHUTDOWN</tt>=====
;Версия API
:>= 1
 
;Описание
:Клиент завершил работу
 
;Синтаксис
<tt>SHUTDOWN</tt>
 
;Параметры
:нет
 
;Пример:
<tt><nowiki>>>SHUTDOWN</nowiki></tt>
 
====Команды от движка к клиенту====
=====<tt style="color: #009;">PLAY, PLAYAD, PLAYADI</tt>=====
;Версия API
:1
Эти команды устарела и больше не используется. Вместо них следует использовать команду <tt>START</tt>
 
=====<tt style="color: #009;">START</tt>=====
;Версия API
:>= 2
 
;Описание
:Начать прогрывание контента. Эта команда отправляется после завершения пребуферизации. Движок отсылает плееру http-ссылку, по которой плеер может начать проигрывание контента. Данная ссылка
 
обрабатывается http-серверов, встроенным в движок.
 
;Синтаксис
<tt>START ''url'' [ad=1 [interruptible=1]] [pos=''position'']</tt>
 
;Параметры
* <tt>''url''</tt>: ссылка для проигрывания
* <tt>''ad=1''</tt>: флаг, указывающий на то, что ссылка <tt>''url''</tt> ведет на рекламный видеоролик, который клиент должен проиграть перед началом воспроизведения основного контента
* <tt>''interruptible=1''</tt>: флаг, указывающий на то, что должен проиграться прерываемый рекламный ролик
* <tt>''position''</tt>: целое число от 0 до 100, которое указывает с какой позиции клиент должен начать проигрывание (например, position=50 означает, что клиент должен начать проигрывание с
 
позиции 50%, т.е. с середины контента)
 
;Пример:
<tt><nowiki><<START http://127.0.0.1:6878/content/xxxx
<<START http://127.0.0.1:6878/content/xxxx ad=1
<<START http://127.0.0.1:6878/content/xxxx ad=1 interruptible=1
<<START http://127.0.0.1:6878/content/xxxx pos=0</nowiki></tt>
 
=====<tt style="color: #009;">PAUSE</tt>=====
;Версия API
:>= 1
 
;Описание
:Движок начал буферизацию, клиент по возможности должен остановиться на паузу до получения команды <tt>RESUME</tt>
 
;Синтаксис
<tt>PAUSE</tt>
 
;Параметры
:нет
 
;Пример:
<tt><nowiki><<PAUSE</nowiki></tt>
 
=====<tt style="color: #009;">RESUME</tt>=====
;Версия API
:>= 1
 
;Описание
:Движок завершил буферизацию, клиент может продолжить воспроизведение.
 
;Синтаксис
<tt>RESUME</tt>
 
;Параметры
:нет
 
;Пример:
<tt><nowiki><<RESUME</nowiki></tt>
 
=====<tt style="color: #009;">STOP</tt>=====
=====<tt style="color: #009;">SHUTDOWN</tt>=====
;Версия API
:>= 1
 
;Описание
:Движок завершил работу
 
;Синтаксис
<tt>SHUTDOWN</tt>
 
;Параметры
:нет
 
;Пример:
<tt><nowiki><<SHUTDOWN</nowiki></tt>
 
 
====События от клиента к движку====
 
=====<tt style="color: #009;">DUR</tt>=====
;Версия API
:>= 1
 
;Описание
:Сообщить движку о длительности контента, который в данный момент проигрывается клиентом. Данная команда должна отправлять сразу после того, как клиент определил длительность контента.
 
;Синтаксис
<tt>DUR ''video_url'' ''duration''</tt>
 
;Параметры
* <tt>''video_url''</tt>: ссылка на видео, которая была отправлена клиенту после окончания пребуферизации в команде <tt>START</tt>
* <tt>''duration''</tt>: длительность в миллисекундах
 
;Пример:
<tt><nowiki>Клиент определить длительность контента: 3780 секунд:
>>DUR http://127.0.0.1:6878/content/5b5ba8c462f4014d8b57377c97d2e13caee52cdd/0.685119063624 3780000</nowiki></tt>
 
=====<tt style="color: #009;">PLAYBACK</tt>=====
;Версия API
:>= 1
 
;Описание
:Сообщить движку о прогрессе проигранного контента (сколько процентов проигралось).
:Данная команда особенно важна, когда идет прогрывание рекламных роликов - переход к основному контенту происходит только после того, как движок получил команду PLAYBACK 100 (т.е. после того, как
 
клиент полность проиграл рекламный ролик)
 
;Синтаксис
<tt>PLAYBACK ''video_url'' ''event''</tt>
 
;Параметры
* <tt>''video_url''</tt>: ссылка на видео, которая была отправлена клиенту после окончания пребуферизации в команде <tt>START</tt>
* <tt>''event''</tt>: одно из указанных событий:
** 0: начало проигрывания
** 25: проиграно 25% видео
** 50: проиграно 50% видео
** 75: проиграно 75% видео
** 100: проиграно 100% видео (воспроизведение завершено)
 
;Пример:
<tt><nowiki>>>PLAYBACK http://127.0.0.1:6878/content/5b5ba8c462f4014d8b57377c97d2e13caee52cdd/0.685119063624 0
>>PLAYBACK http://127.0.0.1:6878/content/5b5ba8c462f4014d8b57377c97d2e13caee52cdd/0.685119063624 25
>>PLAYBACK http://127.0.0.1:6878/content/5b5ba8c462f4014d8b57377c97d2e13caee52cdd/0.685119063624 50
>>PLAYBACK http://127.0.0.1:6878/content/5b5ba8c462f4014d8b57377c97d2e13caee52cdd/0.685119063624 75
>>PLAYBACK http://127.0.0.1:6878/content/5b5ba8c462f4014d8b57377c97d2e13caee52cdd/0.685119063624 100</nowiki></tt>
 
=====<tt style="color: #009;">EVENT</tt>=====
 
====События от движка к клиенту====
=====<tt style="color: #009;">STATE</tt>=====
;Версия API
:>= 1
 
;Описание
:Информация о текущем статусе TS Engine
 
;Синтаксис
<tt>STATE 'state_id'</tt>
 
;Параметры
* <tt>''state_id''</tt>: состояние движка:
** 0
** 1
** 2
 
;Пример:
<tt><nowiki><<STATE 0</nowiki></tt>
 
=====<tt style="color: #009;">STATUS</tt>=====
;Версия API
:>= 1
 
;Описание
:Данное сообщение отправляется периодически для информирования клиента о текущем статусе загрузки контента
 
;Синтаксис
<tt>STATUS main:status_string
STATUS main:status_string|ad:status_string</tt>
 
;Параметры
:нет
 
;Пример:
<tt><nowiki><<STATUS main:prebuf;45;30|ad:buf;69
<<STATUS main:dl|ad:dl</nowiki></tt>
 
=====<tt style="color: #009;">AUTH</tt>=====
;Версия API
:>= 1
 
;Описание
:Уровень доступа пользователя
 
;Синтаксис
<tt>AUTH ''user_auth_level''</tt>
 
;Параметры
* <tt>''user_auth_level''</tt>: уровень доступа пользователя
 
;Пример:
<tt><nowiki>Пользователь не зарегистрирован:
<<AUTH 0
 
Пользователь зарегистрирован:
<<AUTH 1</nowiki></tt>
 
=====<tt style="color: #009;">EVENT</tt>=====
Описание скоро будет

Navigation menu