0

I have a bunch of .avi files I would like to load into R, breakdown each frame as an individual image, arrange the images, and save as a separate image. In spite of a sincere effort to try to find a package to load .avi files, I can't find anything.

1) is it possible to load and work with avi files in r?

2) how is this done?

3) is there a specific library for this?

Ive seen several examples using linux, such as this post, but I'm hoping for an R solution.

Converting AVI Frames to JPGs on Linux

Phil_T
  • 942
  • 9
  • 27
  • Maybe CRAN package [Rbgs](https://cran.r-project.org/web/packages/Rbgs/index.html). See function `readvideo {Rbgs}`. – Rui Barradas Sep 03 '18 at 19:17
  • Have you tried the [imager package](https://dahtah.github.io/imager/imager.html#loading-and-saving-videos)? – Stéphane Laurent Sep 03 '18 at 19:20
  • Yeah, tried imager. Its not specific for avi formates though. I have not tried Rbgs. I noticed that many people have bash solutions using the Magick package. This is now available in R, so I was going to try that next. – Phil_T Sep 03 '18 at 19:24
  • On second thought, imager should work. I'll post a solution as soon as I figure it out. – Phil_T Sep 03 '18 at 19:40
  • FFmpeg is the package most programs in R use to load video files into the r environment. – Phil_T Sep 03 '18 at 20:21

1 Answers1

0

I figured this out. As indicated in the comments section, ffmpeg is the package called by various packages in R to load videos into the R environment. The Imager package has a function called "load.video.internal" that works well and uses ffmpeg. I had to down load the package from github because this function was not available in the version I installed using "install.packages". I ended up copy/pasting the function from the source package and commenting out the reference to the "has.ffmpeg" function because it kept hanging at this step. Using paste, I was able to indicate the file path and load an avi file successfully.

Modified load.video.internal function:

load.video.internal <- function(fname,maxSize=1,skip.to=0,frames=NULL,fps=NULL,extra.args="",verbose=FALSE)
{
  # if (!has.ffmpeg()) stop("Can't find ffmpeg. Please install.")
  dd <- paste0(tempdir(),"/vid")
  if (!is.null(frames)) extra.args <- sprintf("%s -vframes %i ",extra.args,frames)
  if (!is.null(fps)) extra.args <- sprintf("%s -vf fps=%.4d ",extra.args,fps)

  arg <- sprintf("-i %s %s -ss %s ",fname,extra.args,as.character(skip.to)) %>% paste0(dd,"/image-%d.bmp")
  tryCatch({
    dir.create(dd)
    system2("ffmpeg",arg,stdout=verbose,stderr=verbose)
    fls <- dir(dd,full.names=TRUE)
    if (length(fls)==0) stop("No output was generated")
    ordr <- stringr::str_extract(fls,"(\\d)+\\.bmp") %>% stringr::str_split(stringr::fixed(".")) %>% purrr::map_int(~ as.integer(.[[1]])) %>% order
    fls <- fls[ordr]
    #Check total size
    imsz <- load.image(fls[[1]]) %>% dim %>% prod
    tsz <- ((imsz*8)*length(fls))/(1024^3)
    if (tsz > maxSize)
    {
      msg <- sprintf("Video exceeds maximum allowed size in memory (%.2d Gb out of %.2d Gb)",tsz,maxSize)
      unlink(dd,recursive=TRUE)
      stop(msg)
    }
    else
    {
      out <- map_il(fls,load.image) %>% imappend("z")
      out

    } },
    finally=unlink(dd,recursive=TRUE))

}

Example of its use:

vid_in <- load.video.internal(paste("/home/phil/Documents/avi_files/Untitled.avi"))

UPDATED SIMPLER VERSION:

the magick package will read avi files using the image_read function.

Phil_T
  • 942
  • 9
  • 27