Титровальные скрипты - создание объекта шаг за шагом.

Здесь обсуждаются любые продукты компании СофтЛаб-НСК для телевизионного вещания (Форвард Т, Форвард ТС, Форвард Голкипер, Форвард Рефери, Форвард Офис, Форвард Инжест)

Модераторы: ElenVR, Людмила, PR

Ответить
Даниленко Сергей
Сообщения: 7093
Зарегистрирован: 26 фев 2004 09:53
Откуда: Techsupport SoftLab-NSK

Титровальные скрипты - создание объекта шаг за шагом.

Сообщение Даниленко Сергей »

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

Часть 1. Введение.
Этот топик будет посвящён описанию того, как самому написать титровальный объект с использованием технологии титровальных скриптов.
Будет показан весь процесс от начала до конца с максимально возможной детальностью. Также будет уделено внимание процессу отладки скрипта и некоторым тонкостям программирования скриптов. В определённом объёме затронем вопрос защиты скрипта, что позволит реализовывать коммерческие версии (за деньги, под заказ).

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


Идея для нашего объекта такая: на анимированной или статической подложке будет показываться информация в виде картинки и текста.
Изображение
Текстовая информация будет состоять из двух частей - основного текста и дополнительного (номер телефона или название организации).
Такой объект можно использовать, например, для показа "доски объявлений".
Подложка, как уже было сказано выше, может быть анимированной либо статической. Кроме того, подложка может отсутствовать вообще.
Картинка и дополнительный текст в рамках одного объявления также могут отсутствовать.
Основной текст должен быть всегда.
Информация для показа объявлений берется из одного текстового файла. При показе последнего объявления будет проиходить автоматическое перезачитывание текстового файла. И если он поменялся, то на новом обороте будут показываться новые объявления.
Вот такой объектик попробуем сами сделать.
В принципе все это решаемо и без использования титровальных скриптов - через создание дополнительного расписания в программе OnAir. Но использование скриптов позволяет выполнять эту задачу гораздо более просто и компактно.

Комментарии, вопросы и замечания просьба оставлять в специально для этого предназначенной ветке форума. Из этой ветки они будут удалены!
Последний раз редактировалось Даниленко Сергей 30 авг 2012 11:07, всего редактировалось 1 раз.
Даниленко Сергей
Сообщения: 7093
Зарегистрирован: 26 фев 2004 09:53
Откуда: Techsupport SoftLab-NSK

Сообщение Даниленко Сергей »

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

Часть 2. Создаем проект в FDTitleDesigner.
Запускаем программу FDTitleDesigner (как правило, она располагается здесь: C:\Program Files\ForwardT Software\FDTitle\FDTitleDesigner.exe).

Документ по программе FDTitleDesigner можно найти здесь:
http://www.softlab-nsk.com/rus/forward/ ... signer.pdf

Титровальный объект, который присутствует в проекте по умолчанию (TitleObject) переименовываем в CallBoard (доска объявлений). Так будет называться и сам скрипт.
Добавляем в этот титровальный объект 8 титровальных элементов:
Main
Тип - "Подпись". Назначение - служебный элемент, в отображении принимать участие не будет. Служит для выдачи технической информации в программу OnAir. Информация такого рода: в каком сейчас состоянии находится весь объект (проигрывается, остановлен), зациклен объект или нет и т.д.

Background
Тип - "АнимЛого". Назначение - показ анимированной (файлы типа avi, mpeg2, mov и т.д.) или статической (файлы типа tga, png и т.д.).
Первая тонкость - по описанию в документации такой тип титровальных элементов предназначен только для показа анимации (файлов типа avi, mpeg2, mov и т.д.). Но на самом деле в титровальном скрипте его также можно использовать и для показа статической анимации. Это значит что, не нужно заводить пару титровальных элементов - один для анимированной подложки, а другой - для графической. Не нужно создавать в скрипте кусок кода для понимания типа файла для подложки и выбора нужного для него титровального элемента. Достаточно использовать один элемент на оба типа.
Pic1, Pic2
Тип - "Картинка". Назначение - показ графической части объявления.

MainText1, MainText2
Тип - "Подпись". Назначение - показ основной части текста объявления.

AdText1, AdText2
Тип - "Подпись". Назначение - показ дополнительной части текста объявления.

Как мы видим для отображения информации используется удвоенное количество титровальных элементов. Это необходимо для реализации безостановочного конвейера "один титровальный элемент показывает информацию - во второй грузим следующее задание".

Изображение

После этого сохраняем титровальный проект в FDTitleDesigner (Файл->Сохранить проект как...).

Важно: названия титровальных элементов при использовании скрпитов должны использовать только латинские (английские) буквы.

Комментарии, вопросы и замечания просьба оставлять в специально для этого предназначенной ветке форума. Из этой ветки они будут удалены!
Последний раз редактировалось Даниленко Сергей 30 авг 2012 11:07, всего редактировалось 1 раз.
Даниленко Сергей
Сообщения: 7093
Зарегистрирован: 26 фев 2004 09:53
Откуда: Techsupport SoftLab-NSK

Сообщение Даниленко Сергей »

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

Часть 3. Добавляем скрипт.
По умолчанию кнопка добавления скриптов неактивна.
Для того, чтобы эту кнопку активировать, нужно добавить специальную запись в реестре.

Для 32-разряддных ОС (WinXP, Win7):
Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\SoftLab-NSK\FDTitle]
"ScriptEnable"=dword:00000001


Для 64-разряддной ОС (Win7):
Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\SoftLab-NSK\FDTitle]
"ScriptEnable"=dword:00000001


Выделенный фрагмент можно скопировать в текстовый файл. После этого следует сменить расширение файла с txt на reg и применить получившийся регистрационный файл.

Кнопка добавления скрипта становится доступной (при этом в дереве титровальных объектов нужно выделить титровальный объект, в который вы собираетесь добавить скрипт).
Изображение

Нажимаем кнопку. Появляется диалог.
Изображение
В нём выбираем "Скрипт по умолчанию". Жмём "Далее". Потом "Готово".
В программе FDTitleDesigner появляется дополнительная закладка с исходныс текстом скрипта.
Изображение

Комментарии, вопросы и замечания просьба оставлять в специально для этого предназначенной ветке форума. Из этой ветки они будут удалены!
Последний раз редактировалось Даниленко Сергей 30 авг 2012 11:07, всего редактировалось 1 раз.
Даниленко Сергей
Сообщения: 7093
Зарегистрирован: 26 фев 2004 09:53
Откуда: Techsupport SoftLab-NSK

Сообщение Даниленко Сергей »

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

Часть 4. Убираем лишние функции из скрипта.
Редактирование скрипта производится непосредственно в программе FDTitleDesigner на закладке с текстом скрипта. Если при написании/редактировании скрипта возникают ошибки, то информация о них сразу же появляется в специальном окне "Вывод".

Изображение

Практически любое изменение в коде скрипта приводит к его перекомпиляции, поэтому ошибки становятся видны сразу. И также сразу исчезают при их исправлении. Никакой кнопки для сборки/компиляции скрипта не существует - всё делается автоматически.

Часть функций из скрипта можно удалить, т.к. они использоваться не будут.

1)Удаляем объявление переменной _initState (стр. 9) т.к. мы не будем использовать продвинутый механизм инициализации переменных скрипта.

2)Удаляем строки 40-53 с функциями BeginInitialize и EndInitialize по тем же самым причинам.

3)Удаляем строки 55-58

4)Удаляем строки 104-124

5)Удаляем строки 160-166, т.к. мы не будем использовать нотификационные сообщения из программы OnAir.

6)В дальнейшем уберём ряд сообщений о "жизнедеятельности" титровальных элементов - это строки кода после 203 линии. которые помечены комментарием "// notification from Elements"

!!!Внимание!!! Удалять ненужные строки нужно с конца, чтобы не "разбегались" номера строк.

Если в вашей версии скрипта каких-то функций нет, то это означает, что вы используете более старую версию ПО. Но для наших целей это не является проблемой.

Комментарии, вопросы и замечания просьба оставлять в специально для этого предназначенной ветке форума. Из этой ветки они будут удалены!
Последний раз редактировалось Даниленко Сергей 30 авг 2012 11:08, всего редактировалось 2 раза.
Даниленко Сергей
Сообщения: 7093
Зарегистрирован: 26 фев 2004 09:53
Откуда: Techsupport SoftLab-NSK

Сообщение Даниленко Сергей »

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

Часть 5. Сохраняем и загружаем объект со скриптом.
Титровальный объект со скриптом (как и любой титровальный объект) можно сохранить (экспортировать) в виде шаблона (template). Файлы с шаблонами имеют расширение SLTitleTmpl. По своему формату - это xml-файл, который можно открыть, например, в "блокноте". Внутри шаблона содержатся все созданные нами титровальные элементы и код нашего скрипта.

Изображение

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

Для сохранения выделяем в дереве объектов программы FDTitleDesigner наш титровальный объект со скриптом CallBoard. Кликаем правой кнопкой мышки. В появившемся меню выбираем опцию "Экспортировать объект как Шаблон...".

Изображение

Откроется диалог "Помощник экспорта".
На первой странице нужно выбрать в какой файл сохранить наш шаблон. Остальные опции этой страницы обсудим позже.

Изображение

На следующей странице мастера нужно заполнить информацию о скрипте.
Изображение

Информация, которую мы заполняем на этой странице, в дальнейшем можно будет видеть в программе FDTitleDesigner в разделе "Скрипт инфо".

Изображение

Пожалуй самое важное поле для заполнения - это версия скрипта. Настоятельно рекомендуем заполнять это поле при экспорте - это поможет в дальнейшем правильно формировать историю вашей разработки.
Сохранённый в виде шаблона объект мы можем в дальнейшем многократно использовать в разных титровальных проектах. Также в виде шаблона вы можете передавать свои разработки заказчикам.
Для загрузки шаблона нужно в окне "Дерево объектов" программы FDTileDesigner кликнуть правой кнопкой мыши. В появившемся меню следует выбрать опцию "Импортировать объект из Шаблона..."
Изображение
В появившемся файловом диалоге выбираем нужный SLTitleTmpl-файл. После этого в вашем титровальном проекте появляется наш титровальный объект со скриптом.
Делать импорт шаблона можно как в новый титровальный проект, так и в уже имеющийся (т.е. дополнять ваш текущий проект).

Текущая версия нашего объекта со скриптом здесь:
ftp://ftp.sl.iae.nsk.su/Public/ForwardT ... ard_p5.zip

Комментарии, вопросы и замечания просьба оставлять в специально для этого предназначенной ветке форума. Из этой ветки они будут удалены!
Последний раз редактировалось Даниленко Сергей 30 авг 2012 11:16, всего редактировалось 2 раза.
Даниленко Сергей
Сообщения: 7093
Зарегистрирован: 26 фев 2004 09:53
Откуда: Techsupport SoftLab-NSK

Сообщение Даниленко Сергей »

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

Часть 6. На чём разрабатывать скрипты? Где взять докуменацию?
Для разработки скриптов нужно установить наше ПО, т.к. будет использоваться наша титровальная система. А вот плата (FD300, или FD322, или FD422) в дествительности не нужна.
Поэтому можно установить наше ПО типа ForwardTxSoftware (предназначено для работы с платами) и работать в режиме "без платы".
Также можно использовать и другую версию ПО - ForwardTxLite. Оно вообще предназначено только для работы в этом режиме.
Подробнее про режим "без платы" можно посмотреть здесь:
http://www.softlab-nsk.com/rus/forward/qna.html#a2_19

Последний релиз нашего ПО всегда доступен на сайте в разделе "Загрузка".
http://www.softlab-nsk.com/rus/forward/download.html

Если требуется более свежая версия, то следует напрямую обращаться в отдел техподдержки:
forward@softlab.tv
forward@sl.iae.nsk.su
forward@softlab-nsk.com

Текущая версия документации по скриптам для разработчиков здесь:
C:\Program Files\ForwardT Software\FDTitle\TitleScriptDocumentation.chm

Для написания и отладки скриптов потребуются следующие программы:
FDTitleDesigner - написание/просмотр скриптов. Просмотр работы скрипта возможен только в том случае, если скрипт не использует специальные нотификационные сообщения из программы OnAir (как в нашем скрипте).
Программа (в ПО ForwardTxSoftware ) по умолчанию здесь:
C:\Program Files\ForwardT Software\FDTitle\FDTitleDesigner.exe

FDOnAir - для просмотра работы скрипта в случае если скрипт использует специальные нотификационные сообщения.
Программа (в ПО ForwardTxSoftware ) по умолчанию здесь:
C:\Program Files\ForwardT Software\OnAir\FDOnAir.exe

SLTitlePreview - для осуществления работы в режиме "без платы".
Программа (в ПО ForwardTxSoftware ) по умолчанию здесь:
C:\Program Files\ForwardT Software\SLTitlePreview\SLTitlePreview.exe

DBGView - для отладки работы скрипта.
Программа (в ПО ForwardTxSoftware ) по умолчанию здесь:
C:\Program Files\ForwardT Software\Tools\Dbgview.exe

Комментарии, вопросы и замечания просьба оставлять в специально для этого предназначенной ветке форума. Из этой ветки они будут удалены!
Последний раз редактировалось Даниленко Сергей 30 авг 2012 11:13, всего редактировалось 2 раза.
Даниленко Сергей
Сообщения: 7093
Зарегистрирован: 26 фев 2004 09:53
Откуда: Techsupport SoftLab-NSK

Сообщение Даниленко Сергей »

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

Часть 7. Посмотрим что у нас есть в скрипте.
Откроем в FDTitleDesigner закладку с кодом скрипта. Посмотрим что у нас есть и для чего это нужно.
Код, который есть в скрипте, как правило, состоит из двух частей.
Первая часть - это набор функций, которые сгенерировал "мастер". Во многих случаях эти функции нужно самому переопределять, вносить туда свою логику. Например, при запуске объекта на воспроизведение. Или нужна какая-то реакция на загрузку задания в титровальный объект.
Вторая часть - это функции, которые вы добавляете самостоятельно. Например, функция, которая при загрузке зачитывает содержимое файла с заданием для титровального объекта.

Итак по порядку. У нас сейчас есть только первая часть функций, рассмотрим их.

В самом начале скрипта определяется набор библиотек, используемых в скрипте.
import System.IO;
import System.Diagnostics;
import SLTMTitleCommon.Scripting;
import LogotypeLib;
Такие библиотеки бывают 3-х типов:
1)Системные (первые две) - реализуют возможность программирования с использованием .NetFramework. К этому мы ещё вернёмся когда нам потребуется работа с массивами.
2)Библиотеки нашей титровальной системы (две последние) - дают возможность работы с титровальными элементами (менять свойства, запускать/останавливать воспроизведение и т.д.)
3)Собственные. Если у вас в нескольких скриптах есть одна и та же функция (например, для чтения файла с заданием), то логично её вынести в такую библиотеку. Смысл - исправлять ошибки проще в одном месте, а не в каждом из ваших скриптов. В этом смысле import в скриптах используется также как include файлов cpp и h файлов в C++.
var script = new Script(titleRoot);


Переменная script (ее можно назвать как угодно) описывает создание экземпляра класса Script. Собственно эта строка и осуществляет вызов и исполнение скрипта.

Далее идёт набор функций, изменять которые не рекомендуется, и обычно это не требуется.

Конструктор:
function Script(obj)
{
super(obj);
//debugger
init();
}
"Зачистка" скрипта при прекращении его жизни.
function CleanUp(obj, e : VsaScriptingHostEventArgs) {
// Add Your clean
_scriptingHost.remove_CleanUp(CleanUp);
Debug.WriteLine("Script CleanUp")
}
Следующая функция нами обязательно будет использоваться.
function init(){
_scriptingHost.add_CleanUp(CleanUp);

try {
// Add Your init code

} catch (ee) {
Debug.WriteLine("script init exception:" + ee);
}
}


Она вызывается при инициализации скрипта и в ней мы будем настраивать некоторые первоначальные свойства наших титровальных элементов.

Далее пойдут функции, которые перекрывают некоторый набор функций базового класса ядра нашей титровальной системы. Обычно, если функция, возвращающая булевское значение (boolean), перекрыта, то ее реализация в конкретном скрипте должна возвращать:
false - в случае, если необходимо вызвать исходную реализацию (т.е. всё сделает реализация "по умолчанию" базового класса)
true - если все необходимые действия мы сделаем сами, а исходную реализацию ("по умолчанию" базового класса) вызывать не требуется.

Набор функций следующий:
function Unload(): boolean {
return true;
}
Вызывается по выгрузке (деинициализации) скрипта. Без особой необходимости ее перекрытие не требуется и мы её использовать не будем.
override function Start(atStart : double, fadeDuration : double) : boolean {
Debug.WriteLine("script Start");
try {
// TODO: Start logic
//return true;
} catch (ee) {
Debug.WriteLine("script Start exception:" + ee);
}
return false;
}
Вызывается по запуску воспроизведения объекта. В параметре atStart передается время старта, в fadeDuration — время появления объекта на экране (может быть задано в программе FDOnAir). Здесь мы будем стартовать воспроизведение титровальных элементов нашего скрипта.
override function Stop(atStop : double, fadeDuration : double) : boolean {
Debug.WriteLine("script Stop");
try {
// TODO: Stop logic
//return true;
} catch (ee) {
Debug.WriteLine("script Stop exception:" + ee);
}
return false;
}

Вызывается по остановке воспроизведения скрипта. В параметре atStop передается время остановки, в fadeDuration — время исчезания объекта с экрана (может быть задано в программе FDOnAir). Обязательно будем использовать для остановки титровальных элементов, которые входят в скрипт.
override function Abort(fadeDuration : double) : boolean {
Debug.WriteLine("script Abort");
try {
// TODO: Abort logic
//return true;
} catch (ee) {
Debug.WriteLine("script Abort exception:" + ee);
}
return false;
}
Вызывается по прерыванию воспроизведения объекта. В параметре fadeDuration задается время исчезания объекта с экрана (может быть задано в программе FDOnAir). Это "жёсткая" остановка воспроизведения. Отличие от Stop можно видеть на примере поведение титровального элемента "Бегущая строка". В случае вызова Stop то объявление, которое сейчас показывается в эфире, доиграется до конца. Но следующее показано уже не будет. В случае вызова Abort воспроизведение текущего объявления оборвётся сразу.
override function LoadTask(task: String ) : boolean {
Debug.Print("LoadTask '{0}'.", task);
try {
// TODO: LoadTask logic
//return true;
} catch (ee) {
Debug.WriteLine("script LoadTask exception:" + ee);
return false;
}
return false;
}
Вызывается при загрузке задания в титровальный объект. В этой функции, например, можно прочитать данные из загружаемого файла, проверить их на валидность и т.д.
Целый ряд функций предназначен для передачи в программу OnAir всевозможной информации.

Изображение
override function GetTaskInfo(task : String): TaskInfoArgs
{
//if (System.IO.Path.GetExtension(task) == ".txt") {
// var info :TaskInfoArgs = new TaskInfoArgs()
// info.loopped = true;
// info.duration = 0;
// info.firstStop = 0;
// return info;
//}
return null;
}
Возвращает информацию о задании. "Место" использования помечено цифрой 6 на предыдущем рисунке.
override function GetLoopped() : TaskInfoArgs{
//var info = new TaskInfoArgs();
//info.loopped = true;
//return info;
return null;
}


Возвращает информацию о типе воспроизведения - зацикленное или незацикленное. "Место" использования помечено цифрой 2 на предыдущем рисунке.
override function GetPlayInfo() : PlayInfoArgs {
//var info = new PlayInfoArgs();
//Crawl.GetPlayInfo(&info);
//info.loopped = true;
//return info;
return null;
}
Возвращает в информацию о текущем состоянии воспроизведения. "Место" использования помечено цифрой 3 на предыдущем рисунке.
//override function GetTask( ) : String {
// return _task;
//}
Возвращает информацию о текущем загруженном файле-задании. "Место" использования помечено цифрой 5 на предыдущем рисунке.
//override function GetTaskMask( ) : String {
// return "Text Files (*.txt)|*.txt|";
//}
Возвращает информацию о типах файлов (расширениях), которые можно загружать в данный титровальный объект. "Место" использования помечено цифрой 4 на предыдущем рисунке.
//override function GetStatus(): LogotypeLib.SLTMRunTimeStatus {
// return TODO: ;
//}
Возвращает информацию о текущем состоянии воспроизведения. Используется для "подсвечивания" титровальных кнопок F9...

Следующие функции нужно переопределять если мы будем выставлять наружу свойства нашего скрипта.
override function GetProperties(): ScriptPropertyInfo[] {
//var list: ArrayList = new ArrayList();
//var info: ScriptPropertyInfo = new ScriptPropertyInfo();
//var i: int = 0;

//// 1. Общее время нахождения телефона на экране, вместе с въездом и выездом
//info.type = ScriptPropertyKnownTypes.eDouble;
//info.name = "PhoneTime";
//info.displayName = "PhoneTime";
//info.descr = "Общее время нахождения телефона на экране, вместе с въездом и выездом";
//info.category = "General";
//info.defaultVal = phoneStopSec;
//info.index = i++;
//info.attributes = ScriptPropertyFlags.Browsable;
//info.extra = null;
//list.Add(info);

//return ScriptPropertyInfo[](list.ToArray(info.GetType()));
return null;
}

override function SetPropertyValue(name : String, value : Object) {
//switch (name) {
//case "PhoneTime":{
// phoneStopSec = double(value);
// TODO: add your code for modify local variables
// break;
//case "Separator":
// phonesSplitter = String(value);
// break;
//case "GradientColor1":
// _GradientColor1 = Color(value);
// if (!_initState) {
// SetColor("GradientColor1", _GradientColor1);
// }
// break;

//}
}

override function GetPropertyValue(name : String) :Object {
//switch (name) {
//case "PhoneTime":
// return phoneStopSec;
// break;
//case "Separator":
// return phonesSplitter;
// break;
//case "GradientColor1":
// _GradientColor1 = GetColor("GradientColor1");
// return _GradientColor1;
//}
return null;
}
Свойства скрипта у нас будут. Например, нам нужно будет указывать длительность нахождения объявления на экране. И лучше всего это будет сделать именно через свойства скрипта. Поэтому к этим функциям мы обязательно вернёмся.

И последняя группа функций.
Они вызываются автоматически по событиям, связанным с показом титровальных элементов. В таких функциях можно включить какую-либо специализированную обработку событий, и по ним осуществлять какие-то действия. Например, по завершению показа какого-либо элемента запускать показ другого.
// notification from Elements
override function OnStatusChanged(name: String, index: int, oldStatus: LogotypeLib.SLTMRunTimeStatus, newStatus: LogotypeLib.SLTMRunTimeStatus) {
try {
if (oldStatus == newStatus) return;
// TODO: StatusChanged logic
} catch (ee) {
Debug.WriteLine("script OnStateChanged exception:" + ee);
}
}
Вызывается по изменению состояния (статуса) титровального элемента с именем name, номером index. В параметре oldStatus передается предыдущее состояние элемента, в newStatus — новое. Возможные состояния элемента:
LogotypeLib.eStopping — идет процесс остановки
LogotypeLib.ePreparing — идет процесс подготовки
LogotypeLib.eStopped — воспроизведение остановлен
LogotypeLib.eStarting — идет процесс запуска
LogotypeLib.eRunning — воспроизведение запущено

override function OnStopTimeChanged(elementName: String, index: int, newStopTime: double){
try {
// TODO: OnStopTimeChanged logic
} catch (ee) {
Debug.WriteLine("script OnStopTimeChanged exception:" + ee);
}
}
Вызывается по изменению времени остановки показа элемента с именем name, номером index. В параметре newStopTime передается новое время остановки элемента.
// notification from Elements
override function OnElementStart(name: String, index: int, id: int, time: double, firstStopTime: double, stopTime: double, text: String) {
Debug.WriteLine("===script OnElementStart:" + name + " index:" + index + " id:" + id + " time:" + time + " firstStop:" + firstStopTime + " stop:" + stopTime + " text:" + text);
try {
// TODO:
} catch (ee) {
Debug.WriteLine("script OnElementStart exception:" + ee);
}
}
Вызывается по запуску показа титровального элемента с именем name, номером index. В параметре time передается время старта, в параметре text — текст задания (последней его части, если их много; для бегущей строки — последнее объявление) для данного элемента. id — индекс части задания (например, очередное объявление в бегущей строке).
// notification from Elements
override function OnElementFinishing(name: String, index: int, id: int, time: double, text: String) {
Debug.WriteLine("===script OnElementFinishing:" + name + " index:" + index + " id:" + id + " time:" + time + " text:" + text);
try {
// TODO:
} catch (ee) {
Debug.WriteLine("script OnElementFinishing exception:" + ee);
}
}
Вызывается, когда начато завершение показа титровального элемента с именем name, номером index. Например, это происходит в момент, когда бегущая строка начинает «уезжать» с экрана (показывается ее последний кусок). В параметре time передается время начала завершения, в параметре text — текст задания (последней его части, если их много; для бегущей строки — последнее объявление) для данного элемента. id — индекс части задания (например, очередное объявление в бегущей строке).
// notification from Elements
override function OnElementStop(name: String, index: int, id: int, time: double, text: String) {
Debug.WriteLine("===script OnElementStop:" + name + " index:" + index + " id:" + id + " time:" + time + " text:" + text);
try {
// TODO:
} catch (ee) {
Debug.WriteLine("script OnElementStop exception:" + ee);
}
}
Вызывается по завершению показа (остановке) титровального элемента с именем name, номером index. Например, это происходит в момент, когда бегущая строка заканчивает «уезжать» с экрана. В параметре time передается время остановки, в параметре text — текст задания (последней его части, если их много; для бегущей строки — последнее объявление) для данного элемента. id — индекс части задания (например, очередное объявление в бегущей строке).

Часть из функций этой группы мы будем использовать.

Комментарии, вопросы и замечания просьба оставлять в специально для этого предназначенной ветке форума. Из этой ветки они будут удалены!
Последний раз редактировалось Даниленко Сергей 30 авг 2012 11:10, всего редактировалось 1 раз.
Даниленко Сергей
Сообщения: 7093
Зарегистрирован: 26 фев 2004 09:53
Откуда: Techsupport SoftLab-NSK

Сообщение Даниленко Сергей »

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

Часть 8. Работаем с Main.
Среди титровальных элементов нашего объекта есть Main.
Ранее про него было заявлено следующее:
Тип - "Подпись". Назначение - служебный элемент, в отображении принимать участие не будет. Служит для выдачи технической информации в программу OnAir. Информация такого рода: в каком сейчас состоянии находится весь объект (проигрывается, остановлен), зациклен объект или нет и т.д.
Давайте посмотрим как мы его можем использовать для этих целей.
Для начала выставим его свойства так, как надо нам. Делать это будем в функции Init, которая вызывается в конструкторе:
function init(){
_scriptingHost.add_CleanUp(CleanUp);

try {
// Add Your init code

} catch (ee) {
Debug.WriteLine("script init exception:" + ee);
}
}
Установку свойств делаем в блоке try-catch.
Для начала установим размер и положение на экране этого элемента.

Изображение

Т.к. он является чисто служебным, то его можно сделать маленьким и задвинуть куда-нибудь в уголок.
Устанавливаем размер:
function init(){
_scriptingHost.add_CleanUp(CleanUp);

try {

var Size : int[] = new int[2];
Size[0] = Size[1] = 4;
Main.Props["Size"] = Size;


} catch (ee) {
Debug.WriteLine("script init exception:" + ee);
}
}
Main.Props["Size"] - это обращение напрямую к свойству Size (Размер) титровального элемента. Про свойства титровальных элементов (какие у кого есть, как называются) специально поговорим в другой раз.

Устновим расположение Main:
function init(){
_scriptingHost.add_CleanUp(CleanUp);

try {

var Size : int[] = new int[2];
Size[0] = Size[1] = 4;
Main.Props["Size"] = Size;

var Location : int[] = new int[2];
Location[0] = Location[1] = 0;
Main.Props["Location"] = Location;


} catch (ee) {
Debug.WriteLine("script init exception:" + ee);
}
}
Аналогичным образом выставляем свойство Location (Позиция).

Запускаем программу FDTitleDesigner в режиме "превью". Видим, что Main располагается там, где мы хотели и с теми размерами, которые мы хотели.

Изображение

Есть ещё несколько мест, в которых можно сейчас добавить работу Main - это функции Start, Stop, Abort.

Для Start:
override function Start(atStart : double, fadeDuration : double) : boolean {
Debug.WriteLine("script Start");
try {

Main.LoadTask("", ETaskType.eTaskText);
Main.Start(atStart, fadeDuration);

return true;

} catch (ee) {
Debug.WriteLine("script Start exception:" + ee);
}
return false;
}
Main.LoadTask("", ETaskType.eTaskText) - загружаем задание типа "Text" (титровальный элемент "Подпись", которым является Main, может принимать строки напрямую).

Main.Start(atStart, fadeDuration); - командой Start запускаем на воспроизведение в указанное время.

Обязательно нужно вернуть true - нужно дать знать, что мы сами обработали команду Start.

Для Stop:
override function Stop(atStop : double, fadeDuration : double) : boolean {
Debug.WriteLine("script Stop");
try {

Main.Stop(atStop, fadeDuration);

return true;


} catch (ee) {
Debug.WriteLine("script Stop exception:" + ee);
}
return false;
}
Main.Stop(atStop, fadeDuration); - останавливаем воспроизведение в указанное время (atStop).

Обязательно нужно вернуть true - нужно дать знать, что мы сами обработали команду Stop.

Для Abort:
override function Abort(fadeDuration : double) : boolean {
Debug.WriteLine("script Abort");
try {

Main.Abort(fadeDuration);

return true;

} catch (ee) {
Debug.WriteLine("script Abort exception:" + ee);
}
return false;
}
Main.Abort(fadeDuration); - прерываем воспроизведение.

Обязательно нужно вернуть true - нужно дать знать, что мы сами обработали команду Abort.


Пока на этом всё. Работу с Main продолжим потом.

Текущая версия нашего объекта со скриптом здесь:
ftp://ftp.sl.iae.nsk.su/Public/ForwardT ... ard_p8.zip

Комментарии, вопросы и замечания просьба оставлять в специально для этого предназначенной ветке форума. Из этой ветки они будут удалены!
Последний раз редактировалось Даниленко Сергей 30 авг 2012 19:17, всего редактировалось 2 раза.
Даниленко Сергей
Сообщения: 7093
Зарегистрирован: 26 фев 2004 09:53
Откуда: Techsupport SoftLab-NSK

Сообщение Даниленко Сергей »

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

Часть 9. Свойства титровальных элементов.

Каждый элемент титровальной системы имеет свои свойства.

Изображение

По большому счёту свойства бывают двух типов: общие (присущие всем элементам) и частные (встречающееся только у какого-нибудь или у каких-нибудь).
Пример общих свойств: размеры титровального элемента, есть у каждого титровального элемента.
Пример частных свойств - скорость прокрутки, есть только у бегущей строки. Или свойство "Задание". Оно есть ппрактически у всех титровальных элементов за исключением SMS/SMS2/SMSRoll.
С другой стороны, свойства бывают разных типов: целое число, вещественное число, строка, путь к файлу, перечисление и т.д.

В предыдущей части мы уже работали со свойствами титровального элемента Main.
Доступ к свойствам осуществляется через поле Props титровального элемента.
Свойства можно устанавливать:
Main.Props["Size"] = Size;//устанавливаем размер

Свойства можно получать:
var bLoop: Boolean = Main.Props["Loop"];//узнаём о "зацикленности" элемента

К сожалению, в текущий момент времени в документации нет полной сводки свойств каждого титровального элемента и значений, которые они могут принимать. Поэтому я, например, поступаю следующим образом. Переключаю программу FDTitleDesigner на английский интерфейс. Как правило, название свойства в поле Props[] совпадает с его английским названием:
Main.Props["Location"], Main.Props["Size"].
Если нет однозначного понимания как должно называаться свойство, то делаем следующее:
Сохраняем титровальный проект, открываем его в текстовом редакторе и ищем как называется нужное свойство.
Например, нам нужно узнать как называется свойство "Горизонтальное выравнивание". Открыли проект.
Изображение

Ищем и не находим.

Это связано с тем, что в титровальный проект сохраняются только те свойства элементов, которые отличаются от свойств по умолчанию.
Поэтому в FDTitleDesigner меняем свойство "Горизонтальное выравнивание" на что-нибудь, отличающееся от того, что прописано по умолчанию и повторяем процедуру снова.

Изображение

В этот раз находим. Свойство называется HAlignment.

Кстати, значение, отличающееся отличающееся от значения "по умолчанию" в FDTitleDesigner выделяется жирным шрифтом - это видно на рисунке.

Свойство найдено. Хотим выставить "К правому краю". Какое значение ему нужно выставить из списка свойств?

Изображение

Данное свойство - это enum (перечисление). И нужное значение будет равно номеру строки в списке начиная с 0.
Для выравнивания "К правому краю" в нашем случае нужно поставить 2.

Main.Props["HAlignment"] = 2;

Комментарии, вопросы и замечания просьба оставлять в специально для этого предназначенной ветке форума. Из этой ветки они будут удалены!
Даниленко Сергей
Сообщения: 7093
Зарегистрирован: 26 фев 2004 09:53
Откуда: Techsupport SoftLab-NSK

Сообщение Даниленко Сергей »

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

Часть 10. Работаем с Main 2.

Продолжаем работу с Main. Мы его планируем использовать для передачи информации о состоянии всего титровального объекта в программу OnAir. Подробнее поясним чего мы хотим добиться.
Программа OnAir постоянно опрашивает состояние титровальных объектов. И титровальный объект постоянно должен эту информацию предоставлять. У нас в объекте кроме Main есть и другие титровальные элементы.
Но:
-Подложка (Background) может отсутствовать, т.е. её нельзя использовать для постоянной выдачи информации
-Картинки с информацией (Pic1, Pic2) могут отсутствовать, т.е. их нельзя использовать для постоянной выдачи информации
-Дополнительная текстовая информация (AdText1, AdText2) может отсутствовать, т.е. их нельзя использовать для постоянной выдачи информации

Осталась пара титровальных элементов типа "Подпись" для показа основного текста (MainText1, MainText2). Но и здесь есть трудности. Титровальных элементов пара. Один из них сейчас показывается, другой нет. Поэтому для передачи информации о состоянии объекта в OnAir нужно заводить дополнительный механизм для понимания кто сейчас из пары MainText1 и MainText2 должен рапортовать о состоянии всего объекта.
И вот здесь мы будем использовать Main. Поскольку по его поведению мы должны передавать информацию о состоянии титровального объекта в программу OnAir, то нужно, чтобы он "жил" всё время. Соответственно и выставим некоторые его свойства.
function init(){
_scriptingHost.add_CleanUp(CleanUp);
try {

//устанавлтваем размеры
var Size : int[] = new int[2];
Size[0] = Size[1] = 4;
Main.Props["Size"] = Size;

//устанавливаем положение
var Location : int[] = new int[2];
Location[0] = Location[1] = 0;
Main.Props["Location"] = Location;

//зацикливаем
Main.Props["Loop"] = 0;
//запрещаем въезд-выезд
Main.Props["Direction"] = 4;
Main.Props["OutDirection"] = 4;
//обнуляем проявление
Main.Props["FadeIn"] = 0;
Main.Props["FadeOut"] = 0;
//устанавливаем бесконечное время показа
Main.Props["StayTime"] = -1;
//устанавливаем скорость в 0
Main.Props["Speed"] = 0;
//устанавливаем паузу в 0
Main.Props["Pause"] = 0;

//задание у титровального элемента не должно сохраняться
//в титровальный проект, запрещаем редактировать задание
Main.SetTaskDummy(true);
//загружаем пустое задание
Main.LoadTask("", ETaskType.eTaskText);

//чтобы нужные нам свойства нельзя было редактировать
//запрещаем делать это
Main.SetPropertyDummy("Loop",true);
Main.SetPropertyDummy("Direction",true);
Main.SetPropertyDummy("OutDirection",true);
Main.SetPropertyDummy("FadeIn",true);
Main.SetPropertyDummy("FadeOut",true);
Main.SetPropertyDummy("StayTime",true);
Main.SetPropertyDummy("Speed",true);
Main.SetPropertyDummy("Pause",true);

//дополнительно запрещаем запись в лог-файл программы OnAir
Main.Props["LogEnabled"] = 0;
//запрещаем редактирование этого свойства
Main.SetPropertyDummy("LogEnabled",true);

} catch (ee) {
Debug.WriteLine("script init exception:" + ee);
}
}
С установкой свойств мы уже знакомы. Выставленные таким образом свойства заставляют элемент Main "жить" всё время пока живёт титровальный объект. В совокупности с нашими недавними изменениями в функциях Start, Stop, Abort это позволит правильно передавать информацию в программу OnAir.
Метод SetPropertyDummy("ххх",true) делает невозможным редактировать свойство ххх (read only). Метод SetTaskDummy(true) выполняет аналогичные действия, но для свойства "Задание".
Запускаем "превью" и видим, что свойства, которыми мы хотим управлять, выставлены в правильные значения. Кроме того, они недоступны для редактирования.
Изображение

Текущая версия нашего объекта со скриптом здесь:
ftp://ftp.sl.iae.nsk.su/Public/ForwardT ... rd_p10.zip


Комментарии, вопросы и замечания просьба оставлять в специально для этого предназначенной ветке форума. Из этой ветки они будут удалены!
Последний раз редактировалось Даниленко Сергей 31 авг 2012 18:19, всего редактировалось 1 раз.
Даниленко Сергей
Сообщения: 7093
Зарегистрирован: 26 фев 2004 09:53
Откуда: Techsupport SoftLab-NSK

Сообщение Даниленко Сергей »

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

Часть 11. Файл с заданием - определяем формат.

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

Для загрузки файла-задания существует специальная команда в программе OnAir. Кроме того, файл с заданием всегда загружается при загрузке титровального проекта в программе OnAir. Ну и можно в скрипте предусмотреть возможность автоматического перезачитывания файла с заданием где-нибудь при показе последнего объявления.

Выбор формата файла с заданием - это достаточно важная вещь.
Какой выбрать тип файла? Обычный простой txt? Или сразу же заложиться на на что-нибудь вроде xml?
С одной стороны, нужно всегда помнить о возможном расширении формата файла в дальнейшем. С этой точки зрения хорошо использовать форматы типа xml.
Но, с другой стороны, редактировать такие файлы вручную в "блокноте" достаточно сложно - всегда есть опасность "поломать" структуру файла. И в идеале нужно создавать какой-нибудь форматер (дополнительное приложение) для формирования задания для вашего скрипта. А это по определению дополнительные затраты труда программиста, и, соответственно, увеличение стоимости разработки и цены конечного продукта.
Простой текстовый файл с этой точки зрения проще. На нём и остановимся.

Будем использовать простой текстовый файл со строками следующего вида:
Основной текст | Дополнительный текст | Путь к графическому файлу

где:
Основной текст - присутствует всегда и показывается в одноимённой зоне
Дополнительныйтекст - может отсутствовать, в случае наличия будет также показываться в одноимённой зоне.
Путь к графическому файлу - файл может отсутствовать, если есть, то показывается в зоне "Графика". Путь к графическому файлу может быть абсолютным (полным) или относительным (коротким). "Относительность" определяется по пути к файлу с заданием для титровального объекта. Это значит, что если рядом с ним положить все картинки, то не нужно будет писать полный путь к файлу. Будет достаточно указать относительный (короткий путь). Зачастую достаточно будет ввести только название файла.

Символ | - разделитель полей внутри строки. В дальнейшем вынесем его как свойство скрипта, что даст возможность изменять этот параметр.

Каждая строка в файле - отдельное объявление.

Например:
БЕЗБОЛЕЗНЕННАЯ СТОМАТОЛОГИЯ.|264-31-08|F:\AVI\PRORES\bs.mov

Определим правила формирования строки в случае отсутствия дополнительных полей.

1)Если есть только основной текст, то никакие разделители можно не использовать.
Например:
БЕЗБОЛЕЗНЕННАЯ СТОМАТОЛОГИЯ. 264-31-08

2)Если нет графики, но есть дополнительный текст, то разделитель нужен.
Например:
БЕЗБОЛЕЗНЕННАЯ СТОМАТОЛОГИЯ. 264-31-08|ИМЕЮТСЯ ПРОТИВОПОКАЗАНИЯ.

3)Если нет дополнительного текста, но есть графика, то должны быть два разделителя.
Например:
БЕЗБОЛЕЗНЕННАЯ СТОМАТОЛОГИЯ.||F:\AVI\PRORES\bs.mov

Есть ещё один важный момент - расширение для файла с заданием. На первых порах (когда скриптов не так много) можно обходиться расширением txt. Но, в дальнейшем, это потенициально может привести к проблемам. Задания для всех скриптов имеют одно и то же расширение и неминуемо рано или поздно возникнет путаница. Поэтому для нашего скрипта будем использовать своё собственное расширение для файла. Например t4cb (task for CallBoard).

Комментарии, вопросы и замечания просьба оставлять в специально для этого предназначенной ветке форума. Из этой ветки они будут удалены!
Последний раз редактировалось Даниленко Сергей 06 сен 2012 15:40, всего редактировалось 2 раза.
Даниленко Сергей
Сообщения: 7093
Зарегистрирован: 26 фев 2004 09:53
Откуда: Techsupport SoftLab-NSK

Сообщение Даниленко Сергей »

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

Часть 12. Доопределяем функции, отвечающие за состояние титровального объекта.

Наш объект по поведению будет зацикленным. Так давайте честно об этом признаемся в методе GetLoopped.
override function GetLoopped() : TaskInfoArgs{

var info = new TaskInfoArgs();
info.loopped = true;

return info;

}
Структура TaskInfoArgs, некоторые поля которой мы заполняем, содержит информацию о текущем задании. В данном случае мы заполняем только одно из её полей - о свойстве "зациклить" нашего титровального объекта.

Возвращаем информацию о текущем состоянии загруженного задания.
override function GetPlayInfo() : PlayInfoArgs {

var info = new PlayInfoArgs();

Main.GetPlayInfo(&info);

info.loopped = true;

return info;

}
Часть данных возвращаемой структуры типа PlayInfoArgs заполняет наш специальный титровальный элемент Main. Информацию о "зацикленности" добавляем мы.

Возвращаем информацию о задании содержащемся в task. Сначала проверяем наше ли это задание - здесь как раз воспользуемся нашим расширением файла t4cb. Если наше, то заполняем поля структуры TaskInfoArgs, содержащей информацию о текущем задании.
override function GetTaskInfo(task : String): TaskInfoArgs
{
if (System.IO.Path.GetExtension(task) == ".t4cb")
{
var info : TaskInfoArgs = new TaskInfoArgs()

info.loopped = true;//зацикленно

//длительность задания оставляем пока равной 0
//вернёмся в дальнейшем к этому пункту
info.duration = 0;

//этот параметр также оставляем пока равным 0
//вернёмся в дальнейшем к этому пункту
info.firstStop = 0;

return info;
}

return null;
}

Возвращаем с помощью Main текущий статус.
override function GetStatus(): LogotypeLib.SLTMRunTimeStatus {
return Main.Status;
}
Функция GetTask( ) должна возвратить информацию о текущем загруженном файле с заданием. Для начала заведём специальную переменную для хранения текущего задания.
import SLTMTitleCommon.Scripting;
import LogotypeLib;

var script = new Script(titleRoot);

class Script extends SLTMTitleCommon.Scripting.ScriptBase {

var _Task : String = "";

function Script(obj)
{
super(obj);
//debugger
init();
}
:::::::::::::::
:::::::::::::::
:::::::::::::::
Значение переменной _Task присваиваем при загрузке задания.
override function LoadTask(task: String ) : boolean {
Debug.Print("LoadTask '{0}'.", task);

//Если файл не существует, то генерим exception
if(!File.Exists(task))
{
throw new FileNotFoundException(null, task);
}

try
{
//Присваеваем переменной, отвечающей
//за путь к файлу с заданием, значение
_Task = task;

return true;
}

catch (ee)
{
Debug.WriteLine("script LoadTask exception:" + ee);

return false;
}

return false;
}
Возвращаем информацию о текущем задании в программу OnAir
override function GetTask( ) : String
{
return String.IsNullOrEmpty(_Task) ? String.Empty : _Task; }
И в заключении возвращаем файловую маску для возможности выбора нашего типа файла (t4cb)
override function GetTaskMask( ) : String {
return "CallBoard Task Files (*.t4cb)|*.t4cb|"; }
Текущая версия нашего объекта со скриптом здесь:
ftp://ftp.sl.iae.nsk.su/Public/ForwardT ... rd_p12.zip

Комментарии, вопросы и замечания просьба оставлять в специально для этого предназначенной ветке форума. Из этой ветки они будут удалены!
Последний раз редактировалось Даниленко Сергей 06 сен 2012 15:08, всего редактировалось 1 раз.
Даниленко Сергей
Сообщения: 7093
Зарегистрирован: 26 фев 2004 09:53
Откуда: Techsupport SoftLab-NSK

Сообщение Даниленко Сергей »

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

Часть 13. Локализация.

Обычно мы у себя в компании разработку нового приложения ведём на английском языке (имеется ввиду GUI программ). После того, как интерфейс программы "устаканится", делается версия на русском языке. Т.е. производится локализация.
Локализацию можно делать и в титровальных скриптах.
Например, мы хотим, чтобы фильтр файлов при выборе файла-задания скрипта в программе FDTitleDesigner был или на русском языке (при русском GUI программы), или на английском (если выбран английский вариант GUI программы).

Вернёмся к методу GetTaskMask, который возвращает файловую маску для возможности выбора нашего типа файла (t4cb). Добавим локализацию фильтра файла.
override function GetTaskMask( ) : String {

//Узнаём текущий язык GUI в программе FDTitleDesigher
var lcid : int = System.Threading.Thread.CurrentThread.CurrentUICulture.LCID;

switch (lcid)
{
case 0x419 ://В случае если русский
return "Задания для скрипта CallBoard (*.t4cb)|*.t4cb|";

default: //В остальных случаях - английский
return "CallBoard Task Files (*.t4cb)|*.t4cb|";
}

}
Сначала определяем язык GUI в программе FDTitleDesigner. После этого возвращаем разные строки файловой маски в зависимости от языка.

Русский.
Изображение

Английский.
Изображение

Текущая версия нашего объекта со скриптом здесь:
ftp://ftp.sl.iae.nsk.su/Public/ForwardT ... rd_p13.zip

Комментарии, вопросы и замечания просьба оставлять в специально для этого предназначенной ветке форума. Из этой ветки они будут удалены!
Последний раз редактировалось Даниленко Сергей 06 сен 2012 16:18, всего редактировалось 2 раза.
Даниленко Сергей
Сообщения: 7093
Зарегистрирован: 26 фев 2004 09:53
Откуда: Techsupport SoftLab-NSK

Сообщение Даниленко Сергей »

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

Часть 14. Свойства титровального скрипта.

Каждый титровальный элемент имеет свой набор свойств, которые отображаются на соответствующей панели FDTitleDesigner.
Изображение

Титровальные скрипты также могут иметь свои собственные свойства (параметры).
Изображение

Есть два повода для того, чтобы использовать свойства скрипта.

1)Облегчить пользователю настройку скрипта для работы.
Например, в нашем скрипте есть четыре элемента, которые показывают текст (MainText1, MainText2, AdText1, AdText2). Для отображения текста в нашей титровальной системе используется файлы с коллекцией стилей (efc-файлы). Поэтому в каждом из четырёх элементов пользователю нужно будет её выбрать. Но если мы вынесем возможность указания коллекции стилей в качестве свойства (параметра) скрипта, то тогда это нужно будет сделать только один раз. А уже в самом скрипте можно предусмотреть синхронизацию свойств всех четырёх элементов для отображения текста - как только поменялось свойство "коллекция стилей", то сразу же меняются соответствующие свойства в титровальных элементах.

2)Дать возможность указать свойство, которое невозможно задать через какое-нибудь из стандартных свойств титровальных элементов.
Например, мы хотим в нашем скрипте вести логирование. Т.е. текст каждого вышедшего в эфир сообщения заносить в лог-файл с указанием даты и времени его выхода. Для этого нам нужно:
а)указать папку, в которую нужно скидывать лог-файлы
б)указать префикс к лог-файлу, чтобы их можно было как-то отличать от других файлов
в)дать возможность выбора "записывать/не записывать" лог-файл.
Но таких свойств в титровальных элементах нет. Вернее что-то похожее есть - свойство "Разрешить лог" присутствует во многих титровальных элементах. Но служит оно для разрешения записи не в наш лог, а в лог программы OnАir. Поэтому именно только в свойствах скрипта можно задать нужные параметры по поводу записи лога.

В настоящий момент времени в титровальных скриптах поддерживаются свойства следующих типов:
1.строка
2.целое число
3.вещественное число
4.путь к файлу
5.цвет
6.логическое (True/False)
7.перечисление (в версиях ПО начиная с релиза 5.4.0)
8.путь к папке (в версиях ПО начиная с релиза 5.4.0)


Пока в нашем скрипте свойств нет. Но они нам обязательно потребуются. Поэтому посмотрим как работают со свойствами в скриптах.

Чтобы свойство появилось и работало нужно сделать три шага:
1)Переопределить функцию с описанием свойства
override function GetProperties(): ScriptPropertyInfo[]

2)Переопределить функцию для получения свойства
override function GetPropertyValue(name : String) :Object

3)Переопределить функцию для установки свойства
override function SetPropertyValue(name : String, value : Object)

Начнём с описания свойства. Функция GetProperties() возвращает массив объектов типа ScriptPropertyInfo. Каждый из объектов содержит описание одного свойства. Сделаем импорт библиотек, позволяющих работать с массивами. В начало нашего скрипта добавим следующую строку:
import System.Collections;

После этого производим описание свойства:
override function GetProperties(): ScriptPropertyInfo[] {
//Создаём временный массив
var list: ArrayList = new ArrayList();
var i: int = 0;

//Создаём объект типа ScriptPropertyInfo, который будет содержать описание свойства.
var info: ScriptPropertyInfo = new ScriptPropertyInfo();

//Заполняем поля объекта с описанием свойств
//1.Подложка (фоновое статическое изображение или анимация)";

//Тип - файл
info.type = ScriptPropertyKnownTypes.eFileName;

//Внутреннее имя - только на английском языке
info.name = "Background";

//"Человеческое" название свойства для пользователя
info.displayName = "Background";

//Краткое описание
info.descr = "Background image / animation.";

//Поле extra позволяет задать файловую маску
//Пока мы её сформируем наполовину вручную, потом ещё раз вернёмся к этому вопросу.
//Сначала добавим статическую графику
info.extra = "All image files (*.png;*.bmp;*.dib;*.jpg;*.tga)|*.png;*.bmp;*.dib;*.jpg;*.tga";
//добавляем фильтр для анимации - берём непосредственно из самого титровального элемента
info.extra = info.extra + Background.GetTaskMask();

//Категория свойства - пока бывает только General
info.category = "General";

//Начальное значение - фона может не быть
info.defaultVal = "";

//Свойство можно редактировать
info.attributes = ScriptPropertyFlags.Browsable;

//добавляем объект с информацией во временный массив
list.Add(info);

//возвращаем массив объектов с описанием свойств
return ScriptPropertyInfo[](list.ToArray(info.GetType()));
}
Для получения и установки свойства нам нужна переменная, в которой будет храниться путь к файлу подложки.
В начале скрипта объявим её.
var script = new Script(titleRoot);

class Script extends SLTMTitleCommon.Scripting.ScriptBase {

var _Task : String = "";
var _Background : String = "";
function Script(obj)
{
super(obj);
//debugger
init();
}

::::::::::::::
::::::::::::::
Переопределяем функцию для установки свойства. Эта функция будет вызываться когда пользователь будет менять свойства скрипта.
override function SetPropertyValue(name : String, value : Object) {
switch (name) {

//Ищем нужное свойство по его info.name = "Background";
case "Background":{

//Присваиваем новое значение нашей переменной
_Background = String(value);
break;

}
}
}
Переопределяем функцию для получения свойства
override function GetPropertyValue(name : String) :Object {
switch (name) {

//Ищем нужное свойство по его info.name = "Background";
case "Background":

//Возвращаем значение
return _Background;

break;
}

return null;
}
Вот собственно и всё. Нажимаем в FDTitleDesigner кнопку "Превью" (без этого новые свойства не появятся). Выключаем режим "Превью".
В разделе "Параметры скрипта" видим наше свойство - Background со всеми заданными нами атрибутами.
Изображение
Текущая версия нашего объекта со скриптом здесь:
ftp://ftp.sl.iae.nsk.su/Public/ForwardT ... rd_p14.zip



Комментарии, вопросы и замечания просьба оставлять в специально для этого предназначенной ветке форума. Из этой ветки они будут удалены!
Даниленко Сергей
Сообщения: 7093
Зарегистрирован: 26 фев 2004 09:53
Откуда: Techsupport SoftLab-NSK

Сообщение Даниленко Сергей »

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

Часть 15. Локализация свойств скрипта.

Свойства скрипта можно локализовать. Внесём некоторые изменения в функцию GetProperties(), которая отвечает за описание свойств.
//Переопределяем функцию с описанием свойств
override function GetProperties(): ScriptPropertyInfo[] {

//Создаём временный массив
var list: ArrayList = new ArrayList();
var i: int = 0;

//Узнаём текущий язык GUI в программе FDTitleDesigher
var lcid : int = System.Threading.Thread.CurrentThread.CurrentUICulture.LCID;

//Создаём объект типа ScriptPropertyInfo, который будет содержать описание свойства.
var info: ScriptPropertyInfo = new ScriptPropertyInfo();

//Заполняем поля объекта с описанием свойств
//1.Подложка (фоновое статическое изображение или анимация)";

//Тип - файл
info.type = ScriptPropertyKnownTypes.eFileName;
//Внутреннее имя - только на английском языке
info.name = "Background";

switch (lcid){

//Русский язык
case 0x419:

//"Человеческое" название свойства для пользователя
info.displayName = "Подложка";
//Краткое описание
info.descr = "Фоновое изображение / анимация.";
//Поле extra позволяет задать файловую маску
//Пока мы её сформируем наполовину вручную, потом ещё раз вернёмся к этому вопросу.
//Сначала добавим статическую графику
info.extra = "Все графические файлы (*.png;*.bmp;*.dib;*.jpg;*.tga)|*.png;*.bmp;*.dib;*.jpg;*.tga";
//добавляем фильтр для анимации - берём непосредственно из самого титровального элемента
info.extra = info.extra + Background.GetTaskMask();

break;

//Английский язык
default:

//"Человеческое" название свойства для пользователя
info.displayName = "Background";
//Краткое описание
info.descr = "Background image / animation.";
//Поле extra позволяет задать файловую маску
//Пока мы её сформируем наполовину вручную, потом ещё раз вернёмся к этому вопросу.
//Сначала добавим статическую графику
info.extra = "All image files (*.png;*.bmp;*.dib;*.jpg;*.tga)|*.png;*.bmp;*.dib;*.jpg;*.tga";
//добавляем фильтр для анимации - берём непосредственно из самого титровального элемента
info.extra = info.extra + Background.GetTaskMask();
}

//Категория свойства - пока бывает только General
info.category = "General";
//Начальное значение - фона может не быть
info.defaultVal = "";
//Свойство можно редактировать
info.attributes = ScriptPropertyFlags.Browsable;
//добавляем объект с информацией во временный массив
list.Add(info);

//возвращаем массив объектов с описанием свойств
return ScriptPropertyInfo[](list.ToArray(info.GetType()));
}


Вот и всё. При русском языке интерфейса программы FDTitleDesigner свойства скрипта отображаются также по русски.

Изображение

Текущая версия нашего объекта со скриптом здесь:
ftp://ftp.sl.iae.nsk.su/Public/ForwardT ... rd_p15.zip


Комментарии, вопросы и замечания просьба оставлять в специально для этого предназначенной ветке форума. Из этой ветки они будут удалены!
Ответить