Tuesday, April 25, 2017

FFMpeg Green Screen - A Chroma Key For Every Lock

Green screen effects are older than I am, by a significant margin.

The technique; essentially recording a subject in front of a uniformly colored screen, often green, then taking that recording figuratively making all the green background transparent and finally overlaying on another video.  The result, the subject filmed in from of the green screen appearing in the context of the second video.  Easiest and safest way to film your kids in a shark tank.

Before we get started, the majority of my FFMpeg posts use filters and capabilities that have existed in FFMpeg for quite some time (e.g. v2.7.2), but the chroma key filter is fairly new, I used v3.2.4, but I suspect the capability was introduced some time earlier.

There are a good deal of green screen videos available on YouTube for playing around.  Let's demonstrate how to generate a crude green screen.

Let's start with the green screen subject.

Then, let's look at a video we wish to introduce our subject into.

Sprinkle in a little FFMpeg magic;
Prior to overlaying the two videos, they need to be similar in size and framerate.
$ ffmpeg -n -i foreground.mp4 -ss 20 -t 120 -strict -2 -s hd720 -r 30 foreground-720p.mp4
$ ffmpeg -n -i background.mp4 -ss 20 -t 120 -strict -2 -s hd720 -r 30 background-720p.mp4

Then, specify the two videos, the color of the green screen and some blending factors.

$ ffmpeg -y -i background-720p.mp4 -i foreground-720p.mp4 -filter_complex '[1:v]colorkey=0x008000\:0.3\:0.2[ckout];[0:v][ckout]overlay[out]' -map '[out]' -t 10 greenScreen.mp4

The result:

Now, take your new skills and your own creativity and show the world your new-found powers!

Thursday, April 20, 2017

FFMpeg Fade Controls -- Fade to Black

A pretty common for the open scenes of a video to 'fade in' and 'fade out' at the ending of the video.  Ffmpeg provides a video filter to easily apply fading in/out, the subject of this post.  Saddle up and prepare to be amazed.

Let's start with a simple 30-second video as our input:

Fade In

The video fade-in filter is of the form fade=in:<startFrame><endFrame>, simply specifying a start and stop reference, the fading will begin at the start point and complete at the stop point.  The units, unfortunately, are frame numbers rather than time (e.g. seconds).

Given the video is 24 fps, we can fade into the video in the first 5 seconds by issuing the following command:
$ ffmpeg -y -i opening.mp4 -vf fade=in:0:120 -acodec copy fadeIn-5sec.mp4

Fading in the first 10 seconds by:
$ ffmpeg -y -i opening.mp4 -vf fade=in:0:240 -acodec copy fadeIn-10sec.mp4

Fading in the first 20 seconds by:
$ ffmpeg -y -i opening.mp4 -vf fade=in:0:480 -acodec copy fadeIn-20sec.mp4

Fade Out

The video fade-out filter is of the form fade=out:<startFrame><fade duration>, simply specifying a start and stop reference, the fading will begin at the start point and within the specified duration.  The units, unfortunately, are frames rather than time (e.g. seconds).

Fading out the last 10 seconds is a bit trickier, primarily because of the frame units.  In order to specify the start/duration references we need to know the number of frames in the video and the fps.

Frame count can be determined by:
$ ffprobe -v error -count_frames -select_streams v:0   -show_entries stream=nb_read_frames -of default=nokey=1:noprint_wrappers=1  opening.mp4
10sec = 240 frames

Starting reference would be 719-240 (24fps * 10sec) = 479:
$ ffmpeg -y -i opening.mp4 -vf fade=out:479:240 -acodec copy fadeOut-10sec.mp4

Fade In/Out

You can chain fade in and out affects, for instance to fade in the first 10 seconds and fade out the last 10 seconds:
$ ffmpeg -y -i opening.mp4 -vf fade=in:0:240,fade=out:479:240 -acodec copy fadeInOut.mp4

Now, go forth and use these tricks responsibly.


Sunday, April 9, 2017

Video Ticker -- Give Your Text Some Legs

CNN does it, many videos with lyrics do it, why pray tell aren't you?

We'll explore the introduction of lyrics in future posts, but it's pretty common to overlay text onto a video.  Applying moving text is a bit less common, but easily do-able with a bit of tweaking and patience.

Let's take a simple video, a guaranteed ear wig:

Next, if we grab the lyrics and paste them into a text file; http://www.metrolyrics.com/dowackado-lyrics-roger-miller.html

We can overlay the contents of the lyrics file in the form of moving text by the following command:
$ ffmpeg -y -i video.mp4 -vf "drawtext=enable='gte(t,0)':fontfile=/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf:fontsize=36:fontcolor=white:borderw=5:textfile=lyrics.txt:reload=1:y=h-line_h-10:x=W-((W/tw)*325*n+350)" -acodec copy outVideo.mp4

Whoa, that's worthy of a command breakdown:
The drawtext video filter starts with an enable conditional [e.g. enable='gte(t,0)], while it has little affect in this example, this is a way to turn on the drawtext videofilter after a duration has expired.  This could prove valuable if you wish to postpone the drawing of text later into the video.
The fontfile is precisely that, the preferred font.  You may wish to play around with available fonts to select the most appropriate one for your overlay.
Font size, font color, borderwidth are all specifiers for the overlay font.
The next argument specifies the textfile that contains the overlay contents.  The format of the file is important, consisting of 1 continuous line containing the entirety of the lyrics.  Short pauses in lyrics can be done by adding spaces.
The reload command implies that the lyrics can change from frame to frame.  The last arguments specify the y-position of the beginning of the text.  Notice that the y-position video frame height (e.g. h), minus the height of the text along with an additional offset to draw the text up a bit from the absolute bottom of the video.  The x-position is the more interesting one, starting at the frame width (e.g. W) and frame-by-frame subtracting a dX.

The result:

It takes a good deal of patience and tweaking to get the timing right.

Have fun!

Friday, April 7, 2017

Hello Again -- I'm Back Baby!

Whelp, it's been quite some time since I authored a post.  Not to make excuses, but I kinda took it pretty tough when Danny Trejo, a long-time dedicated fan, unsubscribed from my blog posts.  Despite the fact that I painstakingly watched 'Machete', 'Machete Kills' and have pre-ordered tickets for 'Machete Kills in Space', Danny can't spare the time to read my itty-bitty blog.

Oh well, time goes on and I've gotten back on the old horse, you should see some new stuff coming your way next week.