1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217
|
---
header-includes: |
\DeclareUnicodeCharacter{03C0}{$\pi$}
---
Basically streaming videos does not change anything compared to streaming audio:
you just have to use video files instead of sound files! For instance, if you
want to stream a single file to an icecast server in ogg format (with theora and
vorbis as codecs for audio and video) you can simply type:
```{.liquidsoap include="video-simple.liq"}
```
And of course you could have used a `playlist` instead of `single` to have
multiple files, or used other [formats](encoding_formats.html) for the stream.
In order to test a video stream, it is often convenient to use the `output.sdl`
operator (or `output.graphics`) which will open a window and display the video
stream inside. These can handle streams with video only, you can use the
`drop_audio` operator to remove the sound part of a stream if needed.
You should be expecting much higher resource needs (in cpu time in particular)
for video than for audio. So, be prepared to hear the fan of your computer! The
size of videos have a great impact on computations; if your machine cannot
handle a stream (i.e. it's always catching up) you can try to encode to smaller
videos for a start.
### Setting up frame size and positions
We provide an abstract API to specify video frame sizes and positions that is independent
from the actual rendered size. This way, you can define all your elements and have them
being rendered at different frame size without having to change their placement or size values!
This works by setting up a _virtual canvas_ that is larger than the _actual canvas_. You specify
your positions, sizes etc. in terms of units for the larger canvas and they are translated automatically
to values that apply for the actual canvas.
We provide some default values. They are all `16:9` ratio using a virtual canvas of `10 000` pixels height:
```{.liquidsoap include="video-default-canvas.liq"}
```
The returned canvas is a record with the following methods:
- `width`/`height`: size of the actual frame
- `px`: define values in terms of virtual pixels
- `vw`/`vh`: define values in terms of percentage (between `0.` and `1.`) of, resp., the actual frame width and height
- `rem`: define values in terms of percentage (between `0.` and `1.`) of the default font size
All the positioning methods are functions. For convenience, you can use the infix operator `@` to make things more readable. For instance,
instead of writing `px(120)` to define a size of `120px`, you can write: `120 @ px`. These two notations are equivalent but the second
one is more readable in this context.
Here's an example of how to use this:
```{.liquidsoap include="video-canvas-example.liq"}
```
### Encoding with FFmpeg
The `%ffmpeg` encoder is the recommended encoder when working with video. Not only does it support a wide range
of audio and video formats but it can also send and receive data to many different places, using `input.ffmpeg.`
and `output.url`. On top of that, it also supports all the [FFmpeg filters](https://ffmpeg.org/ffmpeg-filters.html)
and passing encoded data, if your script does not need re-encoding.
The syntax for the encoder is detailed in the [encoders page](encoding_formats.html). Here are some examples:
```liquidsoap
# AC3 audio and H264 video encapsulated in a MPEG-TS bitstream
%ffmpeg(format="mpegts",
%audio(codec="ac3",channel_coupling=0),
%video(codec="libx264",b="2600k",
"x264-params"="scenecut=0:open_gop=0:min-keyint=150:keyint=150",
preset="ultrafast"))
# AAC audio and H264 video encapsulated in a mp4 file (to use with
# `output.file` only, mp4 container cannot be streamed!
%ffmpeg(format="mp4",
%audio(codec="aac"),
%video(codec="libx264",b="2600k"))
# Ogg opus and theora encappsulated in an ogg bitstream
%ffmpeg(format="ogg",
%audio(codec="libopus"),
%video(codec="libtheora"))
# Ogg opus and VP8 video encapsulated in a webm bitstream
%ffmpeg(format="webm",
%audio(codec="libopus"),
%video(codec="libvpx"))
```
### Streaming with FFmpeg
The main input to take advantage of FFmpeg is `input.ffmpeg`. It should be able to decode pretty much any url and file that the `ffmpeg` command-line
can take as input. This is, in particular, how `input.rtmp` is defined.
For outputting, one can use the regular outputs but some of them have special features when used with `%ffmpeg`:
- `output.file` is able to properly close a file after it is done encoding it. This makes it possible to encode in formats that need a proper header after encoding is done, such as `mp4`.
- `output.url` will only work with the `%ffmpeg` encoder. It delegates data output to FFmpeg and can support any url that the `ffmpeg` command-line supports.
- `output.file.hls` and `output.harbor.hls` should only be used with `%ffmpeg`. The other encoders do work but `%ffmpeg` is the only encoder able to generate valid `MPEG-TS` and `MP4` data segments for the HLS specifications.
## Useful tips & tricks
Video is a really exciting world where there are lots of cool stuff to do.
### Transitions
Transitions at the beginning or at the end of video can be achieved using
`video.fade.in` and `video.fade.out`. For instance, fading at the beginning of
videos is done by
```{.liquidsoap include="video-transition.liq" from="BEGIN" to="END"}
```
### Adding a logo
You can add a logo (any image) using the `video.add_image` operator, as follows:
```{.liquidsoap include="video-logo.liq" from="BEGIN" to="END"}
```
### Inputting from a webcam
If your computer has a webcam, it can be used as a source thanks to the
`input.v4l2` operator. For instance:
```{.liquidsoap include="video-webcam.liq"}
```
### Video in video
Suppose that you have two video sources `s` and `s2` and you want to display a
small copy of `s2` on top of `s`. This can be achieved by
```{.liquidsoap include="video-in-video.liq" from="BEGIN" to="END"}
```
### Scrolling text
Adding scrolling text at the bottom of your video is as easy as
```{.liquidsoap include="video-text.liq"}
```
You might need to change the `font` parameter so that it matches a font file
present on your system.
### Effects
There are many of effects that you can use to add some fun to your videos:
`video.greyscale`, `video.sepia`, `video.lomo`, etc. [Read the
documentation](reference.html) to find out about them. If you have compiled
Liquidsoap with [frei0r](http://www.piksel.org/frei0r/) support, and have
installed frei0r plugins, they will be named `video.frei0r.*`. You can have a
list of those supported on your installation as usual, using `liquidsoap --list-plugins`.
### Presenting weather forecast
You can say that a specific color should be transparent using
`video.transparent`. For instance, you can put yourself in front of a blue
screen (whose RGB color should be around 0x0000ff) and replace the blue screen
by an image of the weather using
```{.liquidsoap include="video-weather.liq" to="END"}
```
## Detailed examples
### The anonymizer
Let's design an ``anonymizer`` effect: I want to blur my face and change my voice
so that nobody will recognise me in the street after seeing the youtube
video. [Here (YouTube)](https://www.youtube.com/E7Fb0wV3h5Q) is what we are going to achieve.
This video was produced thanks to the following script:
```{.liquidsoap include="video-anonymizer.liq"}
```
### Controlling with OSC
In this example we are going to use OSC integration in order to modify the
parameters in realtime. There are many OSC clients around, for instance I used
[TouchOSC](http://hexler.net/software/touchosc) :
[Result (YouTube)](https://www.youtube.com/EX1PTjiuuXY)
Here is how the video was made:
```{.liquidsoap content="video-osc.liq"}
```
### Blue screen
You want to show yourself in front of a video of a bunny, as in
You want to show yourself in front of a video of a bunny, as in [this result (YouTube)](https://www.youtube.com/zHikXRNMQu4)
The idea is to film yourself in front of a blue screen, make this blue screen
transparent and put the resulting video in front of the bunny video (actually, I
don't have a blue screen at home, only a white wall but it still kinda works).
```{.liquidsoap include="video-bluescreen.liq"}
```
|