ropensci / av

Working with Video in R
https://docs.ropensci.org/av
Other
92 stars 10 forks source link

webm encoding slower through av than from command line #11

Open thomasp85 opened 5 years ago

thomasp85 commented 5 years ago

It appears encoding to webm is much slower when done through av, compared to calling ffmpeg directly from the command-line. This is only a difference for the webm format as mp4 has the same encoding time no matter how you call it...

pngfile <- tempfile(fileext = '.png')
webmfile <- tempfile(fileext = '.webm')
mp4file <- tempfile(fileext = '.mp4')
png(pngfile)
plot(1:10, 1:10)
dev.off()
#> quartz_off_screen 
#>                 2
system.time(av::av_encode_video(rep(pngfile, 100), output = webmfile))
#>    user  system elapsed 
#>  11.214   0.073  11.321
system.time(av::av_encode_video(rep(pngfile, 100), output = mp4file))
#>    user  system elapsed 
#>   0.957   0.066   0.467

Created on 2018-12-11 by the reprex package (v0.2.1)

jeroen commented 5 years ago

Thanks. Some hypotheses:

thomasp85 commented 5 years ago

Hmm... constructing a minimal equivalent system call seems to make the difference much smaller than I experienced through gganimate... It is still there, but not as extreme

pngfile <- tempfile(fileext = '.png')
webmfile <- tempfile(fileext = '.webm')
mp4file <- tempfile(fileext = '.mp4')
png(pngfile)
plot(1:10, 1:10)
dev.off()
#> quartz_off_screen 
#>                 2
system.time(av::av_encode_video(rep(pngfile, 100), output = webmfile))
#>    user  system elapsed 
#>  11.516   0.078  11.706
system.time(av::av_encode_video(rep(pngfile, 100), output = mp4file))
#>    user  system elapsed 
#>   0.760   0.057   0.368

pngfiles <- sprintf(paste0(file.path(tempdir(), 'file'), '%04d.png'), seq_len(100))
file.copy(pngfile, pngfiles)
#>   [1] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
#>  [15] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
#>  [29] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
#>  [43] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
#>  [57] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
#>  [71] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
#>  [85] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
#>  [99] TRUE TRUE
glob <- file.path(dirname(pngfiles[1]), sub('^.*(\\..+$)', 'file%4d\\1', basename(pngfiles[1])))

system.time(system2(
  'ffmpeg', 
  c("-pattern_type sequence",
    paste0('-i ', glob),
    '-y',
    webmfile
)))
#>    user  system elapsed 
#>  14.822   0.127   8.186

Created on 2018-12-11 by the reprex package (v0.2.1)

jeroen commented 5 years ago

Can you compare if the two different outputs have the same bitrate / quality parameters?

thomasp85 commented 5 years ago

what settings do I need to set on the command line to ensure the same quality as default av?

jeroen commented 5 years ago

I would think they use the same defaults, but perhaps the command line is overriding this. You can try the ffprobe command line util on both video files to check the bitrate (or av::av_video_info)

thomasp85 commented 5 years ago

av's default bitrate is x20 of using the command line (32 kb/s vs 664 kb/s) so this might indeed be the reason

jeroen commented 5 years ago

We probably need something like this but then for webm:

https://github.com/ropensci/av/blob/f54806d3527f4379e0f59cbabafb81328a59c193/src/video.c#L301-L304

thomasp85 commented 5 years ago

I think if it is just because av chooses a higher quality default setting, then it is not a problem... I was more worried that av was doing some unnecessary work of some sort that resulted in a slowdown

jeroen commented 5 years ago

Well it's still nice to get it sorted out to use a sensible default.

jeroen commented 5 years ago

If I add -b:v 0 to the command line as recommended here the speed is quite similar as in av. 🤔