Working with Video in R
Switch branches/tags
Nothing to show
Clone or download
Latest commit 687e024 Oct 17, 2018

README.md

av

R Bindings to FFmpeg

Project Status: Active – The project has reached a stable, usable state and is being actively developed. Build Status AppVeyor Build Status CRAN_Status_Badge

Installation

You can install av from CRAN

install.packages("av")

You can install the development version from GitHub with:

# Install from GH
devtools::install_github("ropensci/av")

# For the demo
devtools::install_github("thomasp85/gganimate")

Demo Video

Generate a demo video with some random plots and free demo music:

av::av_demo()

This demo is totally lame, please open a PR with something better (in base R!).

Using gganimate

You can use av_encode_video() as the renderer in gganimate:

# Get latest gganimate
# devtools::install_github("thomasp85/gganimate")
library(gganimate)

# Define the "renderer" for gganimate
av_renderer <- function(vfilter = "null", filename = 'output.mp4'){
  function(frames, fps){
    unlink(filename)
    av::av_encode_video(frames, filename, framerate = fps, vfilter = vfilter)
  }
}

# Create the gganimate plot
p <- ggplot(airquality, aes(Day, Temp)) + 
  geom_line(size = 2, colour = 'steelblue') + 
  transition_states(Month, 4, 1) + 
  shadow_mark(size = 1, colour = 'grey')

# Render and show the video
q <- 2
df <- animate(p, renderer = av_renderer(), width = 720*q, height = 480*q, res = 72*q, fps = 25)
utils::browseURL('output.mp4')

Video Filters

You can add a custom ffmpeg video filter chain. For example this will negate the colors, and applies an orange fade-in effect to the first 15 frames.

# Continue on the example above
myrenderer <- av_renderer(vfilter = 'negate=1, fade=in:0:15:color=orange')
df <- animate(p, renderer = myrenderer, width = 720*q, height = 480*q, res = 72*q, fps = 25)
av::av_video_info('output.mp4')
utils::browseURL('output.mp4')

Filters can also affect the final fps of the video. For example this filter will double fps because it halves presentation the timestamp (pts) of each frame. Hence the output framerate is actually 20!

myrenderer <- av_renderer(vfilter = "setpts=0.5*PTS")
df <- animate(p, renderer = myrenderer, fps = 10)
av::av_video_info('output.mp4')
utils::browseURL('output.mp4')

Capture Graphics

Beside gganimate, we can use av_capture_graphics() to automatically record R graphics and turn them into a video. This example makes 12 plots and adds an interpolation filter to smoothen the transitions between the frames.

library(gapminder)
library(ggplot2)
makeplot <- function(){
  datalist <- split(gapminder, gapminder$year)
  lapply(datalist, function(data){
    p <- ggplot(data, aes(gdpPercap, lifeExp, size = pop, color = continent)) +
      scale_size("population", limits = range(gapminder$pop)) + geom_point() + ylim(20, 90) +
      scale_x_log10(limits = range(gapminder$gdpPercap)) + ggtitle(data$year) + theme_classic()
    print(p)
  })
}

# Play 1 plot per sec, and use an interpolation filter to convert into 10 fps
video_file <- file.path(tempdir(), 'output.mp4')
av::av_capture_graphics(makeplot(), video_file, 1280, 720, res = 144, vfilter = 'framerate=fps=10')
av::av_video_info(video_file)
utils::browseURL(video_file)