1

I'm trying to change the volume on my audio tag in my Shiny app. Some sites that I've looked into show that you can directly use the "volume" argument within the audio tag to set it but I have not been able to reproduce it.

This site https://www.w3schools.com/jsref/prop_audio_volume.asp and https://www.w3schools.com/jsref/tryit.asp?filename=tryjsref_audio_volume that I found uses Javascript to update the volume but I cannot figure out how to call a function created in Javascript in Shiny. Any help is much appreciated.

library(shiny)
library(shinyjs)

ui <- fluidPage(
  useShinyjs(),
  tags$audio(id = "myAudio", controls = NA, autoplay = NA, tags$source(src="aud.mpeg")),
  br(),
  actionButton("mybutton", "Submit"),

  tags$script('
    var x = document.getElementById("myAudio").onclick 
    function setHalfVolume() {
      x.volume = 0.2;
    };
  ')
)

server <- function(input, output) {
  observeEvent(input$mybutton, {
    setHalfVolume()
  })

}

shinyApp(ui = ui, server = server)

Suo726
  • 35
  • 3
  • For future readers: here is a [follow up question](https://stackoverflow.com/questions/60665381/in-shiny-r-is-there-a-way-to-run-an-observeevent-right-after-an-observeevent-wi) – ismirsehregal Mar 13 '20 at 09:43

2 Answers2

1

You are very close to the goal, but you have some problems in get the correct ids.

To follow your path replace the script with:

document.getElementById("mybutton").onclick = 
    function setHalfVolume() {
        document.getElementById("myAudio").volume = 0.2;
    };

The onclick attribute of the button has to be changes not the attribute of the audio. And the audio DOM has the volume attribute to change.

One further approach would be to use the onclick attribute of the actionButton directly.

tags$script('
    decrease = function(){ document.getElementById("myAudio").volume = 0.2;}
')
tags$audio(id = "myAudio", controls = NA, autoplay = NA,     tags$source(src="sound.mp3")),
actionButton("lowerButton", "lower", onclick="decrease()")
thomas
  • 381
  • 2
  • 7
0

Thank you for the question and the answer. This has helped a lot. I have a follow-up: Is it possible to change the volume using a slider? Thus, it would be necessary to have an input variable to the script. Something like this (but doesnt seem to work):

tags$script('volumeChange = function(in){ document.getElementById("myAudio").volume = in;}'),
#calibration slider
sliderInput("levelSlider", "Level:",min = 0, max = 1, value = 0.3),
# calibrate level button
actionButton("playButton", "Play sound", onclick=paste0("volumeChange(","levelSlider$value",")")),
  • I'm not exactly sure how I would implement your code, but my audio element has a built in audio slider already when I open my app in a web browser like chrome. However, this doesn't appear if I simply run the app in RStudio. – Suo726 Mar 25 '20 at 00:00