2. A Tour of Yo

Welcome to the world of Yo! Here we are going to produce a movie clip with only a few lines of codes.

2.1. Motivation of Yo

Although video editting requires visualization in user interface to be more precise and easy to operate for movie makers, there are some tasks that are more suitable for a programming solution rather than doing it manually.

For example, there may be a video editting task that requires a lot of repeatable but trivial operations such as concatenate many photo frames to get a time-elapse video. Or there is an analytical task where we want to cut off all black frames and silent part from a very long video. Search for a certain pattern is easy for machine but requires plenty of time if do it manually. The logic is pretty straightforward but no video editting software could provide an easy and quick solution for these kind of tasks.

That is why we proposed Yo.

2.2. Example for impatients

2.2.1. A time elapse video

The following program creates a time-elapse video with thousands of photographs with only 5 lines of code:

photos = Clip[]("photo/")       # read all pics in photos/ and create a array of clips
mymovie = Clip()                # create mymovie for final rendering
for p in photos:                # set the playing time of every pic as 1 frame
    mymovie = mymovie & p[1:2]  # and concatenate it to the end of the main clip
mymovie.save("timelapse.webm")  # render and save the file

The input files are directly taken from the camera storage. The filenames are automatically generated by camera, in ascending order of shot taken time, which gurantees the order of frames.

The operator & means to concatenate in Yo language. As p is an image file, it is viewed as a video clip with same content at every frame, and infinite length. p[1:2] builds up a video clip from frame 1 to frame 2, of that infinte long frame. Thus it forms a picture of 1 frame long.

The output can be viewed here: In a new window

Special thanks to Mr Li for photography.

2.2.2. Flash in a Fibonacci way

The following code adds a bunch of white flashes on a video, with a interval of seconds of fibonacci numbers:

fib = Int[]()
fib.add(1)
fib.add(1)
for i = 2 to 12:
    fib.add((fib[i - 1]) + (fib[i - 2]))  # calculate the fibonacci numbers
a = Clip("Muppets.mp4")[0:420]            # read a clip and select the first 420 frames
for i = 1 to 12:
    white = Clip("white.png")[1:11]       # create a clip with pure white color for 10 frames
    white.alpha @ 0 = 0.0                 # set the alpha value to 0.0 at 0th frame
    white.alpha @ 5 = 1.0                 # set the alpha value to 1.0 at 5th frame
    a = a ^ white @ (fib[i])              # put the white screen on top of the original clip
    a.save("flashwithfib.webm")           # with an offset of fibonacci numbers

In the first five lines we calculate the first 13 Fibonacci number in a dynamic programming way. Results are stored in array fib.

In the loop, we first build up a white flash. The flash is built from a pure white png file with a length of 10 frame. Then we adjust the alpha value of the 5th frame. Yo would do the interpolation at every frame so we could see a gradual change in alpha value. The screen gradually become white then the white fade out. That’s the job done by operator @. Which could be easily understood for its semantic meaning.

In the statement a = a ^ white @ (fib[i]) we put the white flash clip on the top of the original video clip. It’s just like adding a new layer in Photoshop, or a new sequence in Premier. So we could see through the transparent white flash layer.

See the visualization of timeline below to understand the offset of Fibonacci.

The output can be viewed here: In a new window

Special thanks to Stephen Edwards for providing the movie clip.

2.2.3. Video Content Analyzing

Yo is also capable for video content analyzing. User may get a frame of a clip at a specific time, a pixel of a frame at a specific coordinate, and the RGB values of a specific pixel. Various analyzing can be developed based on this. The following program analyzes an input video and cut off the black screen at the end of the video.

# a function definition, reads Clip and Int, returns with Bool
func isblack(a: Clip, f: Int) -> Bool:
    for i = 300 to 350:
        for j = 200 to 250:
            # get pixel at frame f at coordinate (i,j)
            p = a<i!j>@f
            # get RGB values of the pixel
            if (p.R == 0) && (p.G == 0) && (p.B == 0):
                return true
    return false
a = Clip("video-with-black-screen.webm")
cuttime = 0
for time = 1 to 180:
    # if a black screen detected
    if isblack(a,time):
        cuttime = time
        # log it to standard output
        log("black screen detected, cut at:")
        log(cuttime)
        break
b = a[1:cuttime]
b.save("video-without-black-screen.webm")

This tasks involves more subtle manipulation on video content. The function isblack is defined to check if a certain area of a frame consists of all black pixels, then return with a judgement of whether this frame is a black screen.

In the main process, we go through all frames in the video and cut out all black frames. In addition, the built-in function log is used to write execution logs to the standard output.

2.3. Features

Features in video editting level:

  • Video and Audio cropping and concatenating
  • Video and Audio Effects (Chroma Key, Color Adjustment, Grayscale, etc…)
  • Multi­Layer Compositing
  • Animation Curves (Bézier, Linear, Constant)
  • Time Mapping (Curve­based Slow Down, Speed Up, Reverse)
  • Audio Mixing & Resampling
  • Frame Rate Conversions
  • Multi­Processor Support (Performance)
  • Unit Tests (Stability)
  • All FFmpeg Formats and Codecs Supported (Images, Videos, and Audio files)

Features in language level:

  • Basic arithemtic, boolean, string operations and control flow (condition / loop)
  • Use indent as blocks
  • Type inference
  • Object-oriented
  • User-defined type and function supported
  • Lambda calculation
  • Built-in functions for file system, video rendering etc.
  • Competiable with C++ libraries imported