How to stop audio with shinyjs

I am having trouble stopping sounds from playing in shinyjs. I've used a function like the following to play a sound, but I would like that each time this function is called again, it stops any previous sounds from playing before playing the new sound.

shinyjs.soundmaker = function() {
  var snd = new Audio("data:audio/wav;base64,blablablabla"); # here would be a long text part for the sound
  snd.play();
}

I have tried simply starting the function with a sound pause command to no avail:

shinyjs.soundmaker = function() {
  snd.pause();
  var snd = new Audio("data:audio/wav;base64,blablablabla"); # here would be a long text part for the sound
  snd.play();
}

and also tried writing it like 'window.snd = new Audio' etc., as apparently the 'window' should make snd accessible globally. However, nothing I can think of seems to work as intended. Is there a way to make this function so that whenever it is called, any previously playing sounds are stopped?

The solution to this problem using js and R Shiny is to create a separate js function that stops sounds from playing. Then, each time you want to start a new sound, you first also call the sound stopping function - hence, any previously playing sound will be stopped before the new one begins.

library(shiny)
library(shinyjs)

ui <- fluidPage(

    useShinyjs(),
    
    extendShinyjs(script = "marbles.js"),
    extendShinyjs(script = "birds.js"),
    extendShinyjs(script = "stopper.js"),
    
    column(10, offset = 1,
           align = "center",
           fluidRow(column(4,
                           align = "center",
                           column(10,
                                  align = "center",
                                  offset = 1,
                                  br(),
                                  actionButton('sound1','Sound 1', width = '100%',
                                               style="color: #ffffff; background-color: #35467b; border-color: #2e1911"))),
                    column(4,
                           align = "center",
                           column(10,
                                  align = "center",
                                  offset = 1,
                                  br(),
                                  actionButton('sound2','Sound 2', width = '100%',
                                               style="color: #ffffff; background-color: #1dbd6b; border-color: #1dbd6b"))),
                    column(4,
                           align = "center",
                           column(10,
                                  align = "center",
                                  offset = 1,
                                  br(),
                                  actionButton('stopper','Stop sounds', width = '100%',
                                               style="color: #ffffff; background-color: #b73838; border-color: #b73838")))
           )),
)

server <- function(input, output) {

    observeEvent(input$sound1, {
        
        js$stopper()
        js$birds()
        
    })
    
    observeEvent(input$sound2, {
        
        js$stopper()
        js$marbles()
        
    })
    
    observeEvent(input$stopper, {
        
        js$stopper()
        
    })
    
    
}

# Run the application 
shinyApp(ui = ui, server = server)

The sound stopping function is simple:

shinyjs.stopper = function() {
  
  snd.pause();
  
}

Then the two sound functions would be the following, but you insert your own base64 plain text in the 'new audio' part (to convert a wav to base64, see e.g.: WAV to Base64 | Audio | Base64 Encode | Base64 Converter | Base64). All the javascript functions should be saved as js files in the same folder as your app:

shinyjs.birds = function() {
  snd = new Audio("data:audio/wav;base64,blablablabla");
  snd.play();
}

shinyjs.marbles = function() {
  snd = new Audio("data:audio/wav;base64,blablablabla");
  snd.play();
}

In short, for whatever reason, it doesn't seem to work to just call sound.pause() at the start of the function where you make a new sound start playing. Instead, make a separate function that stops the sound, and then run the new sound afterwards.

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.