Search code examples
rshinyaudio-streaminguislider

Trigger audio files using a slider in R Shiny


Hi I'm trying to develop a Shiny app where a moveable slider triggers the audio samples, whereby each point in a slider (say ranging from 0 to 100) is mapped to a specific audio. So moving the slider will alter the sound according to the slider position. Ideally, I would want the transition between slider positions to smooth sounding and highly interactive.

I'm guessing I would need to use the code below to map each slider value to a specific audio file.

tags$audio(src = "sound.mp3", type = "audio/mp3", autoplay = NA, controls = NA)

Anyone know of the best approach for getting such task done or give me some pointers?


Solution

  • You can change the src argument via JS and trigger the change with the slider. Please check the following:

    library(shiny)
    library(htmltools)
    library(tuneR)
    library(shinyjs)
    
    xseq <- round(seq(from = 440, to = 880, length.out = 100), digits = 0)
    
    if(!dir.exists("audio")){
      dir.create("audio")
    }
    
    # create some audio files
    filenames = paste0("audio/", xseq, ".wav")
    for (i in seq_along(xseq)) {
      Wobj <- sine(xseq[i])
      writeWave(Wobj, filename = filenames[i])
    }
    
    # Add directory of static resources to Shiny's web server
    addResourcePath(prefix = "audioResources", directoryPath = "audio")
    
    myAudioResources <- paste0("audioResources/", xseq, ".wav")
    
    ui <- fluidPage(
      useShinyjs(),
      tags$audio(id = "myaudio", controls = NA, autoplay = NA, src = ""),
      sliderInput(inputId = "selectTrack", "Select track", min = 1,
                  max = length(xseq),
                  value = 1)
    )
    
    server <- function(input, output, session) {
      observeEvent(input$selectTrack, {
        runjs(sprintf("document.getElementById('myaudio').src = '%s';", myAudioResources[input$selectTrack])) # dynamically change src
      })
    }
    
    shinyApp(ui, server)
    

    This is based on my earlier answer here.