Обзор HTTP API

HTTP API позволяет усправлять движком с помощью HTTP запросов.

ВАЖНО! Технически невозможно отправить запрос движку с https-страницы, так как общение с движком осуществляется по незащищенному протоколу HTTP. Все такие запросы блокируются всеми современные браузерами.
При необходимости работать с движком со своего https-сайта вебмастер должен создать для этих целей незащищенную http-страницу.

Основные доступные команды - получение медиа-потока от движка в требуемом формате.
На данный момент доступны два формата выдачи медиа-потока: http progressive download либо HLS.
Для получения потока необходимо указать движку, что именно вы хотите смотреть.
Движок может возпроизводить такие виды контента:

Команда движку представляет собой URL определенного формата.
Формат зависит от того, какой контент вы хотите смотреть и в каком формате его должен выдать движок.

Для запуска контента, распостраняемого по протоколу HLS, необходимо отправить запрос на адрес:

http://127.0.0.1:6878/hls/manifest.m3u8 (выдача в формате HLS)
http://127.0.0.1:6878/hls/getstream (выдача в виде MPEG TS потока по HTTP методом последовательного "склеивания" отдельных HLS-сегментов)
            

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

http://127.0.0.1:6878/ace/manifest.m3u8 (выдача в формате HLS)
http://127.0.0.1:6878/ace/getstream (выдача в формате http progressive download)
            

Во всех примерах предполагается, что используемый по умолчанию порт 6878 не был изменен в настройках движка.
Так же предполагается, что движок запущен. Процедура проверки состояния движка и его версии описана здесь (TODO: добавить ссылку).
Описанное здесь HTTP API доступно с версии движка 3.1.0-rc8 (код версии: 3002800)
Все ответы от движка в рамках HTTP API содержат заголовок "Access-Control-Allow-Origin: *", что позволяет отправлять запросы движку с помощью AJAX-запросов с любого домена, не нарушая политику безопасности браузера.

Параметры запросов к HTTP API

Общие параметры:
sid - идентификатор плеера
use_api_stop - будет ли плеер отправлять команду "стоп" движке после остановки воспроизведения (0 или 1) 
use_api_events - будет ли плеер получать события от движка с помощью event_url (0 или 1)

Параметры для запуска контента, распостраняемого по протоколу HLS:
manifest_url - ссылка на HLS-манифест (.m3u8 файл)
use_timeshift - нужно ли добавлять p2p-таймшифт к трансляции (см. HLS P2P таймшифт)

Параметры для запуска остальных типов контента:
одно из
direct_url - прямая ссылка на контент
id - AceStream Content ID
infohash - инфохеш транспортного файла
url - ссылка на транспортный файл
либо можно передать содержимое транспортного файла в теле POST-запроса

для формата выдачи HLS:
transcode_audio - необходимо ли транскодировать аудио в AAC (0 или 1)
transcode_mp3 - необходимо ли транскодировать MP3 в AAC (0 или 1)
preferred_audio_language - предпочитаемый язык аудио-дорожки
            

HLS P2P таймшифт

При просмотре HLS live трансляции через движок есть возможность увеличить таймшифт до 30 минут за счет p2p-технологии.
Для этого необходимо указать параметр use_timeshift=1 при старте.
При использовании P2P таймшифта есть некоторые ограничения.
Во-первых, таймшифт может быть увеличен только для HLS-трансляций с фиксированной длительностью сегмента.
Во-вторых, при увеличении таймшифта движок не может гарантировать наличие всех сегментов, объявленных в манифесте.
Это значит, что при перемотке назад движок может выдать ошибку 404 Not found при запросе сегмента в том случае, если запрошенный сегмент не может быть скачан по p2p.
В такой ситуации плеер должен перемотать на позицию live. Движок при возникновении такой ситуации также отправляет событие missing_content (если use_api_events=1).

Расширенные возможности HTTP API.

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

format=json
        

При получении данного параметра движок выдаст в ответ не медиа-поток, а набор ссылок в формате JSON:

    
{
    "playback_url": playback_url,
    "stat_url: stat_url,
    "command_url": command_url,
    "event_url": event_url,
}


playback_url - ссылка для получения медиа-потока
stat_url - ссылка для получения информации про сессию
command_url - ссылка для отправки команд движку
event_url - ссылка для получения событий

event_url в ответе выдается только в том случае, если страт выполнялся с параметром use_api_events.

По ссылке playback_url движок отдаст запрошенный медиа-поток. Эту ссылку необходимо передать плееру.

По ссылке stat_url выдается информация про сессию воспроизведения в формате JSON:


{
    "response": {
        "status": "dl",
        "uploaded": 0,
        "speed_down": 516,
        "speed_up": 0,
        "downloaded": 14155776,
        "peers": 2,
        "total_progress": 0
    },
    "error": null
}

        

По ссылке command_url движок принимает команды для управления сессией воспроизведения.
Название команды передается в параметре method.
На данный момент доступна одна команда: stop - остановить сессию воспроизведения.
Рекомендуется всегда останавлить сессию воспроизведения с помощью этой команды, когда воспроизведение останавливается на уровне плеера.

Пример:
http://127.0.0.1:6878/ace/cmd/5410b27fc567c35c8547e3b69b141215ce3a1fd7/ef0609c43e560697329d93dae4571edb?method=stop
Ответ:

{
    "response": "ok",
    "error": null
}

        

Ссылка event_url используется для получения событий от движка методом long polling.

Пример:
http://127.0.0.1:6878/ace/event/5410b27fc567c35c8547e3b69b141215ce3a1fd7/ef0609c43e560697329d93dae4571edb
Ответ:

{
    "response": "{\"name\": \"got_codec_info\"}, \"params\": {\"audio_codec_id\": 86018, \"video_codec_id\": 28}",
    "error": null
}

Данные по событию возвращаются в виде закодированного в строку JSON-объекта в поле response.
Для получения данных строку необходимо декодировать:

var event = JSON.parse(response.response);

После декодирования переменная event будет содержать такой объект:

{
    "name": "got_codec_info",
    "params: {
        "audio_codec_id": 86018,
        "video_codec_id": 28
    }
}

name - название события
params - объект с параметрами (значения зависят от события)

Когда текущая сессия воспроизведения будет остановлена, event_url вернет такой ответ:

{
    "response": null,
    "error": "download stopped"
}

После получения такого ответа необходимо прекратить отсылать запросы на event_url.
        
Есть такие виды событий:

Как происходит запуск

После получения команды на старт движок делает один либо несколько редиректов со статусом 302.
Финальный URL представляет собой прямую ссылку на медиа-поток в запрошенном формате.
Для формата HLS это ссылка на m3u8 плейлист, для формата http progressive download это прямая ссылка на контент.
Плеер по возможности должен запоминать финальную ссылку и запрашивать контент по ней.

Формат выдачи может поменяться, если транспортный файл содержит несколько единиц контента.
В этом случае движок выдает m3u8-плейлист со ссылками на запуск сессии воспроизведения каждой отдельной единицы контент внутри транспортного файла.
Такое происходит в двух случаях:

Примеры

1. Запуск VOD по infohash, вывод в HLS


# запрос (команда на старт):
GET /ace/manifest.m3u8?infohash=5410b27fc567c35c8547e3b69b141215ce3a1fd7 HTTP/1.1
Host: 127.0.0.1:6878
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.0
Accept-Encoding: gzip, deflate
Connection: keep-alive
        
# ответ (редирект):
Access-Control-Allow-Origin: *
Date: Wed, 23 Sep 2015 12:03:49 GMT
Location: http://127.0.0.1:6878/ace/r/5410b27fc567c35c8547e3b69b141215ce3a1fd7/f528764d624db129b32c21fbca0cb8d6.m3u8
Server: BaseHTTP/0.3 Python/2.7.2

# запрос (следуем по редиректу):
GET /ace/r/5410b27fc567c35c8547e3b69b141215ce3a1fd7/f528764d624db129b32c21fbca0cb8d6.m3u8 HTTP/1.1
Host: 127.0.0.1:6878
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.0
Accept-Encoding: gzip, deflate
Connection: keep-alive

# ответ (редирект):
Access-Control-Allow-Origin: *
Date: Wed, 23 Sep 2015 12:04:27 GMT
Location: http://127.0.0.1:6878/ace/m/5410b27fc567c35c8547e3b69b141215ce3a1fd7/f528764d624db129b32c21fbca0cb8d6.m3u8
Server: BaseHTTP/0.3 Python/2.7.2

# запрос (следуем по редиректу):
GET /ace/m/5410b27fc567c35c8547e3b69b141215ce3a1fd7/f528764d624db129b32c21fbca0cb8d6.m3u8 HTTP/1.1
Host: 127.0.0.1:6878
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.0
Accept-Encoding: gzip, deflate
Connection: keep-alive

# ответ (m3u8 плейлист):
Accept-Ranges: bytes
Access-Control-Allow-Origin: *
Connection: Keep-Alive
Content-Length: 129275
Content-Type: application/x-mpegurl
Date: Wed, 23 Sep 2015 12:04:32 GMT
Keep-Alive: timeout=15, max=100
Server: BaseHTTP/0.3 Python/2.7.2

#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:10
#EXT-X-MEDIA-SEQUENCE:0
#EXTINF:10,
http://127.0.0.1:6878/ace/c/5410b27fc567c35c8547e3b69b141215ce3a1fd7/f528764d624db129b32c21fbca0cb8d6/0.ts
#EXTINF:10,
http://127.0.0.1:6878/ace/c/5410b27fc567c35c8547e3b69b141215ce3a1fd7/f528764d624db129b32c21fbca0cb8d6/1.ts
#EXTINF:10,
http://127.0.0.1:6878/ace/c/5410b27fc567c35c8547e3b69b141215ce3a1fd7/f528764d624db129b32c21fbca0cb8d6/2.ts
...
#EXTINF:10,
http://127.0.0.1:6878/ace/c/5410b27fc567c35c8547e3b69b141215ce3a1fd7/f528764d624db129b32c21fbca0cb8d6/86.ts
#EXTINF:18,
http://127.0.0.1:6878/ace/c/5410b27fc567c35c8547e3b69b141215ce3a1fd7/f528764d624db129b32c21fbca0cb8d6/87.ts
#EXT-X-ENDLIST

2. Запуск VOD по ссылке на транспортный файл


# запрос (команда на старт)
GET /ace/getstream?url=http://d.rutor.org/download/123509 HTTP/1.1
Host: 127.0.0.1:6878
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.0
Accept-Encoding: gzip, deflate
Connection: keep-alive

# ответ (редирект)
Access-Control-Allow-Origin: *
Date: Wed, 23 Sep 2015 12:27:01 GMT
Location: http://127.0.0.1:6878/ace/r/d565523a00595914b24001963f8ee94e4d2246ec/f528764d624db129b32c21fbca0cb8d6
Server: BaseHTTP/0.3 Python/2.7.2

# запрос (следуем по редиректу):
GET /ace/r/d565523a00595914b24001963f8ee94e4d2246ec/f528764d624db129b32c21fbca0cb8d6 HTTP/1.1
Host: 127.0.0.1:6878
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.0
Accept-Encoding: gzip, deflate
Connection: keep-alive

# ответ (редирект):
Access-Control-Allow-Origin: *
Date: Wed, 23 Sep 2015 12:27:01 GMT
Location: http://127.0.0.1:6878/content/d565523a00595914b24001963f8ee94e4d2246ec/0.415550673815
Server: BaseHTTP/0.3 Python/2.7.2

# запрос (прямая ссылка на контент)
GET /content/d565523a00595914b24001963f8ee94e4d2246ec/0.415550673815 HTTP/1.1
Host: 127.0.0.1:6878
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.0
Accept-Encoding: gzip, deflate
Connection: keep-alive

# ответ (контент)
Accept-Ranges: bytes
Connection: Keep-Alive
Content-Length: 3128031232
Content-Type: video/avi
Date: Wed, 23 Sep 2015 12:27:01 GMT
Keep-Alive: timeout=15, max=100
Server: BaseHTTP/0.3 Python/2.7.2
X-Content-Duration: 10689.0077638

3. Запуск VOD по AceStream Content ID с использованием расширенных возможностей HTTP API, формат HLS

http://127.0.0.1:6878/ace/manifest.m3u8?format=json&sid=0.6045503369100068&transcode_audio=1&transcode_mp3=0&use_api_events=1&use_api_stop=1&id=94c2fd8fb9bc8f2fc71a2cbe9d4b866f227a0209

{
    "response": {
        "playback_url": "http://127.0.0.1:6878/ace/r/5410b27fc567c35c8547e3b69b141215ce3a1fd7/ef0609c43e560697329d93dae4571edb.m3u8",
        "stat_url": "http://127.0.0.1:6878/ace/stat/5410b27fc567c35c8547e3b69b141215ce3a1fd7/ef0609c43e560697329d93dae4571edb",
        "command_url": "http://127.0.0.1:6878/ace/cmd/5410b27fc567c35c8547e3b69b141215ce3a1fd7/ef0609c43e560697329d93dae4571edb",
        "event_url": "http://127.0.0.1:6878/ace/event/5410b27fc567c35c8547e3b69b141215ce3a1fd7/ef0609c43e560697329d93dae4571edb",
    },
    "error": null
}

Media Server API

Media Server API используется для задач, не связанных напрямую с получением медиа-потока от движка. Запрос отправляются сюда:

http://127.0.0.1:6878/server/api

Все запросы должны содержать обязательный параметр method.

На данный момент доступны такие методы:

1. Запустить воспроизведение в одном из установленных у пользователя плеере.

method: open_in_player
Параметры:
обязательно должен присутствовать один из таких параметров:
    manifest_type - тип манифеста (обязательно должен присутствовать при указании параметра manifest_url; сейчас доступен только один тип: hls)
    manifest_url - URL манифеста (для HLS-трансляций)
    content_id - AceStream Content ID
    url - URL транспортного файла
либо можно передать содержимое транспортного файла в теле POST-запроса.

player_id - идентификатор плеера, в котором необходимо запустить воспроизведение.
        Это необязательный параметр.
        Если он не указан, то движок сам выберет плеер для запуска.
        Список идентификаторов доступных плееров можно получить командой get_available_players

Формат ответа:

{
    "result": "ok",
    "error": null
}

 
Пример:
http://127.0.0.1:6878/server/api?method=open_in_player&content_id=94c2fd8fb9bc8f2fc71a2cbe9d4b866f227a0209

Ответ:

{
    "result": "ok",
    "error": null
}

2. Получить список доступных плееров:

method: get_available_players
обязательно должен присутствовать один из таких параметров:
    manifest_type - тип манифеста (обязательно должен присутствовать при указании параметра manifest_url; сейчас доступен только один тип: hls)
    manifest_url - URL манифеста (для HLS-трансляций)
    content_id - AceStream Content ID
    url - URL транспортного файла
либо можно передать содержимое транспортного файла в теле POST-запроса.

Формат ответа:

{
    "result": {
        "players": [
            {
                "id": "player_id",
                "name": "player_name",
                "icon": "player_icon"
            },
            ...
        ]
    },
    "error": null
}

player_id - идентификатор плеера, который необходимо отослать в команде open_in_player при необходимости запустить воспроизведение в этой плеере
player_name - название плеера
player_icon - иконка плеера (base64 encoding); null если иконки нет
 
Пример:
http://127.0.0.1:6878/server/api?method=get_available_players&content_id=94c2fd8fb9bc8f2fc71a2cbe9d4b866f227a0209

Ответ:

{
    "result": {
        "players": [
            {"icon": null, "id": "10c995a33b489e60b4597c68bf126d5be9a79e20", "name": "Ace Player HD"},
            {"icon": null, "id": "05f360d3d54f8e1987506cca09bae7b39170ce28", "name": "MPC-HC"},
            {"icon": null, "id": "0f3a8626f1017b92058dd3cdcb2c2d15d8e5a2a3", "name": "VLC"},
            {"icon": null, "id": "d976c6cb0baf17d38bd69ab05d6394a3b437d6e1", "name": "\u041f\u0440\u043e\u0438\u0433\u0440\u044b\u0432\u0430\u0442\u0435\u043b\u044c Windows Media"}
        ]
    },
    "error": null
}


3. Добавление контента в плейлист движка.

Добавление в плейлист движка происходит только с согласия пользователя. В связи с этим в Media Server API отсутствует метод для прямого добавления, но есть возможность открыть iframe с формой для добавления. Для этого необходимо создать iframe на веб-странице и загрузить в него такую ссылку:

http://127.0.0.1:6878/server/iframe?method=playlist_add_item

Как правило, iframe создается при нажатии на кнопку вида "Добавить в плейлист Ace Stream Media Center".
Можно также передать движку идентификатор контента, который необходимо добавить в плейлист.
Эт делается с помощью одного из таких параметров:
content_id - AceStream Content ID
magnet - magnet link
infohash - инфохеш транспортного файла
transport_file_url - ссылка на транспортный файл

Можно указать название контента:
title - название контента (будет добавлен под этим названием в плейлист; необязательный параметр)

Если движку передать информацию о добавляемом контенте, то в iframe загрузится частично заполненная форма добавления в плейлист.
Если информацию не передавать - отобразится пустая форма.

Пример:
http://127.0.0.1:6878/server/iframe?method=playlist_add_item&content_id=94c2fd8fb9bc8f2fc71a2cbe9d4b866f227a0209

Закрытие iframe.
После того, как пользователь принял решение о добавлении в плейлист, iframe должен быть закрыт.
Код внутри iframe не может этого сделать (это запрещено политикой безопасности браузеров), поэтому ответственность по закрытию iframe возлагается на веб-страницу, открывшую его.
Данная схема работает на основе HTML5 Messaging API.
При необходимости закрыть код внутри iframe отправляет такое сообщение (оно адресовано странице, открывшей iframe):

window.parent.postMessage({
        acestream: {
            msg: "close_iframe_playlist_add_item"
        }
}, "*");


Открывающая страница должна обработать такое сообщение и закрыть iframe.
Пример кода на открывающей странице:

function acestreamEventListener(event) {
    if(event.data.acestream) {
        var msg = event.data.acestream.msg;
        if(msg === 'close_iframe_playlist_add_item') {
            var iframe = document.getElementById("acestream-iframe-playlist-add-item");
            iframe.parentNode.removeChild(iframe);
        }
    }
}

addEventListener("message", acestreamEventListener, false)