Tengo una lista de archivos de audio alojados para los que me gustaría obtener la duración, sin tener que descargar los archivos.
Puedo hacer esto creando un elemento html DOM <audio>
y extrayendo la duración con el duration
de duración. Esto funciona muy bien en la siguiente aplicación brillante: al hacer clic en el botón "Hacer clic en mí", la duración se devuelve en una alerta.
shinyApp( ui = fluidPage( useShinyjs(), actionButton("btn", "Click me"), tags$audio(id = "myaudio", src = "https://download.samplelib.com/mp3/sample-3s.mp3", type = "audio/mp3", autoplay = NA, controls = NA) ), server = function(input, output) { observeEvent(input$btn, { runjs("alert(myaudio.duration);") }) } )
Este es el punto en el que estoy atascado: ¿Cómo puedo aprovechar este método para extraer la duración de múltiples (> 1'000) mp3?
src=
e iterar una lista de mp3?R
?Esta respuesta solo funciona para un archivo de audio.
Para obtener la duración del audio e imprimirlo, necesitamos usar js
, un entorno en shinyjs
de la siguiente manera:
Defina get_duration
como nuestro JS y especifique qué sucede cuando la entrada cambia a través Shiny.onInputChange
. Aquí también he usado reactiveValues
para almacenar duraciones en el cambio.
library(shinyjs) library(shiny) get_duration <- 'shinyjs.aud_duration = function(params) { var duration = myaudio.duration; Shiny.onInputChange("aud_duration", duration); }' ui <- fluidPage( useShinyjs(), extendShinyjs(text = get_duration, functions = "aud_duration"), actionButton("btn", "Click me"), tags$audio(id = "myaudio", src = "https://download.samplelib.com/mp3/sample-3s.mp3", type = "audio/mp3", autoplay = NA, controls = NA), verbatimTextOutput("aud_duration") ) server <- function(input, output) { js$aud_duration() durations <- reactiveValues(duration = NA) observeEvent(input$btn, durations$duration <- input$aud_duration ) output$aud_duration <- renderText(durations$duration) } shinyApp(ui, server)
Gracias a la respuesta de @NelsonGon, que resolvió parte del problema, pude desarrollar una solución a mi problema que escala y, por lo tanto, funciona en múltiples URL. Resuelve los siguientes problemas:
get_duration <- function(src){ library(shinyjs) library(shiny) get_duration <- 'shinyjs.aud_duration = function(params) { var duration = myaudio.duration; Shiny.onInputChange("aud_duration", duration); }' ui <- fluidPage( useShinyjs(), extendShinyjs(text = get_duration, functions = "aud_duration"), tags$audio(id = "myaudio", src = src), ) server <- function(input, output) { js$aud_duration() durations <- reactiveValues(duration = NA) observe({ invalidateLater(1000) if(!is.null(isolate(input$aud_duration))){ stopApp(input$aud_duration) } }) } shiny::runGadget(ui, server) }
se puede ejecutar de la siguiente manera:
get_duration("https://download.samplelib.com/mp3/sample-3s.mp3") [1] 3.239184