Stupeflix Video Description Language (SXML) Documentation¶
Introduction¶
The Stupeflix Video Description Language is an XML language (called SXML below).
It is intended to be as simple as possible to create videos, yet powerful enough to allow complex projects. It was designed around several fundamental ideas:
- it is XML, and fully human readable
- it is 4D
- it is vector-based
The language uses the Craftsman 1.0 API schema.
XML, and fully human readable¶
A lot of software claims that they are able to export XML documents. Sometimes it is true and sometimes the XML contains actually chunk of binary data, in hexadecimal form, if you are lucky. That’s not the most useful form of XML most developers would say.
So even if in the end most of our customers use scripts to generate SXML bits, the XML is always human readable. So, you can understand and debug it easily. You can share snippets of XML to show how to create a nice effect you designed. You can use all the standard tools to create XML or to process it. XSLT stylesheets are for example a good way to build video templates that will transform your data into a SXML file.
The description hierarchy is a good fit with the XML node hierarchy, and I hope you will find it natural to use. I do, but you know, I am not really that objective on this subject.
And, finally, you can even decide to rewrite a video rendering engine using the same XML language of you want. Don’t forget to contact us if you do so!
More seriously, your projects will have some chance to be used in another place, in another time, outside the Stupeflix platform.
4D¶
Everything is 3D in SXML, even 2D elements. And even more, everything is 4D, as everything can be animated.
So, if you decide to animate your scene, your 2D elements will in fact reveal as 3D planes, just as every other ones. In a similar way, if you decide to alter filters parameters throughout a sequence, just add an animator as child element in the XML. Each node in the hierarchy can be animated: think of the SXML as a large scene graph, so if you animate one node, all sub-elements will move in 3D.
Vector based video description¶
Vector based graphics are well known. That means that you can scale up them without a loss of precision. In the SXML language, the fundamental idea is the same. However, the idea is pushed a little bit further.
The same SXML file can be used to generate different videos, at different resolution. That’s nice, that’s exactly the kind of things Vector based graphics are good at. BUT, an issue quickly emerges: what about aspect ratio? How do you render the video with a 16:9 ratio for a plasma screen, a 4:3 ratio for a web video, or 3:2 ratio for an iPhone? Do you stitch the video? It would be ugly.
The answer is that everything in the language should be liquid to adapt to the video aspect ratio, much more a web page than classical vector graphics. When you position your overlays, you specify margins, just like in CSS. When you add images in an effect, their aspect ratio is kept. When you use animators, you can ignore the screen ratio and just say “slide-in” or “slide-out”.
But maybe the most important concept is about time: you won’t find any timeline in the SXML. Instead, you can nest video sequence in the language itself, and container duration will be computed from its content. For example, you want to create videos using a fixed template and with some voice over. The voice over duration is different each time. In a standard timeline based video editor, you would have to move around video elements to adapt to the new audio duration. With the SXML, just includes the voice over, its duration will be detected before rendering starts, and propagated throughout the full video description. You can even download the XML with every node annotated with duration information, just by using a special API call, for debugging purpose for example.
You will see throughout the upcoming tutorials other examples of this important concept.
Example¶
Let’s start with an example of a very simple but yet valid movie definition.
<movie service="craftsman-1.0">
<body>
<stack>
<effect type="kenburns" duration="2.5">
<image filename = "http://assets.stupeflix.com/code/images/Ha_long_bay.jpg"/>
</effect>
<effect type="panel" duration="5.0">
<image filename = "http://assets.stupeflix.com/code/images/Canyon_de_Chelly_Navajo.jpg"/>
</effect>
<audio filename="http://dl.dropbox.com/u/1524046/Music/Catch_a_Marvel.mp3" fadeout="2" />
<text type="legend">Welcome to the desert.</text>
</stack>
<effect type="flower" duration="5.0">
<image filename = "http://assets.stupeflix.com/code/images/Monument_Valley.jpg"/>
</effect>
</body>
</movie>
This xml description produce a movie made of two parts: - first part with a stack of several elements : fullscreen foreground with a kenburns effect disappearing after 2.5 seconds, and fullscreen background with a panel effect, plus a text effect on top of it. An audio track is added, with a fadeout of “2s”. - second part, a single flower effect, with no audio Let’s see now how to build a video using this service.
Stupeflix XML Language¶
To describe a movie, we will start by defining atoms, that creates a video stream or an audio stream, and operators to compose these elements. Operators transform one or several video/audio streams into one stream which can be further combined with other streams.
Atoms¶
Atoms are responsible for generating a single video / audio stream directly from assets. They define a stream of audio or video (or both) with a fixed duration. They will be combined on the fly by the video generator.
Available atoms are:
effect
Can be used to turn one or several images or video assets (image and video tags) into a video stream (with optional audio stream).
text
Turn a text into a video stream, using some kind of text rendering effect.
audio
Turn an audio asset into an audio stream.
overlay
Add an overlay on top of an existing scene.
Note
Image and video tags are not directly atoms, as the effect is responsible to handle aspect ratio adaptation if the input image or video aspect ratio is different from the generated video.
Operators¶
An operator combines several audio/video streams into a single one.
Available operators are:
sequence
This operator takes a set of streams and just concatenate them in time. The related tag is sequence, or body : top level tag is a sequence.
stack
This operator takes a set of streams and display them together. The display order is the xml order : first in the list, first to be drawn, and so may be partially hidden by subsequent draws.
Note
A stack or a sequence or effect can contain atoms, sequences, and stacks.
Effects¶
You will find a complete descriptions of parameters for each kind of effects in Effects parameters.
A typical effect tag looks like:
<effect type="diving" duration="5.0" >
<image filename="http://assets.stupeflix.com/code/images/Ha_long_bay.jpg"/>
<image filename="http://assets.stupeflix.com/code/images/Canyon_de_Chelly_Navajo.jpg"/>
<image filename="http://assets.stupeflix.com/code/images/Monument_Valley.jpg"/>
</effect>
Transitions¶
A transition tag can only be inserted in a sequence tag (or in the body tag). It uses the previous and the next video sequences provided, overlap them (reducing the sequence total duration), and so generate a new video stream. Previous and next video sequences can be any video stream: effect or stack of complex effects.
You will find complete documentation and demonstration for each kind of transition in the developers’ library:.
A typical transition tag looks like :
<transition type="move" direction="down" duration="1" />
Text¶
Attribute | Presence | Description |
---|---|---|
type | required | the type of text effect. The available types are “legend”, “zone”, and “advanced” |
duration | optional | the duration of the text tag (optional because it may be inferred from the enclosing stack tag). |
The text to be displayed is then contained in the text tag:
<text type="legend">Here is the text to be displayed</text>
The basic tutorial on text and effects/animations are right there Text effects. More advanced text rendering method is explained there Advanced Text Rendering. And here is the list of available fonts.
Audio¶
Attribute | Presence | Description |
---|---|---|
filename | required | an url |
duration | optional | overrides the audio file original duration |
fadein | optional | starts the audio track with a fade in of the specified duration |
fadeout | optional | ends the audio track with a fade out of the specified duration |
skip | optional | skip the specified duration in the input file |
margin-start | optional | starts the audio track with the specified delay (full duration is usually given by a enclosing node) |
margin-end | optional | ends the audio track with the speficied delay before the end (full duration given by the enclosing node) |
margin-both | optional | sets both margin. This is exclusive of other “margin” attributes |
volume | optional | arbitrary float, sets the volume (default is 1.0) |
An audio entry example:
<audio filename="thriller.mp3" fadein="1.0" fadeout="4.0" skip="2.0" />
Here is a small example on how to use margins:
<movie service="craftsman-1.0">
<body>
<stack>
<effect type="panel" duration="15.0">
<image filename = "http://assets.stupeflix.com/code/images/Ha_long_bay.jpg"/>
</effect>
<audio filename="http://dl.dropbox.com/u/1524046/Music/Catch_a_Marvel.mp3" fadeout="2.0" margin-both="2.0" />
</stack>
</body>
</movie>
In that case, the stack tag is assigned the only specified duration, 15.0 seconds. So the audio margins apply on that duration, and audio track is composed of: * 2.0 seconds of silence * 9.0 seconds of music * 2.0 seconds of fade out * 2.0 seconds of silence
For a total of 15.0 seconds.
Images¶
Attribute | Presence | Description |
---|---|---|
filename | required | an url. |
color | required | the “#” char followd by a 6 or 8 long RGB(A) hexadecimal string |
So an image examples are:
<image filename="lena.jpg"/>
<image color="#ff0000"/>
<image color="#ffffff88"/>
You can too query some Maps to get directly a map image from our provider Mapbox.
The arguments are center (latitude and longitude) to position the map, zoom (0 means no zoom, you get the whole planisphere), pixel size and an optional marker (latitude and longitude).
An example movie xml is:
<image type="map" center="51.526389,-0.160833" zoom="13" markers="51.526389,-0.160833" size="640x640"/>
Supported formats for images are non interlaced pngs, jpeg and non animated gifs.
Videos¶
Attribute | Presence | Description |
---|---|---|
filename | required | an url. |
The most common formats are supported (mpeg2 mpeg4, h264) , for more details see Supported Ffmpeg codecs .
Example:
<video filename="sunset.mpg"/>
Filters¶
You will find a complete descriptions of parameters for each kind of filter in the developers’ library.
Tutorials¶
Masking¶
Masking & Keying¶
Masking and Keying are very important compositing operators. They are used everywhere, from the weather forecast clip to blockbusters. The basic idea is to let a given color become transparent when you compose an image on top another one. There are two ways to proceed in the SXML language.
Applying a mask transform an existing image and set some color to partly or totally transparent. The mask itself is a bicolor image, one being the opaque one, and the other one is transparent. Any intermediary color will result in a partly transparent color.
So, when you apply a mask on an image, it just modifies the alpha channel of it. It is particularly useful as video do not usally have an alpha channel.
Finally, you can apply it in two ways: on a single image, or on the full screen.
Image filtering¶
Here are the media we are using. First the video to be displayed: sts120_launch.mov.
Then the mask wbmask.mp4.
We combine it using a filter with type “mask”. White will be opaque, whereas black will be fully transparent:
<overlay duration="10.0" top="0.1">
<video filename="http://assets.stupeflix.com/code/tutorials/masking/sts120_launch.mov">
<filter type="mask" opaqueColor="#ffffff" transparentColor="#000000">
<video filename="http://assets.stupeflix.com/code/tutorials/masking/wbmask.mp4"/>
</filter>
</video>
</overlay>
In fact we used SXML too to build the mask :
<stack duration="10">
<overlay right="0.15" width="0.45" top="0.15" height="0.45">
<image color="#ffffff"/>
<animator type="slide-in" duration="1.0" direction="left"/>
<animator type="slide-out" duration="1.0" direction="up"/>
<animator type="grow" growEnd="0.7"/>
</overlay>
<overlay left="0.10" width="0.45" top="0.10" height="0.45">
<image color="#ffffff"/>
<animator type="slide-in" duration="1.0" direction="down"/>
<animator type="slide-out" duration="1.0" direction="left"/>
<animator type="grow" growEnd="0.7"/>
</overlay>
<overlay left="0.15" width="0.45" bottom="0.10" height="0.45">
<image color="#ffffff"/>
<animator type="slide-in" duration="1.0" direction="up"/>
<animator type="slide-out" duration="1.0" direction="left"/>
<animator type="grow" growEnd="0.7"/>
</overlay>
<overlay right="0.10" width="0.45" bottom="0.15" height="0.45">
<image color="#ffffff"/>
<animator type="slide-in" duration="1.0" direction="left"/>
<animator type="slide-out" duration="1.0" direction="down"/>
<animator type="grow" growEnd="0.7"/>
</overlay>
</stack>
And finally, if we want to, we can combine the xmls into a single one, as we can nest filters and rendering nodes (stack, sequence, overlay, effect etc).
<overlay duration="10.0" top="0.1">
<video filename="http://assets.stupeflix.com/code/tutorials/masking/sts120_launch.mov">
<filter type="mask" opaqueColor="#ffffff" transparentColor="#000000">
<stack duration="10.0">
<overlay right="0.15" width="0.45" top="0.15" height="0.45">
<image color="#ffffff"/>
<animator type="slide-in" duration="1.0" direction="left"/>
<animator type="slide-out" duration="1.0" direction="up"/>
<animator type="grow" growEnd="0.7"/>
</overlay>
<overlay left="0.10" width="0.45" top="0.10" height="0.45">
<image color="#ffffff"/>
<animator type="slide-in" duration="1.0" direction="down"/>
<animator type="slide-out" duration="1.0" direction="left"/>
<animator type="grow" growEnd="0.7"/>
</overlay>
<overlay left="0.15" width="0.45" bottom="0.10" height="0.45">
<image color="#ffffff"/>
<animator type="slide-in" duration="1.0" direction="up"/>
<animator type="slide-out" duration="1.0" direction="left"/>
<animator type="grow" growEnd="0.7"/>
</overlay>
<overlay right="0.10" width="0.45" bottom="0.15" height="0.45">
<image color="#ffffff"/>
<animator type="slide-in" duration="1.0" direction="left"/>
<animator type="slide-out" duration="1.0" direction="down"/>
<animator type="grow" growEnd="0.7"/>
</overlay>
</stack>
</filter>
</video>
</overlay>
Scene Post-Processing¶
As we just saw, you can apply mask to a single image, in an overlay, text or effect.
But you can apply it too as a postprocessing. In that case it will be full screen, and you apply it every rendering node (text, overlay, effect, stack, sequence).
You can see the result at fullscreen_mask_video.mp4.
<stack duration="10.0">
<filter type="mask" opaqueColor="#ffffff" transparentColor="#000000">
<video filename="http://assets.stupeflix.com/code/tutorials/masking/wbmask.mp4"/>
</filter>
<effect type="sliding">
<image filename="http://assets.stupeflix.com/code/homevideo/images/wiki_Double-O-Arch_Arches_National_Park_2.jpg"/>
<image filename="http://assets.stupeflix.com/code/homevideo/images/wiki_Hopetoun_falls.jpg"/>
<image filename="http://assets.stupeflix.com/code/homevideo/images/wiki_Lightning_over_Oradea_Romania_3.jpg"/>
<image filename="http://assets.stupeflix.com/code/homevideo/images/wiki_Hopetoun_falls.jpg"/>
<image filename="http://assets.stupeflix.com/code/homevideo/images/wiki_Double-O-Arch_Arches_National_Park_2.jpg"/>
</effect>
</stack>
As previously, you can insert inline a rendering node instead of the wbmask video, for example a stack containing several overlays.
Audio, Voice Over & Text-To-Speech¶
Audio¶
What would be video without audio? Fortunately, handling multiple audio tracks is built-in the SXML.
So what can you do?
- integrate an arbitrary number of audio tracks in the stack-sequence hierarchy
- superpose several audio tracks at the same time
- adjust volume
- add fade-in / fade-out effects
- skip the first n seconds in the audio track
In addition, you can also produce audio tracks, using speech synthesis. Finally, by default, every video you add in an effect or an overlay come with its own audio track, which is mixed by default with the other audio tracks.
Basic use, and a common mistake¶
You may want to add an audio track to your video using something similar to:
<movie service="craftsman-1.0">
<body>
<effect type="diving">
<image filename="http://assets.stupeflix.com/code/homevideo/images/wiki_Double-O-Arch_Arches_National_Park_2.jpg"/>
<image filename="http://assets.stupeflix.com/code/homevideo/images/wiki_Hopetoun_falls.jpg"/>
<image filename="http://assets.stupeflix.com/code/homevideo/images/wiki_Lightning_over_Oradea_Romania_3.jpg"/>
</effect>
<audio filename="http://assets.stupeflix.com/code/tutorials/audio/soundtracks/Flypaper.mp3"/>
</body>
</movie>
But this is not the way it works : just see the result at audio_sequence.mp4.
The “body” xml node is a sequence, and so the audio will be played after the effect finishes, not at the same time. The effect will use its default duration, 5 seconds.
So the correct way to do so is to add a stack to your xml and place your effect and your audio in it.
<movie service="craftsman-1.0">
<body>
<stack>
<effect type="diving">
<image filename="http://assets.stupeflix.com/code/homevideo/images/wiki_Double-O-Arch_Arches_National_Park_2.jpg"/>
<image filename="http://assets.stupeflix.com/code/homevideo/images/wiki_Hopetoun_falls.jpg"/>
</effect>
<audio filename="http://assets.stupeflix.com/code/tutorials/audio/soundtracks/Flypaper.mp3"/>
</stack>
</body>
</movie>
Just remember this point, and using audio will be really easy.
Here is the result: audio_fullduration.mp4.
As you can see, the total duration of the video is 3:20, the duration of the music.
Is this really what we wanted? Not really. So, let see how to change this.
Multiple tracks: audio as slave¶
So how can you add several audio at the same time, and how do you force them to adopt the length of the rest of video elements? Just use the xml structure to do so:
<movie service="craftsman-1.0">
<body>
<!-- All music by Josh Woodward, The Simple Life -->
<stack>
<effect type="diving" duration="10">
<image filename="http://assets.stupeflix.com/code/homevideo/images/wiki_Double-O-Arch_Arches_National_Park_2.jpg"/>
<image filename="http://assets.stupeflix.com/code/homevideo/images/wiki_Hopetoun_falls.jpg"/>
</effect>
<audio filename="http://assets.stupeflix.com/code/tutorials/audio/soundtracks/Flypaper.mp3" duration=".." fadein="2"/>
</stack>
<transition type="swirl" duration="2.0"/>
<stack>
<effect type="square" duration="15">
<image filename="http://assets.stupeflix.com/code/homevideo/images/wiki_Hopetoun_falls.jpg"/>
<image filename="http://assets.stupeflix.com/code/homevideo/images/wiki_Double-O-Arch_Arches_National_Park_2.jpg"/>
</effect>
<audio filename="http://assets.stupeflix.com/code/tutorials/audio/soundtracks/ImLettingGo.mp3" duration=".." fadeout="2"/>
</stack>
</body>
</movie>
You can find the result here : audio_slave.mp4.
This way, the audio is bound to play with the effect.
Note the duration=".."
directive in the audio tags: it bounds the duration of the audio track to its parent xml node duration. The stack will look for its children to determine its duration, and so it will ignore the audio tag, as this latter rely itself on its parent. So, that’s the effect node that fix the duration. If you remove this directive, the effect and the stack node duration will be fixed by the audio duration.
You can see some sample use of fadein and fadeout directives.
Note that the transition has an effect on audio too : it creates automatically a crossfade between the two soundtracks.
Multiple tracks: audio as master¶
So, adding a soundtrack is easy. But what about adding a voiceover when you do not know how long it is because it’s created using text to speech? You can play with durations the other way round:
<movie service="craftsman-1.0">
<body>
<!-- All music by Josh Woodward, The Simple Life -->
<stack>
<effect type="diving">
<image filename="http://assets.stupeflix.com/code/homevideo/images/wiki_Double-O-Arch_Arches_National_Park_2.jpg"/>
<image filename="http://assets.stupeflix.com/code/homevideo/images/wiki_Hopetoun_falls.jpg"/>
</effect>
<audio filename="http://assets.stupeflix.com/code/tutorials/audio/soundtracks/Flypaper.mp3" duration=".." fadein="2" fadeout="2" volume="0.1" skip="5"/>
<audio voice="neospeech:julie" margin-end="2.0">Music by Josh Woodward, Flypaper, from the album The Simple Life. Available on Jamendo dot com. Images from Wikipedia Picture of the Day.</audio>
</stack>
</body>
</movie>
Here is the result: audio_master.mp4.
In that sample, the music duration is set to ”..” , as previously. But we removed the duration from the effect. So, what is the duration of the stack, effect, and music? It’s the duration of the last audio track, the voice over. Duration is obtained from the audio file produced by the speech synthetizer. Note the margin-end added to the voice over, to allow some extra time at the end of the voice over and before the end of the video. You can add the same way a “margin-start” directive if you want. Finally, we used the volume directive on the music, to put the emphasis on the voice rather than on the music, and we skipped the first 5 seconds of the music.
Audio sequences¶
You can easily concatenate different audio tracks. Just create as sequence of audio files. Here we use speech synthesis, but it is exactly the same with standard audio files.
<movie service="craftsman-1.0">
<body>
<stack>
<effect type="diving" duration="10">
<image filename="http://assets.stupeflix.com/code/homevideo/images/wiki_Double-O-Arch_Arches_National_Park_2.jpg"/>
<image filename="http://assets.stupeflix.com/code/homevideo/images/wiki_Hopetoun_falls.jpg"/>
</effect>
<sequence>
<audio voice="neospeech:julie">Hello.</audio>
<audio voice="neospeech:paul">Who are you?</audio>
<audio voice="neospeech:julie">I am Julie. Don't you remember?</audio>
<audio voice="neospeech:paul">No, definitely not.</audio>
</sequence>
</stack>
</body>
</movie>
Here is the result: audio_sequence.mp4.
Using video with audio¶
Remember, when you add a video to an effect or to an overlay, an audio track is automatically created. You can prevent the audio track to be created by specifying audio=”false” in the video node.
Let’s see some examples:
<movie service="craftsman-1.0">
<body>
<effect type="diving" duration="10">
<image filename="http://assets.stupeflix.com/code/homevideo/images/wiki_Double-O-Arch_Arches_National_Park_2.jpg"/>
<video filename="http://assets.stupeflix.com/code/tutorials/audio/video/sts120_launch.mov"/>
</effect>
</body>
</movie>
The result is here : audio_video.mp4.
How does it works? The diving effect has a specified duration, so it imposes it to its children. The video will play after roughly 5 seconds, for 5 seconds, and so will do the related audio track.
Now, let’s remove the audio:
<movie service="craftsman-1.0">
<body>
<effect type="diving" duration="10">
<image filename="http://assets.stupeflix.com/code/homevideo/images/wiki_Double-O-Arch_Arches_National_Park_2.jpg"/>
<video filename="http://assets.stupeflix.com/code/tutorials/audio/video/sts120_launch.mov" audio="false"/>
</effect>
</body>
</movie>
See it in action : audio_video_noaudio.mp4.
Finally, let’s add an audio track from a video:
<movie service="craftsman-1.0">
<body>
<stack>
<audio filename="http://assets.stupeflix.com/code/tutorials/audio/video/sts120_launch.mov" fadein="2" fadeout="2" duration=".."/>
<effect type="diving" duration="10">
<image filename="http://assets.stupeflix.com/code/homevideo/images/wiki_Double-O-Arch_Arches_National_Park_2.jpg"/>
<video filename="http://assets.stupeflix.com/code/tutorials/audio/video/sts120_launch.mov" audio="false"/>
</effect>
</stack>
</body>
</movie>
Remember, we have to add a stack to be able to superpose the audio with the effect. Then, we have to add duration=".."
to the audio, so it is a slave of its “stack” parent. And finally, we set audio="false"
on the video.
See it now: audio_video_asaudio.mp4.
Using audio ducking¶
What is audio ducking ? It’s an audio effect you have heard times and times: it’s just the volume of some audio track (usually the music) that is lowered when someone is talking. This is a built-in feature in the SXML. How can you use it ? Just use the “duck-others” parameter.
<movie service="craftsman-1.0">
<body>
<stack duration="80">
<effect duration="80" depthEnable="false" type="none">
<image color="#FF0000"/>
</effect>
<audio filename="http://assets.stupeflix.com/code/audio/music.mp3" />
<audio filename="http://assets.stupeflix.com/code/audio/voice.mp3" duck-others="0.2"/>
</stack>
</body>
</movie>
The audio tracks are of two kinds: those with a duck-others argument (“master” tracks), and those without (“others” tracks).
The “master” tracks have an influence on “others” tracks, but not on “master” tracks.
The duck-others tell what is the volume of all “others” tracks when some sound is detected in the master track.
So, when some sound is detected in “voice.mp3”, the “music.mp3” volume is lowered to 0.2 (20 %). Otherwise, it stays the same.
To get a better result, a fade-in / fade-out and a margin are added to this basic effect : duck-margin and duck-fade are duration, with respective default values of 0.5s and 1.0s .
In this case, the margin tells that the volume will be lowered to 20% 0.5s after and before the detected sound. Similarly, the fade tells that the volume will fade from 100% to 20% in 1s, and same thing from 20% to 100%.
If you want to increase the effect, you can override those default values:
<movie service="craftsman-1.0">
<body>
<stack duration="80">
<effect duration="80" depthEnable="false" type="none">
<image color="#FF0000"/>
</effect>
<audio filename="http://assets.stupeflix.com/code/audio/music.mp3" />
<audio filename="http://assets.stupeflix.com/code/audio/voice.mp3" duck-fade="2.0" duck-margin="2.0" duck-others="0.2" />
</stack>
</body>
</movie>
Finally, there’s another parameter, duck-threshold . This is used to tell when the audio is silent and when some sound is detected. The default value is 0.05, it means that if the volume of “voice.mp3” is lower than 5% of its maximum it will considered as silence. If your audio track has a low volume, or a high level of noise, you may want to respectively descrease this threshold, or increase it.
Wrapping up¶
That was actually a good recapitulation of what we saw earlier today.
You said easy? I heard you!
Overlay¶
Overlays are just like text nodes. They can be placed on screen using CSS like parameters :
- top, bottom, left, right
- width, height
The only difference with text nodes is that you can add to them an image or a video: the aspect ratio of the image/video will NOT be kept. To do so, you’ll need a filter of the type “fitAdapter” for the image to fit the overlay with the right aspect ratio.
<overlay left="0.1" width="0.3" top="0.1" height="0.3" margin-start="1.0" duration="4.0">
<image filename="http://s3.amazonaws.com/stupeflix-assets/apiusecase/landscapes_france_cevennes/4.jpg">
<filter type="fitAdapter">
</filter>
</image>
</overlay>
You can then animate the overlay using the same animators as for text.
Sample XML movie:
<movie service="craftsman-1.0">
<body>
<stack duration="10.0">
<effect type="none">
<image color="#eeeeee"/>
</effect>
<overlay left="0.1" width="0.3" top="0.1" height="0.3" margin-start="1.0" duration="4.0">
<image color="#ff00ff"/>
<animator type="slide-in" direction="up" duration="1.0" />
</overlay>
<overlay right="0.1" width="0.3" top="0.3" height="0.3" margin-start="3.0" duration="4.0">
<image color="#0000ff"/>
<animator type="slide-in" direction="down" duration="1.0" />
<animator type="slide-out" direction="right" duration="1.0" />
</overlay>
<overlay right="0.35" width="0.3" top="0.35" height="0.3" margin-start="6.0" duration="4.0">
<image color="#888888"/>
<animator type="slide-in" direction="down" duration="1.0" />
<animator type="slide-out" direction="right" duration="1.0" />
<animator type="grow" growStart="0.0" growEnd="1.0"/>
</overlay>
</stack>
</body>
</movie>
Text effects¶
Text rendering is vector-based on a frame-by-frame basis or bitmap-based where text is turned into an image. In some cases down here, you’ll have to manage some nitty-gritty details to get exactly what you need. Be brave, that won’t be so difficult.
Text rendering : bitmaps¶
Historically, rendering text is done this way, without the attribute “vector”:
<movie service="craftsman-1.0">
<body>
<text type="zone" fontcolor="#ffffff">
Hello World
</text>
</body>
</movie>
This is a full screen “Hello World”. The principle is simple: the text is turned into an image once for all, and then used as standard image. The drawback is evident: if you zoom on the text it is blurry and aliased.
Text rendering: vectorized¶
So how can we improve this bitmap rendering ? By drawing frame by frame the text but using vector based methods. To activate it, you should change your xml and add the attribute “vector”:
<movie service="craftsman-1.0">
<body>
<text type="zone" vector="true">
Hello World
<filter type="distancemap" distanceWidth="40.0"/>
<filter type="distancecolor" distanceWidth="40.0" color="#ffffff" />
</text>
</body>
</movie>
This is a bit verbose, but will be improved in next versions. You can use 40.0 as magic constant, it should be ok in most cases. The difference should be almost invisible right now. But if you animate the text (zoom, scale...), the difference will be obvious.
More advanced text rendering method is explained there Advanced Text Rendering.
Effects¶
Quality improvement is an interesting property. But the most important benefit comes from the availability of a lot of new effects. All the effects are configured in the distancecolor filter: you just have to replace it with your own one. Simple white text:
<filter type="distancecolor" distanceWidth="40.0" color="#ffffff" />
Drop Shadow¶
Arguments are:
- dropShadowColor : RGBA (red, green, blue, alpha in hexadecimal)
- dropShadowBlurWidth: 0.0 for hard shadow, 1.0 for fully blurred
- dropShadowOpacity : multiplification on alpha channel of dropShadowColor
- dropShadowPosition : x,y position, in text zone height units (1.0 is so equal to the text zone height)
- dropShadowAngle / dropShadowDistance : alternative to dropShadowPosition, but in polar coordinates
<filter type="distancecolor" distanceWidth="40.0" color="#0000ff" dropShadowColor="#000000" dropShadowBlurWidth="0.5" dropShadowOpacity="0.8" dropShadowPosition="-0.02,0.02"/>
Sample video:
Inner Shadow¶
Arguments are:
- innerShadowColor : RGBA (red, green, blue, alpha in hexadecimal)
- innerShadowBlurWidth: 0.0 for hard shadow, 1.0 for fully blurred
- innerShadowOpacity : multiplification on alpha channel of dropShadowColor
- innerShadowPosition : x,y position, in text zone height units (1.0 is so equal to the text zone height)
- innerShadowAngle / innerShadowDistance : alternative to innerShadowPosition, but in polar coordinates
<filter type="distancecolor" distanceWidth="40.0" color="#cccccc" innerShadowColor="#000000" innerShadowBlurWidth="0.5" innerShadowOpacity="0.8" innerShadowPosition="-0.005,0.005"/>
Sample video:
Stroke Color¶
Arguments are:
- strokeWidth : 0.0 for no stroke, 1.0 for maximum width
- strokeOpacity : 0.0 for totally transparent, 1.0 for fully opaque
- strokeColor : color for stroke
<filter type="distancecolor" distanceWidth="40.0" color="#cccccc" strokeWidth="0.04" strokeOpacity="1.0" strokeColor="#0000FF" />
Sample video:
Outer Glow Color¶
Arguments are:
- outerGlowBlurWidth : 0.0 for no glow, 1.0 for maximum glow width
- outerGlowOpacity : 0.0 for totally transparent, 1.0 for fully opaque
- outerGlowColor : color for glow
<filter type="distancecolor" distanceWidth="40.0" color="#cccccc" outerGlowBlurWidth="1.0" outerGlowOpacity="0.5" outerGlowColor="#FF0000" />
Sample video:
Inner Glow Color¶
Arguments are:
- innerGlowBlurWidth : 0.0 for no glow, 1.0 for maximum glow width
- innerGlowOpacity : 0.0 for totally transparent, 1.0 for fully opaque
- innerGlowColor : color for glow
<filter type="distancecolor" distanceWidth="40.0" color="#cccccc" innerGlowBlurWidth="0.03" innerGlowOpacity="0.5" innerGlowColor="#FF0000" />
Sample video:
Full Example¶
Now, you can combine those effects to create a composite one.
<movie service="craftsman-1.0">
<body>
<stack duration="20">
<overlay height="1.0" width="1.0">
<image color="#ffffff" />
</overlay>
<text type="zone" vector="true">
Hello World
<filter type="distancemap" distanceWidth="40.0"/>
<filter type="distancecolor" distanceWidth="40.0" color="#eda35f"
strokeColor="#000000" strokeOpacity="1.0" strokeWidth="0.02"
innerShadowColor="#de7316" innerShadowOpacity="1.0" innerShadowPosition="0.01,-0.01"
dropShadowColor="#00000044" dropShadowOpacity="1.0" dropShadowBlurWidth="0.9" dropShadowPosition="0.05,-0.05"
outerGlowColor="#ffffff44" outerGlowOpacity="1.0" outerGlowBlurWidth="0.7">
</filter>
</text>
</stack>
</body>
</movie>
Sample video:
Another sample, with a scale animation to show good antialiasing properties:
<movie service="craftsman-1.0">
<body>
<stack duration="20">
<overlay height="1.0" width="1.0">
<image color="#ffffff" />
</overlay>
<text type="zone" vector="true">
Hello World
<filter type="distancemap" distanceWidth="40.0"/>
<filter type="distancecolor" distanceWidth="40.0" color="#eda35f"
strokeColor="#000000" strokeOpacity="1.0" strokeWidth="0.02"
innerShadowColor="#de7316" innerShadowOpacity="1.0" innerShadowPosition="0.01,-0.01"
dropShadowColor="#00000044" dropShadowOpacity="1.0" dropShadowBlurWidth="0.9" dropShadowPosition="0.05,-0.05"
outerGlowColor="#ffffff44" outerGlowOpacity="1.0" outerGlowBlurWidth="0.7">
</filter>
<animator type="custom" >
<key time="0.0" scale="0.25,0.25,0.25" pos="0,0,0"/>
<key time="20.0" scale="3,3,3" pos="0,0.5,0.0"/>
</animator>
</text>
</stack>
</body>
</movie>
Sample video:
Extra Bonus: animation¶
The nice thing with all these properties is that everything can be animated. You just have to move the properties to animate into an animator.
Here, we take the last example, but we are starting from no stroke to slight stroke, and we are moving the drop shadow:
<movie service="craftsman-1.0">
<body>
<stack duration="10">
<overlay height="1.0" width="1.0">
<image color="#ffffff" />
</overlay>
<text type="zone" vector="true">
Hello World
<filter type="distancemap" distanceWidth="40.0"/>
<filter type="distancecolor" distanceWidth="40.0" color="#eda35f"
strokeColor="#000000" strokeOpacity="1.0"
innerShadowColor="#de7316" innerShadowOpacity="1.0" innerShadowPosition="0.01,-0.01"
dropShadowColor="#00000044" dropShadowOpacity="1.0" dropShadowBlurWidth="0.9"
outerGlowColor="#ffffff44" outerGlowOpacity="1.0" outerGlowBlurWidth="0.7">
<animator type="custom">
<key time="0.0" strokeWidth="0.0" dropShadowPosition="0.05,-0.05" />
<key time="10.0" strokeWidth="0.02" dropShadowPosition="-0.05,-0.05" />
</animator>
</filter>
</text>
</stack>
</body>
</movie>
Sample video:
The good news is that rendering is just as fast as when nothing is animated. No less, no more. Thanks for your attention, and feel free to send us feedback about your experience on this feature!
Animators¶
Animators can be used in two different contexts:
- geometric transformations animations: translations, rotations, scale
- parameters animations in filters
Geometric animations¶
Geometric animators can be inserted in any node that is drawn or any container
- sequence (or body, which is only the top level sequence)
- stack
- effect
- text
- overlay
- widget
- sphere
- camera
A arbitrary number of animators can be stacked in the same node. The geometric transformations will be then applied in the given order, except for the camera where the order is reversed.
The OpenGL coordinate system is used:
Coordinates for the full screen are:
- x in [-aspectRatio, + aspectRatio]
- y in [-1, +1]
- z = 0
Where aspectRatio is for example 16/9 = 1.7777777... in the following examples.
There are two kinds of animators: builtins, and custom. The first ones are already packaged for you. The latter ones are user defined.
Custom animators¶
They can be used by specifying the “custom” animator type.
<animator type="custom">
<!-- ... -->
</animator>
You can then add some key xml node in it. Each key must contain a time attribute, expressed in seconds, and an arbitrary combination of attributes “rot”, “orient”, “pos”, or “scale” (one of each maximum).
Translations¶
A translation is performed using the “pos” key. The parameters are the translation along the X,Y and Z dimensions.
<overlay>
<image filename="http://assets.stupeflix.com/code/images/surf.jpg"/>
<animator type="custom">
<key pos="-3.55555555,0,0" time="0.0"/>
<key pos="0,0,0" time="1.0"/>
<key pos="0,0,0" time="4.0"/>
<key pos="3.55555555,0,0" time="5.0"/>
</animator>
</overlay>
Scale¶
A scaling is performed using the “scale” key. The parameters are the scale along the X,Y and Z dimensions. The neutral value is of course 1.0.
<overlay>
<image filename="http://assets.stupeflix.com/code/images/surf.jpg"/>
<animator type="custom">
<key scale="1,1,1" time="0.0"/>
<key scale="1.2,1,1" time="1.0"/>
<key scale="1.0,1.2,1" time="4.0"/>
<key scale="1,1,1" time="5.0"/>
</animator>
</overlay>
Rotations¶
A rotation is performed using the rot key. The first parameter in the rot value is the angle, and the following are the axis rotation vector. For example, 360,0,1,0 gives a 360 degrees rotation on the Y (up vertical) axis.
<overlay>
<image filename="http://assets.stupeflix.com/code/images/surf.jpg"/>
<animator type="custom">
<key rot="0,0,1,0" time="0.0"/>
<key rot="360,0,1,0" time="5"/>
</animator>
</overlay>
The four parameters are linearly interpolated from a key to the next one, so it may lead to some hard to understand behaviour if you specify things like :
<overlay>
<image filename="http://assets.stupeflix.com/code/images/surf.jpg"/>
<animator type="custom">
<key rot="0,0,1,0" time="0.0"/>
<key rot="360,0,1,0" time="2.5"/>
<key rot="360,0,0,1" time="5"/>
</animator>
</overlay>
As you can see, a 360 rotation is applied from 2.5s to 5s, so nothing moves.
For “continuous” rotations like this, you may use quaternion based rotations, using the orient parameter (see below).
Orientation¶
Orientation is different from rotation in the way it is interpolated. It is based on quaternions, so the rotation between two positions is more “natural”, in the sense that it is the “shortest” rotation between the two positions. The parameters are the rotation on the X,Y and Z axes (Euler angles).
It can looks like a simple rotation in some cases:
<overlay>
<image filename="http://assets.stupeflix.com/code/images/surf.jpg"/>
<animator type="custom">
<key orient="0.0,0.0,0.0" time="0.0"/>
<key orient="0.0,180.0,0,0" time="5.0"/>
</animator>
</overlay>
Multiple values in keys¶
All keys in an animator must contains exactly the same set of attributes. For example, a key <key time="0.0" pos="0,0,0"/>
is incompatible with a key <key time="0.0" pos="0,0,0" rot="360,0,0,0"/>
.
That said, you can combine several attributes in a key. They will be processed in this order: scale, pos, orient, rot.
<overlay>
<image filename="http://assets.stupeflix.com/code/images/surf.jpg"/>
<animator type="custom">
<key pos="0.0,0.0,0.0" time="0.0" rot="0.0,0.0,0.0,1.0"/>
<key pos="0.0,0.0,-1.0" time="5.0" rot="360.0,0.0,0.0,1.0"/>
</animator>
</overlay>
Builtin animators¶
Those animators are “shortcuts” to the most common operations.
Slide animators¶
The parameters are:
- direction : left, right, up, down (default is left)
- duration (default is full duration)
There are three kinds of slide animators : slide-in, slide-out, and slide.
slide-in
and slide-out
are in/out animations. slide
is animated during the full time.
<overlay>
<image filename="http://assets.stupeflix.com/code/images/surf.jpg"/>
<animator type="slide-in"/>
</overlay>
Slide in with a duration of 1 second :
<overlay duration="5.0">
<image filename="http://assets.stupeflix.com/code/images/surf.jpg"/>
<animator type="slide-in" duration="1.0"/>
</overlay>
Slide out with a duration of 1 second and direction is up :
<overlay duration="5.0">
<image filename="http://assets.stupeflix.com/code/images/surf.jpg"/>
<animator type="slide-out" direction="up" duration="1.0"/>
</overlay>
Slide:
<overlay duration="5.0">
<image filename="http://assets.stupeflix.com/code/images/surf.jpg"/>
<animator type="slide" direction="left"/>
</overlay>
Of course you can combine several animations on the same overlay:
<overlay duration="5.0">
<image filename="http://assets.stupeflix.com/code/images/surf.jpg"/>
<animator type="slide-in" direction="left" duration="1.0"/>
<animator type="slide-out" direction="down" duration="1.0"/>
</overlay>
Rotation animators¶
The parameters are:
- angle, in degrees
- duration (default is full duration)
There are two kind of rot animators : rot-in, rot-out.
These animators are similar to slide animators, but with rotations.
<overlay>
<image filename="http://assets.stupeflix.com/code/images/surf.jpg"/>
<animator type="rot-in" angle="360" duration="1"/>
</overlay>
<overlay>
<image filename="http://assets.stupeflix.com/code/images/surf.jpg"/>
<animator type="rot-out" angle="360" duration="1"/>
</overlay>
Grow animators¶
The parameters are:
- growStart, growEnd: default is 0.0, 0.1
- duration (default is full duration)
The effect is done by translating the object on the Z axis.
First, a grow effect on the full duration:
<overlay>
<image filename="http://assets.stupeflix.com/code/images/surf.jpg"/>
<animator type="grow" growStart="-0.3" growEnd="0.0" />
</overlay>
Same thing, but shrinking:
<overlay>
<image filename="http://assets.stupeflix.com/code/images/surf.jpg"/>
<animator type="grow" growStart="0.3" growEnd="0.0"/>
</overlay>
<overlay>
<image filename="http://assets.stupeflix.com/code/images/surf.jpg"/>
<animator type="grow" growStart="0.0" growEnd="0.1" duration="1"/>
</overlay>
Same thing at the end:
<overlay>
<image filename="http://assets.stupeflix.com/code/images/surf.jpg"/>
<animator type="grow" growStart="0.1" growEnd="0.0" duration="1.0" margin-end="0.0"/>
</overlay>
Animator combination¶
An arbitrary number of animators can be chained. The previous example
<overlay>
<image filename="http://assets.stupeflix.com/code/images/surf.jpg"/>
<animator type="custom">
<key pos="0.0,0.0,0.0" time="0.0" rot="0.0,0.0,0.0,1.0"/>
<key pos="0.0,0.0,-1.0" time="5.0" rot="360.0,0.0,0.0,1.0"/>
</animator>
</overlay>
is equivalent to this one:
<overlay>
<image filename="http://assets.stupeflix.com/code/images/surf.jpg"/>
<animator type="custom">
<key pos="0.0,0.0,0.0" time="0.0"/>
<key pos="0.0,0.0,-1.0" time="5.0"/>
</animator>
<animator type="custom">
<key rot="0.0,0.0,0.0,1.0" time="0.0"/>
<key rot="360.0,0.0,0.0,1.0" time="5.0"/>
</animator>
</overlay>
Node hierarchy and animators¶
You can use animators at several places in your XML tree, each one will animate a node in the “scene graph”.
<stack>
<animator type="custom">
<key pos="0.0,0.0,-3.0" time="0.0"/>
</animator>
<animator type="custom">
<key rot="0.0,0.0,1.0,0.0" time="0.0"/>
<key rot="30.0,1.0,1.0,0.0" time="1.666"/>
<key rot="-30.0,1.0,1.0,0.0" time="3.3333"/>
<key rot="0.0,0.0,1.0,0.0" time="5.0"/>
</animator>
<overlay>
<image filename="http://assets.stupeflix.com/code/images/Monument_Valley.jpg"/>
<animator type="custom">
<key pos="-2.8,2.1,0.0" time="0.0"/>
<key pos="-1.8,1.1,0.0" time="1.0"/>
</animator>
</overlay>
<overlay>
<image filename="http://assets.stupeflix.com/code/images/Ha_long_bay.jpg"/>
<animator type="custom">
<key pos="2.8,2.1,0.0" time="0.0"/>
<key pos="1.8,1.1,0.0" time="1.0"/>
</animator>
</overlay>
<overlay left="auto" right="auto" height="1.0">
<image filename="http://assets.stupeflix.com/code/images/Lightning_over_Oradea_Romania.jpg"/>
<animator type="custom">
<key pos="-2.8,-2.1,0.0" time="0.0"/>
<key pos="-1.8,-1.1,0.0" time="1.0"/>
</animator>
</overlay>
<overlay>
<image filename="http://assets.stupeflix.com/code/images/Canyon_de_Chelly_Navajo.jpg"/>
<animator type="custom">
<key pos="2.8,-2.1,0.0" time="0.0"/>
<key pos="1.8,-1.1,0.0" time="1.0"/>
</animator>
</overlay>
</stack>
Finally, you can mix custom and builtin animators, they have exactly the same role:
<stack>
<animator type="custom">
<key pos="0.0,0.0,-3.0" time="0.0"/>
</animator>
<animator type="custom">
<key rot="0.0,0.0,1.0,0.0" time="0.0"/>
<key rot="30.0,1.0,1.0,0.0" time="1.666"/>
<key rot="-30.0,1.0,1.0,0.0" time="3.3333"/>
<key rot="0.0,0.0,1.0,0.0" time="5.0"/>
</animator>
<overlay>
<image filename="http://assets.stupeflix.com/code/images/Monument_Valley.jpg"/>
<animator type="custom">
<key pos="-1.8,1.1,0.0" time="0.0"/>
</animator>
<animator type="slide-in" direction="left" duration="1.0"/>
</overlay>
<overlay>
<image filename="http://assets.stupeflix.com/code/images/Ha_long_bay.jpg"/>
<animator type="custom">
<key pos="1.8,1.1,0.0" time="0.0"/>
</animator>
<animator type="slide-in" direction="down" duration="1.0"/>
</overlay>
<overlay left="auto" right="auto" height="1.0">
<image filename="http://assets.stupeflix.com/code/images/Lightning_over_Oradea_Romania.jpg"/>
<animator type="custom">
<key pos="-1.8,-1.1,0.0" time="0.0"/>
</animator>
<animator type="slide-in" direction="right" duration="1.0"/>
</overlay>
<overlay>
<image filename="http://assets.stupeflix.com/code/images/Canyon_de_Chelly_Navajo.jpg"/>
<animator type="custom">
<key pos="1.8,-1.1,0.0" time="0.0"/>
</animator>
<animator type="rot-in" angle="90" duration="1.0"/>
</overlay>
</stack>
Time Margins¶
Explanation¶
Duration computation is an important part of the Stupeflix Video XML Language processing.
Margins are there to position in time the different parts of a video. The three parameters are called margin-start
margin-end
and margin-both
.
Margins are relative to a container. This container can be anything except a sequence (or body, which is a sequence too).
Margins are the time equivalent to CSS margins. They must be greater than or equal to zero.
Four values are related by the following: fatherDuration = margin-start + duration + margin-end
So, if you specify only margin-start or margin-end, duration will take all the remaining time. If you specify margin-start and duration, margin-end will be computed accordingly. If fatherDuration is fixed, then some part of the children may be truncated.
You cannot specify at the same time margin-start, duration and margin-end, or margin-both and duration. You will have to specify instead fatherDuration and two of the three parameters.
Let’s start with some examples.
Basic examples¶
The total video length will be 4.0 seconds, the first second is black, the last two seconds are black too.
<stack duration="4.0">
<overlay margin-start="1.0" margin-end="2.0" width="1.0">
<image filename="http://assets.stupeflix.com/code/images/Monument_Valley.jpg"/>
</overlay>
</stack>
The total video length will be 4.0 seconds, the first two seconds are black.
<stack duration="4.0">
<overlay duration="2.0" margin-end="0.0" width="1.0">
<image filename="http://assets.stupeflix.com/code/images/Monument_Valley.jpg"/>
</overlay>
</stack>
Element duration dependencies¶
In this example, the duration is fixed by the video element (taking into account that the video is speedup by a factor of 2.0), and so the text duration will be adapted, using video duration decreased by the margins both at start and at the end.
<stack>
<overlay width="1.0">
<video filename="http://assets.stupeflix.com/code/tutorials/masking/sky_timelapse.mp4" speed="2.0"/>
</overlay>
<text type="zone" height="0.1" margin-both="2.0">Sky Time Lapse</text>
</stack>
In a second example, we use margins on animators for the text. The actual duration of the text is
<stack>
<overlay width="1.0">
<video filename="http://assets.stupeflix.com/code/tutorials/masking/sky_timelapse.mp4" speed="2.0"/>
</overlay>
<text type="zone" height="0.1" left="0.02">Sky Time Lapse
<animator type="slide-in" direction="left" margin-start="1.5" duration="2.0"/>
<animator type="slide-out" direction="left" margin-end="1.5" duration="1.0"/>
</text>
</stack>
In the next example, we use margins on the filter : the filter tint is stuck on the white color only after one second. The animator is in fact 1 second shifted.
<stack>
<overlay width="1.0">
<video filename="http://assets.stupeflix.com/code/tutorials/masking/sky_timelapse.mp4" speed="2.0"/>
<filter type="tint">
<animator type="custom" margin-start="1.0">
<key time="0.0" whiteColor="#ffffff"/>
<key time="3.0" whiteColor="#00ff00"/>
<key time="6.0" whiteColor="#ffff00"/>
</animator>
</filter>
</overlay>
</stack>
Advanced Text Rendering¶
Layout¶
If you want to use right to left languages, create different text layout, mix different text styles, the “advanced” text type was introduced just for you.
Sample¶
<sequence>
<text type="advanced" fontsize="40" duration="1" reference="WWWWWWW">עִבְרִית </text>
<text type="advanced" fontsize="40" duration="1" reference="WWWWWWW">العربية </text>
<text type="advanced" fontsize="40" duration="1" reference="WWWWWWW">汉语/漢語 </text>
<text type="advanced" fontsize="40" duration="1" reference="WWWWWWW">日本人</text>
<animator type="custom">
<key time="0.0" pos="-1,0,0"/>
</animator>
</sequence>
Reference text¶
To define the bounding box for the text to be drawn, you just have to specify a reference text. This text will be drawn internally and its bounding box will be used to constrain the placement of the text you use in the “text” xml tag itself.
<text type="advanced" duration="1" reference="WWWWWWW">Hello World!</text>
In that first example, you can see that the zone defined by “WWWWWWW” is too small to contain “Hello World”, so an ellipsis (”...”) is used to truncate it. It is guaranteed that the text won’t overflow its bounding box. So, if we set a longer reference text, the ellipsis will disappear.
<text type="advanced" duration="1" reference="WWWWWWWWWWWW">Hello World!</text>
How can you setup easily the right reference text? The easier is to start with a text tag with no reference text, to check that position and size is ok, and then everything is ok, move it to the “reference” attribute:
<text type="advanced" duration="1" >WWWWWWWWWWW</text>
then, when the reference text is ok in your layout :
<text type="advanced" duration="1" reference="WWWWWWWWWWWW">Hello World!</text>
Text wrapping: Multiline Reference text¶
When you don’t add a reference text, there is no bounding box at all. When you add a single lined reference text, an ellipsis will be used if the text is too long. But if you specify a multiple lined reference text, it will wrap, and an ellipsis will be used eventually on the last line.
<text type="advanced" duration="1" reference="WWWW WWWWWW WWWWWW">Hello World! This text will be truncated</text>
The wrapping is done on per word basis first, and on a character per character basis if a single word does not fit on the current line.
Advanced Text wrapping¶
If you introduce spaces in the reference text, they will be used to shift the line on the right or on the left, depending on the alignment. This can be used to create complex text wrapping.
<sequence>
<text type="advanced" duration="1" reference="WWWWWWWWWWWWWWWWWWWWWWWWWWW WWWWWWWWWWWWWWWWWWWWWWWW WWWWWWWWWWWWWWWWWWWWWW WWWWWWWWWWWWWWWWWWWWW WWWWWWWWWWWWWWWWWWWWW WWWWWWWWWWWWWWWWWWWWW WWWWWWWWWWWWWWWWWWWWWW WWWWWWWWWWWWWWWWWWWWWWWW WWWWWWWWWWWWWWWWWWWWWWWWWWW">In text display, line wrap is the feature of continuing on a new line when a line is full, such that each line fits in the viewable window, allowing text to be read from top to bottom without any horizontal scrolling.
Word wrap is the additional feature of most text editors, word processors, and web browsers, of breaking lines between and not within words, except when a single word is longer than a line</text>
<animator type="custom">
<key time="0.0" pos="-1.2,0.8,0"/>
</animator>
</sequence>
Anchor point¶
In the last example, we had to introduce an animator to move the text to be viewable. The reason is that the anchor point for the text is the origin of the first character (including spaces), a point situated on its baseline, on its left for left to right languages (see http://www.freetype.org/freetype2/docs/glyphs/glyphs-3.html for more information).
So, usually, everything will be written under and on the right of this point.
This is true only when the text is left align. If the text is right aligned, the origin will on the right of the last character of the first line. If the text is centered, the origin will be the center of the line.
For right to left language, right/left alignment is inverted. The origin of the text is by default the center of the screen, as you can see on these examples:
<text type="advanced" duration="1" reference="WWWWWWWWWWWWWWWWWWWWWWWWWWW WWWWWWWWWWWWWWWWWWWWWWWWWW " align="left">In text display, line wrap is the feature of continuing on a new line.</text>
<text type="advanced" duration="1" reference="WWWWWWWWWWWWWWWWWWWWWWWWWWW WWWWWWWWWWWWWWWWWWWWWWWWWWW " align="right">In text display,
line wrap is the feature of continuing on a new line.</text>
<text type="advanced" duration="1" reference="WWWWWWWWWWWWWWWWWWWWWWWWWWW WWWWWWWWWWWWWWWWWWWWWWWWWWW " align="center">In text display,
line wrap is the feature of continuing on a new line.</text>
<text type="advanced" duration="1" reference="WWWWWWWWWWWWWWWWWWWWW ">עִבְרִית</text>
The text that is taken into account for anchoring is actually the reference text, not the the content text. The process is the following:
- the reference text is splitted into lines
- for each line of this reference text, the bounding box and position is computed
then the text itself is drawn
- the align setting is used for each line of text within the bounds of the reference text line
- the text is drawn
Finally, anchoring is performed using the reference text, so the text is shifted to have the center of the screen matching the origin of the text.
<text type="advanced" duration="1" reference="WWWWWWWWWWWWWWWWWWWWW " align="right">עִבְרִית</text>
Style¶
Example¶
<stack>
<text type="advanced" fontsize="20" duration="1" reference=" WWWWWWWWWWWWW WWWWWWWWWWWWWWW" weight="bold" style="italic" stretch="condensed" face="times" >In text display, line wrap is the feature of continuing on a new line when a line is full, </text>
<animator type="custom">
<key time="0.0" pos="-1.6,0,0"/>
</animator>
</stack>
Alpha Layer¶
Video with an alpha layer¶
Maybe be you have some video assets that have been keyed, for example shot on a green background then postprocessed to turn the green channel into transparent. Or maybe you bought some pre-keyed asset on Toolfarm. And you want to use them into your Stupeflix creation.
It is now possible, the only constraint is that you have to turn your video into a flv with alpha layer file. To do so, you can use for example Adobe Media Encoder.
In the following example, the Boxing.flv is such an flv with alpha. You can use as usual, except of course that some part of the video maybe transparent.
In the first example, we just use a green background, to show what the transparent video looks like.
<stack duration="5">
<overlay width="1.0" height="1.0" duration="..">
<image color="#00ff00" />
</overlay>
<overlay width="1.0" left="0.0" height="1.0">
<video filename="https://stupeflix-assets.s3.amazonaws.com/code/tutorials/masking/Boxing.flv" />
</overlay>
</stack>
In the second one, we use a fancier background.
<stack>
<overlay width="1.0" top="auto" bottom="auto" duration="..">
<image filename="https://stupeflix-assets.s3.amazonaws.com/code/tutorials/masking/boxe.jpg" />
</overlay>
<overlay width="1.0" left="0.0" height="1.0">
<video filename="https://stupeflix-assets.s3.amazonaws.com/code/tutorials/masking/Boxing.flv" />
</overlay>
</stack>
Finally, the limit is your imagination, you can use a video with alpha wherever you can use a video :
<stack duration="5">
<overlay width="1.0" height="1.0" duration="..">
<image color="#ffffff" />
</overlay>
<effect type="diving" duration= "10.0">
<video filename="https://stupeflix-assets.s3.amazonaws.com/code/tutorials/masking/Boxing.flv" />
<image filename="https://stupeflix-assets.s3.amazonaws.com/code/tutorials/masking/boxe.jpg" />
</effect>
</stack>
<stack duration="5">
<overlay width="1.0" top="auto" bottom="auto" duration="..">
<image filename="https://stupeflix-assets.s3.amazonaws.com/code/tutorials/masking/boxe.jpg" />
<animator type="slide-in" duration="1.0"/>
</overlay>
<overlay width="1.0" left="0.0" height="1.0">
<video filename="https://stupeflix-assets.s3.amazonaws.com/code/tutorials/masking/Boxing.flv" />
</overlay>
</stack>
Resources¶
XML Editor¶
The Stupeflix XML Editor is an online tool that allow you to write your video XML and test it immediatly: developer.stupeflix.com.
Supported Ffmpeg codecs¶
Codecs:
D..... = Decoding supported
.E.... = Encoding supported
..V... = Video codec
..A... = Audio codec
..S... = Subtitle codec
...S.. = Supports draw_horiz_band
....D. = Supports direct rendering method 1
.....T = Supports weird frame truncation
------
D V D 4xm 4X Movie
D V D 8bps QuickTime 8BPS video
D A D 8svx_exp 8SVX exponential
D A D 8svx_fib 8SVX fibonacci
EV a64multi Multicolor charset for Commodore 64
EV a64multi5 Multicolor charset for Commodore 64, extended with 5th color (colram)
DEA D aac Advanced Audio Coding
D A D aac_latm AAC LATM (Advanced Audio Codec LATM syntax)
D V D aasc Autodesk RLE
DEA D ac3 ATSC A/52A (AC-3)
EA ac3_fixed ATSC A/52A (AC-3)
D A D adpcm_4xm ADPCM 4X Movie
DEA D adpcm_adx SEGA CRI ADX ADPCM
D A D adpcm_ct ADPCM Creative Technology
D A D adpcm_ea ADPCM Electronic Arts
D A D adpcm_ea_maxis_xa ADPCM Electronic Arts Maxis CDROM XA
D A D adpcm_ea_r1 ADPCM Electronic Arts R1
D A D adpcm_ea_r2 ADPCM Electronic Arts R2
D A D adpcm_ea_r3 ADPCM Electronic Arts R3
D A D adpcm_ea_xas ADPCM Electronic Arts XAS
D A D adpcm_ima_amv ADPCM IMA AMV
D A D adpcm_ima_apc ADPCM IMA CRYO APC
D A D adpcm_ima_dk3 ADPCM IMA Duck DK3
D A D adpcm_ima_dk4 ADPCM IMA Duck DK4
D A D adpcm_ima_ea_eacs ADPCM IMA Electronic Arts EACS
D A D adpcm_ima_ea_sead ADPCM IMA Electronic Arts SEAD
D A D adpcm_ima_iss ADPCM IMA Funcom ISS
DEA D adpcm_ima_qt ADPCM IMA QuickTime
D A D adpcm_ima_smjpeg ADPCM IMA Loki SDL MJPEG
DEA D adpcm_ima_wav ADPCM IMA WAV
D A D adpcm_ima_ws ADPCM IMA Westwood
DEA D adpcm_ms ADPCM Microsoft
D A D adpcm_sbpro_2 ADPCM Sound Blaster Pro 2-bit
D A D adpcm_sbpro_3 ADPCM Sound Blaster Pro 2.6-bit
D A D adpcm_sbpro_4 ADPCM Sound Blaster Pro 4-bit
DEA D adpcm_swf ADPCM Shockwave Flash
D A D adpcm_thp ADPCM Nintendo Gamecube THP
D A D adpcm_xa ADPCM CDROM XA
DEA D adpcm_yamaha ADPCM Yamaha
DEA D alac ALAC (Apple Lossless Audio Codec)
D A D als MPEG-4 Audio Lossless Coding (ALS)
D A D amrnb Adaptive Multi-Rate NarrowBand
D A D amrwb Adaptive Multi-Rate WideBand
DEV amv AMV Video
D V D anm Deluxe Paint Animation
D V D ansi ASCII/ANSI art
D A D ape Monkey's Audio
DES ass Advanced SubStation Alpha subtitle
DEV D asv1 ASUS V1
DEV D asv2 ASUS V2
D A D atrac1 Atrac 1 (Adaptive TRansform Acoustic Coding)
D A D atrac3 Atrac 3 (Adaptive TRansform Acoustic Coding 3)
D V D aura Auravision AURA
D V D aura2 Auravision Aura 2
DEV D avrp Avid 1:1 10-bit RGB Packer
D V D avs AVS (Audio Video Standard) video
D V D bethsoftvid Bethesda VID video
D V D bfi Brute Force & Ignorance
D A D binkaudio_dct Bink Audio (DCT)
D A D binkaudio_rdft Bink Audio (RDFT)
D V binkvideo Bink video
D V D bintext Binary text
DEV D bmp BMP image
D A D bmv_audio Discworld II BMV audio
D V bmv_video Discworld II BMV video
D V D c93 Interplay C93
D V D camstudio CamStudio
D V D camtasia TechSmith Screen Capture Codec
D V D cavs Chinese AVS video (AVS1-P2, JiZhun profile)
D V D cdgraphics CD Graphics video
D V D cinepak Cinepak
DEV D cljr Cirrus Logic AccuPak
D A D cook COOK
D V D cyuv Creative YUV (CYUV)
DEA D dca DCA (DTS Coherent Acoustics)
D V D dfa Chronomaster DFA
D V dirac BBC Dirac VC-2
DEV D dnxhd VC3/DNxHD
DEV dpx DPX image
D A D dsicinaudio Delphine Software International CIN audio
D V D dsicinvideo Delphine Software International CIN video
DES dvbsub DVB subtitles
DES dvdsub DVD subtitles
DEV D dvvideo DV (Digital Video)
D V D dxa Feeble Files/ScummVM DXA
D V D dxtory Dxtory
DEA D eac3 ATSC A/52 E-AC-3
D V D eacmv Electronic Arts CMV video
D V D eamad Electronic Arts Madcow Video
D V D eatgq Electronic Arts TGQ video
D V eatgv Electronic Arts TGV video
D V D eatqi Electronic Arts TQI Video
D V D escape124 Escape 124
D V D escape130 Escape 130
DEV D ffv1 FFmpeg video codec #1
DEVSD ffvhuff Huffyuv FFmpeg variant
DEA D flac FLAC (Free Lossless Audio Codec)
DEV D flashsv Flash Screen Video
DEV D flashsv2 Flash Screen Video Version 2
D V D flic Autodesk Animator Flic video
DEVSD flv Flash Video (FLV) / Sorenson Spark / Sorenson H.263
D V D fraps Fraps
D V D frwu Forward Uncompressed
DEA D g722 G.722 ADPCM
DEA g723_1 G.723.1
DEA D g726 G.726 ADPCM
D A D g729 G.729
DEV D gif GIF (Graphics Interchange Format)
D A D gsm GSM
D A D gsm_ms GSM Microsoft variant
DEV D h261 H.261
DEVSDT h263 H.263 / H.263-1996
D VSD h263i Intel H.263
EV h263p H.263+ / H.263-1998 / H.263 version 2
D V D h264 H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10
DEVSD huffyuv Huffyuv / HuffYUV
D V D idcinvideo id Quake II CIN video
D V D idf iCEDraw text
D V D iff_byterun1 IFF ByteRun1
D V D iff_ilbm IFF ILBM
D A D imc IMC (Intel Music Coder)
D V D indeo2 Intel Indeo 2
D V indeo3 Intel Indeo 3
D V indeo4 Intel Indeo Video Interactive 4
D V indeo5 Intel Indeo Video Interactive 5
D A D interplay_dpcm DPCM Interplay
D V D interplayvideo Interplay MVE video
DEV j2k JPEG 2000
DEV D jpegls JPEG-LS
D V D jv Bitmap Brothers JV video
D V kgv1 Kega Game Video
D V D kmvc Karl Morton's video codec
D V D lagarith Lagarith lossless
EA libfaac libfaac AAC (Advanced Audio Codec)
EA libmp3lame libmp3lame MP3 (MPEG audio layer 3)
DEA D libopencore_amrnb OpenCORE Adaptive Multi-Rate (AMR) Narrow-Band
D A D libopencore_amrwb OpenCORE Adaptive Multi-Rate (AMR) Wide-Band
EV libtheora libtheora Theora
EA libvorbis libvorbis Vorbis
DEV libvpx libvpx VP8
EV libx264 libx264 H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10
EV libx264rgb libx264 H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 RGB
EV libxvid libxvidcore MPEG-4 part 2
EV ljpeg Lossless JPEG
D V D loco LOCO
D A D mace3 MACE (Macintosh Audio Compression/Expansion) 3:1
D A D mace6 MACE (Macintosh Audio Compression/Expansion) 6:1
D V D mdec Sony PlayStation MDEC (Motion DECoder)
D V D mimic Mimic
DEV D mjpeg MJPEG (Motion JPEG)
D V D mjpegb Apple MJPEG-B
D A D mlp MLP (Meridian Lossless Packing)
D V D mmvideo American Laser Games MM Video
D V D motionpixels Motion Pixels video
D A D mp1 MP1 (MPEG audio layer 1)
D A D mp1float MP1 (MPEG audio layer 1)
DEA D mp2 MP2 (MPEG audio layer 2)
D A D mp2float MP2 (MPEG audio layer 2)
D A D mp3 MP3 (MPEG audio layer 3)
D A D mp3adu ADU (Application Data Unit) MP3 (MPEG audio layer 3)
D A D mp3adufloat ADU (Application Data Unit) MP3 (MPEG audio layer 3)
D A D mp3float MP3 (MPEG audio layer 3)
D A D mp3on4 MP3onMP4
D A D mp3on4float MP3onMP4
D A D mpc7 Musepack SV7
D A D mpc8 Musepack SV8
DEVSDT mpeg1video MPEG-1 video
DEVSDT mpeg2video MPEG-2 video
DEVSDT mpeg4 MPEG-4 part 2
D VSDT mpegvideo MPEG-1 video
DEVSD msmpeg4 MPEG-4 part 2 Microsoft variant version 3
D VSD msmpeg4v1 MPEG-4 part 2 Microsoft variant version 1
DEVSD msmpeg4v2 MPEG-4 part 2 Microsoft variant version 2
D V D msrle Microsoft RLE
DEV D msvideo1 Microsoft Video-1
D V D mszh LCL (LossLess Codec Library) MSZH
D V D mxpeg Mobotix MxPEG video
DEA D nellymoser Nellymoser Asao
D V D nuv NuppelVideo/RTJPEG
DEV D pam PAM (Portable AnyMap) image
DEV D pbm PBM (Portable BitMap) image
D A D pcm_alaw PCM A-law
D A D pcm_bluray PCM signed 16|20|24-bit big-endian for Blu-ray media
D A D pcm_dvd PCM signed 20|24-bit big-endian
D A D pcm_f32be PCM 32-bit floating point big-endian
D A D pcm_f32le PCM 32-bit floating point little-endian
D A D pcm_f64be PCM 64-bit floating point big-endian
D A D pcm_f64le PCM 64-bit floating point little-endian
D A D pcm_lxf PCM signed 20-bit little-endian planar
D A D pcm_mulaw PCM mu-law
D A D pcm_s16be PCM signed 16-bit big-endian
D A D pcm_s16le PCM signed 16-bit little-endian
D A D pcm_s16le_planar PCM 16-bit little-endian planar
D A D pcm_s24be PCM signed 24-bit big-endian
D A D pcm_s24daud PCM D-Cinema audio signed 24-bit
D A D pcm_s24le PCM signed 24-bit little-endian
D A D pcm_s32be PCM signed 32-bit big-endian
D A D pcm_s32le PCM signed 32-bit little-endian
D A D pcm_s8 PCM signed 8-bit
D A D pcm_s8_planar PCM signed 8-bit planar
D A D pcm_u16be PCM unsigned 16-bit big-endian
D A D pcm_u16le PCM unsigned 16-bit little-endian
D A D pcm_u24be PCM unsigned 24-bit big-endian
D A D pcm_u24le PCM unsigned 24-bit little-endian
D A D pcm_u32be PCM unsigned 32-bit big-endian
D A D pcm_u32le PCM unsigned 32-bit little-endian
D A D pcm_u8 PCM unsigned 8-bit
D A D pcm_zork PCM Zork
DEV D pcx PC Paintbrush PCX image
DEV D pgm PGM (Portable GrayMap) image
DEV D pgmyuv PGMYUV (Portable GrayMap YUV) image
D S pgssub HDMV Presentation Graphic Stream subtitles
D V D pictor Pictor/PC Paint
DEV D png PNG image
DEV D ppm PPM (Portable PixelMap) image
DEV D prores Apple ProRes
D V D prores_lgpl Apple ProRes (iCodec Pro)
D V D ptx V.Flash PTX image
D A D qcelp QCELP / PureVoice
D A D qdm2 QDesign Music Codec 2
D V D qdraw Apple QuickDraw
D V D qpeg Q-team QPEG
DEV D qtrle QuickTime Animation (RLE) video
DEV D r10k AJA Kona 10-bit RGB Codec
DEV D r210 Uncompressed RGB 10-bit
DEV rawvideo raw video
DEA D real_144 RealAudio 1.0 (14.4K) encoder
D A D real_288 RealAudio 2.0 (28.8K)
D V D rl2 RL2 video
DEA D roq_dpcm id RoQ DPCM
DEV D roqvideo id RoQ video
D V D rpza QuickTime video (RPZA)
DEV D rv10 RealVideo 1.0
DEV D rv20 RealVideo 2.0
D V D rv30 RealVideo 3.0
D V D rv40 RealVideo 4.0
D A D s302m SMPTE 302M
DEV sgi SGI image
D A D shorten Shorten
D A D sipr RealAudio SIPR / ACELP.NET
D A D smackaud Smacker audio
D V D smackvid Smacker video
D V D smc QuickTime Graphics (SMC)
DEV D snow Snow
D A D sol_dpcm DPCM Sol
DEA sonic Sonic
EA sonicls Sonic lossless
D V D sp5x Sunplus JPEG (SP5X)
DES srt SubRip subtitle
D V D sunrast Sun Rasterfile image
DEV D svq1 Sorenson Vector Quantizer 1 / Sorenson Video 1 / SVQ1
D VSD svq3 Sorenson Vector Quantizer 3 / Sorenson Video 3 / SVQ3
DEV D targa Truevision Targa image
D VSD theora Theora
D V D thp Nintendo Gamecube THP video
D V D tiertexseqvideo Tiertex Limited SEQ video
DEV D tiff TIFF image
D V D tmv 8088flex TMV
D A D truehd TrueHD
D V D truemotion1 Duck TrueMotion 1.0
D V D truemotion2 Duck TrueMotion 2.0
D A D truespeech DSP Group TrueSpeech
D A D tta True Audio (TTA)
D A D twinvq VQF TwinVQ
D V D txd Renderware TXD (TeXture Dictionary) image
D V D ultimotion IBM UltiMotion
D V D utvideo Ut Video
DEV D v210 Uncompressed 4:2:2 10-bit
D V D v210x Uncompressed 4:2:2 10-bit
DEV D v308 Uncompressed packed 4:4:4
DEV D v410 Uncompressed 4:4:4 10-bit
D V vb Beam Software VB
D V D vble VBLE Lossless Codec
D V D vc1 SMPTE VC-1
D V D vc1image Windows Media Video 9 Image v2
D V D vcr1 ATI VCR1
D A D vmdaudio Sierra VMD audio
D V D vmdvideo Sierra VMD video
D V D vmnc VMware Screen Codec / VMware Video
DEA D vorbis Vorbis
D VSD vp3 On2 VP3
D V D vp5 On2 VP5
D V D vp6 On2 VP6
D V D vp6a On2 VP6 (Flash version, with alpha channel)
D V D vp6f On2 VP6 (Flash version)
D V D vp8 On2 VP8
D V D vqavideo Westwood Studios VQA (Vector Quantized Animation) video
D A D wavesynth Wave synthesis pseudo-codec
D A D wavpack WavPack
D A wmalossless Windows Media Audio 9 Lossless
D A D wmapro Windows Media Audio 9 Professional
DEA D wmav1 Windows Media Audio 1
DEA D wmav2 Windows Media Audio 2
D A D wmavoice Windows Media Audio Voice
DEVSD wmv1 Windows Media Video 7
DEVSD wmv2 Windows Media Video 8
D V D wmv3 Windows Media Video 9
D V D wmv3image Windows Media Video 9 Image
D V D wnv1 Winnov WNV1
D A D ws_snd1 Westwood Audio (SND1)
D A D xan_dpcm DPCM Xan
D V D xan_wc3 Wing Commander III / Xan
D V D xan_wc4 Wing Commander IV / Xxan
D V D xbin eXtended BINary text
D V D xl Miro VideoXL
DES xsub DivX subtitles (XSUB)
DEV D xwd XWD (X Window Dump) image
DEV D y41p Uncompressed YUV 4:1:1 12-bit
D V yop Psygnosis YOP Video
DEV D yuv4 Uncompressed packed 4:2:0
DEV D zlib LCL (LossLess Codec Library) ZLIB
DEV D zmbv Zip Motion Blocks Video
Stupeflix XML schema XSD