Caster Editor#
See also
This documents covers the editing of a Story Graph through the editor. For an introduction to the concepts of Gencaster, such as the editing and capabilities of the story graph, also take a look ot the Tutorial.
The editor is a website which allows to create and modify a Story Graph. It is possible that many users at once can collaboratively edit this story graph, and also the modifications will be applied in real time to an already running stream, which allows for live coding setups.
Script cells#
Script cells contain different kind of instructions which control what happens on the stream or the story graph. There are multiple types of script cells for different contexts.
Script cell type |
Description |
---|---|
Markdown |
Write text which will be transferred to a spoken text via a Text to Speech engine. The text can also be variable by using the value of a Stream variable. |
Audio |
Provides an interface to upload prepared audio files so that they can be played back on the stream. |
SuperCollider |
SuperColider is a framework for audio engine and Gencaster uses it to generate the audio stream.= It also contains the scripting language sclang which allows to adjust the auditory content on the stream. |
Python |
Python is a scripting language which allows to modify and interact with the story graph and also trigger e.g. PopUps on the Services. Anything that should be decided dynamically (e.g. day vs night) should be coded within Python. |
Markdown#
Markdown is a way to write formatted text in an easy but extensible manner.
The written text will be converted to audio via TextToSpeech
.
It is possible to make this text dynamic by using the value of a Stream variable within the text.
All custom Gencaster markdown macros are documented in GencasterRenderer
.
Examples#
Speak a text on the stream
By creating a markdown script cell and enter the text
Ich wünsch einen schönen Tag.
the text Ich wünsche einen schönen Tag will be spoken on the stream.
Add a break between words
Hallo {break}`300ms` dort.
Switch between voices
There is a variety of voces to choose from, which are documented in stream.models.TextToSpeech.VoiceNameChoices
.
The default voice is DE_NEURAL2_C__FEMALE
, but if we want to switch temporary to e.g. a male voice it is possible via
This is me and {male}`this is also another me`.
Todo
Switch between multiple speakers by their name.
Use the name of the user
First it is necessary to trigger a popup in the frontend so that the user can enter their name.
This is handled via a Python script cell, see trigger a popup via a python script cell which stores the name under the Stream variable name
.
To use this name
within a Markdown cell can be archived via
Hello {var}`name`. I hope you are doing fine.
where the ${var}`name will be replaced with the name provided through the popup, so for example Hello Alice. I hope you are doing fine.
Audio#
An audio cell allows to playback a AudioFile
on the stream in two ways
async
will playback in the background and the story graph will continue with the executionsync
will pause the execution of the story graph until the file has been played back fully.
The volume slider controls the volume of the audio on the stream.
The edit button allows to change the associated audio file by uploading a new file or search through existing files.
Python#
Python is an universal scripting language and allows to
interact with the graph (e.g. set next node)
assign or access a Stream variable
trigger dialogs on the frontend
Examples#
Wait until user clicks on “Start” button
When a user visits the story graph via the Frontend a first popup will be displayed which asks if the user wants to start streaming audio. This is necessary due to Autoplay restrictions in browsers which require a user interaction to playback any audio.
So in order to wait until the user hears audio (which will happen after the user clicks on start) the following snippet can be used.
await wait_for_stream_variable('start')
The execution is async which allows to wait for something to happen, for example waiting for a Stream variable like in this case.
For more technical details see wait_for_stream_variable()
.
Access a stream variable
A Stream variable can be accessed through the vars
dictionary.
# will return None if not set
name = vars.get('name')
Set a stream variable
Assigning a Stream variable to a value is possible by using the vars
dictionary
vars['is_day'] = 8 < datetime.now().hour < 20
Important
Although this statements results in a boolean value, a stream variable can only represent a string as it gets shared with many languages.
Create popup which asks for the name
To trigger a dialog in the frontend use the yield
command with a Dialog
instance.
The exact arguments are documented in Frontend Types.
yield Dialog(
title="Headline",
content=[
Text(text="Can we ask for your name?"),
Input(label="Name", key="name"),
],
buttons=[Button.cancel(), Button.ok()],
)
# wait for user input
await wait_for_stream_variable("name")
This will save the value that was inserted by the user into tho variable name
.
SuperCollider#
A SuperCollider cell allows to directly control what happens in the audio domain of the stream. The language used for this is sclang and the dialect of choice is the *JITlib* dialect, although any other style is also possible, but may require more management.
Although sclang is a non-blocking language, it is possible to wait
within a Script Cell and it is the easiest way to wait some time.
Wait 10 seconds
The following snippet will fade in over 10 seconds and after this will fade out within 1 second.
Ndef(\drone, {
SinOsc.ar(LFDNoise1.kr(0.1!2).exprange(100, 400)) * \amp.kr(0.2);
}).fadeTime_(10.0).play;
10.0.wait;
Ndef(\drone).stop(fadeTime: 1.0);
Comment#
A comment will be ignored for execution, but allows to add commentary on a node.