Consider the following minimal reprex:
library(shiny)
library(stringr)
library(av)
ui <- fluidPage(
sidebarPanel(
actionButton('movie_run', "Let's Go!")
),
mainPanel(uiOutput("movie"))
)
server <- function (input, output) {
observeEvent(input$movie_run, {
output$movie <- NULL
for (i in 1:48) {
plot.mat <- matrix(data = rnorm(n = 100), nrow = 10, ncol = 10)
png(filename = file.path("www", paste0(str_pad(
string = i, width = 3, side = "left", pad = "0"), ".png")))
print("PNG file successfully created!")
par(mar = rep(0,4))
print("Margins successfully set!")
image(plot.mat)
print("Image successfully plotted!")
dev.off()
print("Plotting Device successfully closed!")
}
png.files <- file.path("www", list.files(path = "www", pattern = "\\.png$"))
av_encode_video(input = png.files,
output = file.path("www", "movie.mp4"),
framerate = 24)
unlink(x = png.files)
output$movie <- renderUI({
tags$video(
width="auto", height="auto", controls="", autoplay = "", loop = "",
tags$source(src=paste0("movie.mp4"), type="video/mp4")
)
})
})
}
(The app requires to have a folder called "www" in the app folder)
The app runs fine on my local machine (specs see below), but on shinyapps.io I get in the logs:
[1] "PNG file successfully created!"
[1] "Margins successfully set!"
Warning: Error in plot.new: could not open file 'www/001.png'
15: <Anonymous>
13: fn
8: retry
7: connect$retryingStartServer
6: eval
5: eval
4: eval
3: eval
2: eval.parent
1: local
And the application greys out and shows a "Disconnected from the Server. Reload" message.
I have consulted this FAQ and this SO answer, which suggests to use file.path
for platform-independent file paths and graphics.off
to close plotting devices, to no avail. This related question was solved by using relative file paths, which I did anyway.
Curiously enough, the app sometimes, but rarely works.
I'm wondering whether my storage space on shinyapps.io could be the problem (other apps running), but according to the shinyapps.io documentation, this should not be the case (ephemeral storage, data deleted after a session is closed).
Local sessionInfo()
:
R version 4.3.0 Patched (2023-05-02 r84382)
Platform: aarch64-apple-darwin20 (64-bit)
Running under: macOS Ventura 13.0.1
Matrix products: default
BLAS: /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libBLAS.dylib
LAPACK: /Library/Frameworks/R.framework/Versions/4.3-arm64/Resources/lib/libRlapack.dylib; LAPACK version 3.11.0
locale:
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/C/en_US.UTF-8
time zone: Europe/Zurich
tzcode source: internal
attached base packages:
[1] stats graphics grDevices utils datasets methods base
other attached packages:
[1] rsconnect_1.0.1 av_0.8.3 stringr_1.5.0 shiny_1.7.4
loaded via a namespace (and not attached):
[1] crayon_1.5.2 vctrs_0.6.2 cli_3.6.1 rlang_1.1.1 stringi_1.7.12 renv_1.0.0 promises_1.2.0.1
[8] jsonlite_1.8.4 xtable_1.8-4 glue_1.6.2 openssl_2.0.6 askpass_1.1 htmltools_0.5.5 httpuv_1.6.9
[15] sass_0.4.6 jquerylib_0.1.4 ellipsis_0.3.2 fastmap_1.1.1 lifecycle_1.0.3 memoise_2.0.1 compiler_4.3.0
[22] Rcpp_1.0.11 rstudioapi_0.14 later_1.3.1 digest_0.6.31 R6_2.5.1 curl_5.0.2 magrittr_2.0.3
[29] bslib_0.4.2 tools_4.3.0 withr_2.5.0 mime_0.12 cachem_1.0.8
Any ideas?
As mentioned in the comments, rsconnect::deployApp
does not copy empty directories to the remote server. The problem is solved when you put a .txt
file (or presumably any other file) into www
locally and deploy then. This way, www
is copied and the app works as desired.
Thanks to r2evans for pointing me in the right direction.