在我们的创作工作流中,DigiShow 主要充当一个能配接各种媒体控制信号的控台,并通过信号映射的方法来与其他创作软件共同完成演艺节目的制作。在这个过程中,一般并不需要代码编程,这也是 DigiShow 的一项重要特色。然而,DigiShow 还为习惯代码编程的用户提供了更多可能。
从 DigiShow 1.5 版本后开始支持基于 JavaScript / Qml 的表达式功能和脚本环境。通过一些比较简单的 JavaScript 编程就能大大提升 DigiShow 在实现互动逻辑方面的能力,也能把一些本来需要与外部软件协同完成的功能简化为只需要使用 DigiShow 一个软件就能完成。
本节课内容系针对具有一定 JavaScript 编程能力的人士,其他人亦可做一般了解。
在任何信号条的输入端或输出端都可以为它添加一个JS表达式:
我们来做个实验,先在信号条的输入端选择 Hot Key 接口;在信号条的输出端选择 Virtual Pipe 接口,并选定 Analog 通道 1。
此时,便会出现一个用于输入表达式的 fx 文本框
在 fx 文本框中输入表达式, 即一个能使信号数值发生改变的计算公式,其中可以包含一些特定的变量、数字、数学运算符、数学函数等。此处的表达式需要符合 JavaScript (JS) 语言的语法。
= value
在此例中,按下 Hot Key 键时信号状态为 1,松开键时信号状态为 0。
= !value
在此例中,按下 Hot Key 键时信号状态为 0,松开键时为 1。
完成表达式编写后请按回车键确认。
= 1
在此例中 Hot Key 按键一旦被触动,信号状态将被锁死在 1 状态。
= value ? !lastValue : null
在此例中它的作用是:按一下按键信号状态变1,再按一下按键信号状态变0,如此继续再按一下按键就会再反转一次信号状态。
在此表达式中,? : 运算符用于条件判断并返回不同的值,其语法是:
<判断条件> ? <条件判定为真时的返回值> : <条件判定为假时的返回值>此表达式的执行逻辑是:当按下按键时,value 等于 1 (为真),返回 !lastValue;当松开按键时,value 等于 0 (为假),返回 null,即信号状态数值不作改变。
变量 lastValue 指代在输入发生改变前信号数值,!lastValue 即表示反转上一次的信号状态数值。
= range*Math.random()
= value ? range*Math.random() : 0
此例中的表达式可以略作优化为:value ? range*Math.random() : 0
与 Hot Key 信号输入端链接使用后,按下按键时信号输出端生成一个随机数,松开按键后信号输出端数值回零。
总结一下,在表达式中可以包含一些最常用的变量:
在表达式中可以用到两个常用函数来获取其他信号条上的信号数值:
= value+outputValueOf('Base Level')
举例说明,在信号条的输出端编写表达式:value+outputValueOf('Base Level')
信号输出数值需要由此表达式计算后获得,此表达式表示:需要在该信号的原数值中加入 Base Level 的设定数值,然后再输出。
在信号链接表中新增额外的一行信号条,在它的输出端选择 Virtual Pipe 接口,并选定 Analog 通道 2。然后记得还需要修改此信号条的标题为 Base Level。
现在请移动此信号条中的推杆,来设定 Base Level 的数值。
当移动信号条中的推杆,或在信号条中的输入端信号发生变化触发输出端信号更新时,表达式即会执行计算,并输出计算获得的模拟量数值。
在表达式中可以调用两个常用函数,用来在软件窗口中显示提示信息:
alert() 和 toast() 也常用于在表达式或脚本中进行代码调试时的信息提示。
表达式中可以包含多个语句,语句与语句之间需要用 ; 分号来进行分割,最末一句用于返回由表达式计算获得的数值。如:alert("value = " + value); value
= alert("value = " + value); value
= toast("ratio = " + (value/range*100).toFixed(2) + "%"); value
当需要在表达式中实现较复杂或重复性的逻辑时,通常就得事先构建自己的自定义函数,然后再在表达式中调用。这时就需要来为你的 DigiShow 工程创建一个脚本文件,以便在其中编写自定义函数的程序代码。
示例:
DigishowScriptable {
function onValueChanged(value) {
if (value < 32) {
setOutputValueOf('R', 127)
setOutputValueOf('G', 255)
setOutputValueOf('B', 64)
} else if (value < 64) {
setOutputValueOf('R', 255)
setOutputValueOf('G', 64)
setOutputValueOf('B', 127)
} else if (value < 96) {
setOutputValueOf('R', 64)
setOutputValueOf('G', 127)
setOutputValueOf('B', 255)
} else {
setOutputValueOf('R', 0)
setOutputValueOf('G', 0)
setOutputValueOf('B', 0)
}
return value
}
}
当此信号条输出端发生信号状态变化时,便会执行它所绑定的表达式:onValueChange(value)
在此例中 onValueChange() 函数的定义保存在与当前工程绑定的附加脚本文件内。在脚本中可以调用函数:setOutputValueOf(name, value)
用于改变标题为 name 的信号条的输出端数值为 value。
在 DigiShow 中保存工程后,就可以为这个工程再创建一个附加的脚本文件。
一旦 DigiShow 工程启动后,其附带的脚本文件也会一并载入,脚本中定义的各个函数、属性(变量)都可以在信号端表达式中得到应用。
在脚本文件中一般还包含两个特殊的函数,onStart() 时在工程启动时被系统调用,onStop() 是在工程停止时被系统调用。你可以按自己的需要来修改其中的代码实现。
示例:
DigishowScriptable {
function onStart() {
toast('The scriptable module is started.')
}
function onStop() {
alert('The scriptable module is stopped.')
}
}
DigiShow 脚本文件采用 Qml (Qt Modeling Language) 脚本语言规范。
在脚本中,你可以在 DigishowScriptable { … } 代码段中用 JavaScript 语言来编写你的函数,也能用 Qml 的语法来声明属性(变量)。此脚本环境中还能调用到更为丰富的 DigiShow 功能,例如:
app.slotTitled('test').setSlotOption('outputSmoothing', 1000)
即将标题为 test 的信号条中的信号映射参数 Output Smoothing 设为 1000 毫秒
关于更多关于表达式和脚本环境中的编程参考,可参考:
https://github.com/robinz-labs/digishow/blob/master/guides/expression.zh_CN.md