Итак, создаем обработку и в ней добавляем реквизиты формы:
Реквизиты Адрес, Имя пользователя и пароль служат для подключения к Трассиру. Эту информацию можно получить у сисадмина или в настройках сервера самого Trassir. Обращаю внимание, что для просмотра архива видео подключение должно происходить именно по имени пользователя и паролю, а не просто по паролю SDK (данная особенность описана в мануале SDK Trassir).
Имя канала, идентификатор канала, сессия и токен служат для хранения полученных данных по SDK.
Путь к браузеру - путь к браузеру (в моем случае яндекс) для запуска архива видео. Сразу хочу сказать, что я пытался использовать поле HTML документа в 1С, переход по навигационной ссылке (из БСП) или работу с IE - как говорится, "не взлетело".
Начало и окончание просмотра - для определения интервала архива видео, который хотим получить.
Кроме того, в модуле формы определим 2 переменные для кеширования соединения HTML:
&НаКлиенте
Перем Соединение;
&НаКлиенте
Перем СоединениеТокен;
и сразу определим функции, которые нам вернут требуемое соединение:
&НаКлиенте
Функция ПолучитьСоединение()
Если Соединение <> Неопределено Тогда
Возврат Соединение;
КонецЕсли;
Если ПустаяСтрока(Адрес) Тогда
ВызватьИсключение("Не указан адрес");
КонецЕсли;
Соединение = Новый HTTPСоединение(Адрес, 8080,,Пароль,,,Новый ЗащищенноеСоединениеOpenSSL(Неопределено, Неопределено));
Возврат Соединение;
КонецФункции // ПолучитьСоединение()
&НаКлиенте
Функция ПолучитьСоединениеТокен()
Если СоединениеТокен <> Неопределено Тогда
Возврат СоединениеТокен;
КонецЕсли;
Если ПустаяСтрока(Адрес) Тогда
ВызватьИсключение("Не указан адрес");
КонецЕсли;
СоединениеТокен = Новый HTTPСоединение(Адрес, 555);
Возврат СоединениеТокен;
КонецФункции // ПолучитьСоединениеТокен()
Обратите внимание, что соединение для работы с SDK у нас защищенное, а для просмотра архива видео - нет.
Порты в соединениях (8080 и 555) указаны в настройках сервера Trassir. Если их никто не менял, то по умолчанию они такие.
Так как все результаты запросов Trassir возвращает в виде Json, добавим служебную функцию для чтения:
&НаКлиенте
Функция ПрочитатьЗапросВСтруктуру(СтрокаЗапроса) Экспорт
Чтение = Новый ЧтениеJSON;
Чтение.УстановитьСтроку(СтрокаЗапроса);
Возврат ПрочитатьJSON(Чтение);
КонецФункции // ПрочитатьЗапросВСтруктуру()
Разместим наши реквизиты на форме. Получается примерно такое:
Пропишем для имени канала процедуру начала выбора с кодом (сразу говорю, использую асинхронные вызовы, но переписать на обработчик ожидания, думаю, несложно):
&НаКлиенте
Асинх Процедура ИмяКаналаНачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка)
Запрос = Новый HTTPЗапрос("/channels?sid=" + ПолучитьСессию());
Ответ = ПолучитьСоединение().Записать(Запрос);
СтруктураОтвета = ПрочитатьЗапросВСтруктуру(Ответ.ПолучитьТелоКакСтроку());
Если Не СтруктураОтвета.Свойство("channels") Тогда
Возврат;
КонецЕсли;
СписокВыбора = Новый СписокЗначений;
Для каждого Позиция Из СтруктураОтвета.channels Цикл
СписокВыбора.Добавить(Позиция.guid, Позиция.name);
КонецЦикла;
Обещание = СписокВыбора.ВыбратьЭлементАсинх("Выберите камеру");
Результат = Ждать Обещание;
Если Результат <> Неопределено Тогда
ИмяКанала = Результат.Представление;
ИдентификаторКанала = Результат.Значение;
КонецЕсли;
КонецПроцедуры
Данная процедура получает список каналов, которые есть в Trassir и исходя из выбранного канала получаем идентификатор канала (по сути именно он нам и нужен для получения архива видео).
Функцию Получить соединение мы уже рассматривали, здесь видим еще одну функцию ПолучитьСессию(). Она очень простая:
&НаКлиенте
Функция ПолучитьСессию()
Если Не ПустаяСтрока(Сессия) Тогда
Возврат Сессия;
КонецЕсли;
Если ПустаяСтрока(ИмяПользователя) ИЛИ ПустаяСтрока(Пароль) Тогда
ВызватьИсключение("Не указано имя пользователя и/или пароль");
КонецЕсли;
Запрос = Новый HTTPЗапрос("login?username=" + ИмяПользователя + "&password=" + Пароль);
Ответ = ПолучитьСоединение().Записать(Запрос);
СтруктураОтвета = ПрочитатьЗапросВСтруктуру(Ответ.ПолучитьТелоКакСтроку());
Если СтруктураОтвета.success <> 1 Тогда
Возврат Неопределено;
КонецЕсли;
Сессия = СтруктураОтвета.sid;
ПодключитьОбработчикОбновитьСессию();
Возврат Сессия;
КонецФункции // ПолучитьСессию()
Здесь процедура ПодключитьОбработчикОбновитьСессию запускает периодический пинг для поддержания сессии (в документации описано, что сессия живет 15 минут и её необходимо периодически "дёргать"):
&НаКлиенте
Процедура ОбновитьСессию()
Если ПустаяСтрока(Сессия) Тогда
ОтключитьОбработчикОжидания("ОбновитьСессию");
Возврат;
КонецЕсли;
Запрос = Новый HTTPЗапрос("objects/?sid=" + Сессия);
Ответ = ПолучитьСоединение().Записать(Запрос);
КонецПроцедуры // ОбновитьСессию()
&НаКлиенте
Процедура ПодключитьОбработчикОбновитьСессию()
ОтключитьОбработчикОжидания("ОбновитьСессию");
ПодключитьОбработчикОжидания("ОбновитьСессию", 840);//Раз в 15 минут надо дергать сессию
КонецПроцедуры // ПодключитьОбработчикОбновитьСессию()
И собственно команда для получения архива видео:
&НаКлиенте
Процедура ПросмотрВидео(Команда)
Если Не ПроверитьЗаполнение() Тогда
Возврат;
КонецЕсли;
Запрос = Новый HTTPЗапрос("get_video?channel=" + ИдентификаторКанала + "&container=mjpeg&stream=archive_main&sid=" + ПолучитьСессию());
Ответ = ПолучитьСоединение().Записать(Запрос);
СтруктураОтвета = ПрочитатьЗапросВСтруктуру(Ответ.ПолучитьТелоКакСтроку());
Если СтруктураОтвета.success <> 1 Тогда
Возврат;
КонецЕсли;
Токен = СтруктураОтвета.token;
ПодключитьОбработчикОбновитьТокен();
АдресДляБраузера = "http://" + Адрес + ":555/" + Токен;
ЗапуститьПриложение(ПутьКБраузеру + " " + АдресДляБраузера,, ЛОЖЬ);
ТекДата = ТекущаяДата();
Пока ТекДата + 6 > ТекущаяДата() Цикл
КонецЦикла;
Запрос = Новый HTTPЗапрос("archive_command?command=play&start=" + ПолучитьДатуВремяТрассир(НачалоПросмотра) + "&stop=" + ПолучитьДатуВремяТрассир(ОкончаниеПросмотра) +
"&speed=1&sid=" + ПолучитьСессию() + "&token=" + Токен);
ПолучитьСоединение().Записать(Запрос);
КонецПроцедуры
ПодключитьОбработчикОбновитьТокен действует аналогично и по той же причине, что и ПодключитьОбработчикОбновитьСессию: срок жизни токена 15 секунд и его необходимо "дёргать", чтобы он не умер:
&НаКлиенте
Процедура ПодключитьОбработчикОбновитьТокен()
ОтключитьОбработчикОжидания("ОбновитьТокен");
ПодключитьОбработчикОжидания("ОбновитьТокен", 13);
КонецПроцедуры // ПодключитьОбработкиОбновитьТокен()
&НаКлиенте
Процедура ОбновитьТокен()
Если ПустаяСтрока(Токен) Тогда
ОтключитьОбработчикОжидания("ОбновитьТокен");
Возврат;
КонецЕсли;
Запрос = Новый HTTPЗапрос(Токен + "/?ping");
Ответ = ПолучитьСоединениеТокен().Записать(Запрос);
КонецПроцедуры // ОбновитьТокен()
Теперь собственно, зачем такие сложности с запуском в браузере просмотра архива. Дело в том, что именно в браузере будет просмотр архива видео. Управление архивом (переход на позицию, например) тоже будет отображаться в браузере. Поэтому, чтобы в браузере началось воспроизведение и сделана пауза в 6 секунд (добыта опытным путём) после запуска.
В приложенной обработке то, что было разобрано в статье.
Обработка тестировалась на платформе 8.3.22.1750, но должна работать на версиях, где есть асинхронные вызовы (асинх)
Если будут вопросы, задавайте в комментариях, постараюсь ответить.
P.S. Больно не пинайте - первая статья.