Video Language (or just Video) is a functional-declarative language for manipulating videos from many input sources: images, video files, even live streams.
Rather than evaluating programs for their effects, expressions in Video combine to describe a single video stream. Thus, Video allows authors to write videos in a similar fashion to how LaTeX enables authors to write documents.
All VidLang programs begin with #lang video, the remaining program is a description of the resulting video. Each top level expression is a producer which is anything that produces a video stream. For example, the color producer generates a stream of green frames:
When the module above is converted into a video, the output looks something like:
raco video --preview green.vid
The color function creates an infinitely long producer. The producer’s length can optionally be set explicitly with its properties. If the length is not set, the producers length will automatically set itself to fit the surrounding context. Another function, clip does create a producer from a file:
The clip function uses optional keywords for #:start and #:end. These are syntactic sugar for the properties table directly:
Filters can be attached to every producer. These filters modify the producers behavior: turning it grayscale, changing the aspect ratio, etc. The attach-filter function attaches filters to an existing producer. For example, we can use the grayscale-filter to remove the color from the rotating square clip earlier:
An alternative approach would be to use the #:filters keyword associated with producers.
Video shines when combining multiple producers. The language provides two ways of combining producers, playlists and multitracks. To a first approximation, playlists run producers sequentially, while multitracks play them simultaneously.
Playlists are themselves producers. As such, the playlist function also serves to append multiple playlists together. This example combines the playlist from above with another similar clip of a ball dropping:
#lang video square-movie ball-movie (define square-movie (playlist (clip "spinning_square.mp4" #:properties (hash "start" 0 "end" 2)) (clip "spinning_square.mp4" #:properties (hash "start" 2 "end" 4) #:filters (list (grayscale-filter))))) (define ball-movie (playlist (clip "ball_drop.mp4" #:properties (hash "start" 0 "end" 2)) (clip "ball_drop.mp4" #:properties (hash "start" 2 "end" 4) #:filters (list (grayscale-filter)))))
This is also true of functions created with and . But this feature is experimental.
Transitions can be placed directly in a playlist, and combine the producers directly before and after them:
#lang video (clip "ball_drop.mp4" #:properties (hash "start" 0 "end" 5)) (fade-transition 2) (clip "ball_drop.mp4" #:properties (hash "start" 5 "end" 10) #:filters (list (grayscale-filter)))
#lang video (define colored (clip "ball_drop.mp4" #:properties (hash "start" 0 "end" 5))) (define black+white (clip "ball_drop.mp4" #:properties (hash "start" 5 "end" 10) #:filters (list (grayscale-filter)))) (playlist colored black+white #:transitions (list (fade-transition 2 #:start colored #:end black+white)))
Multitracks play multiple producer simultaneously. Unlike in a playlist, only the top most track will be rendered. Merges combine different tracks in a multitrack. These can be anything from a video overlay, to a chroma key effect. As with transitions in playlists, composite merges can be inlined with the producers in the multitrack’s.
#lang video (multitrack (blank #f) (composite-merge 0 0 1/2 1) (clip "spinning_square.mp4") (composite-merge 1/2 0 1/2 1) (clip "dropping_ball.mp4"))
#lang video (multitrack bg spinning-square dropping-ball #:merges (list (composite-merge 0 0 1/2 1 #:top spinning-square #:bottom bg) (composite-merge 1/2 0 1/2 1 #:top dropping-ball #:bottom bg))) (define bg (blank #f)) (define spinning-square (clip "spinning_square.mp4")) (define dropping-ball (clip "dropping_ball.mp4"))
#lang video (define the-ultimate-color (color "green" #:properties (hash "the-ultimate-property" 42))) (get-property the-ultimate-color "the-ultimate-property") ; => 42
Some properties are implicitly associated with an object by the Video runtime. Such as the width and height of an image, or the length of a clip. For example, the following module will play the first half of the "epic.mp4" movie.
The raco video tool is the most simple way to render video files. To get a list of its current set of features, run:
raco video --help
By default, raco video will render your file to a pre-specified format. You can also open up a preview window playing the program with the --preview flag.