在播放下一个声音之前停止 javascript 中任何先前播放的声音(base64)的方法

Way to stop any previously playing sounds (base64) in javascript before playing next sound

我有一个 javascript 函数可以播放来自 base64 纯文本的特定声音。我认为我正在寻找的东西很简单,但我对 js 一点也不熟悉,因为我实际上是在 R 中使用 js 作为闪亮应用程序的一部分。我只是在寻找一种方法,当这个函数被调用时,它会取消任何以前播放的来自可能已经播放的相同或类似函数的声音:

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

任何帮助都会很棒!

“具体的js代码”Whosebug的重点不是让别人给你写代码;这样你什么也学不到。这是给你指明正确的方向。但是ooook

// Store your Audio in some higher scope: outside of the function
var snd = new Audio();

shinyjs.soundmaker = function() {
  // call snd.stop(); and reassign snd every time you want to play audio
  snd.stop();
  snd = new Audio("data:audio/wav;base64,blablablabla");
  snd.play();
}

阅读 this 了解有关作用域如何工作的更多信息

使用 js 和 R Shiny 解决此问题的方法是创建一个单独的 js 函数来停止播放声音。然后,每次你想开始一个新的声音时,你首先还要调用声音停止函数 - 因此,任何以前播放的声音都会在新声音开始之前停止。

library(shiny)
library(shinyjs)

ui <- fluidPage(

    useShinyjs(),
    
    extendShinyjs(script = "marbles.js", functions = c("marbles")),
    extendShinyjs(script = "birds.js", functions = c("birds")),
    extendShinyjs(script = "stopper.js", functions = c("stopper")),
    
    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)

声音停止功能很简单:

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

那么这两个声音函数将是下面的,但是你在'new audio'部分插入了你自己的base64纯文本(将wav转换为base64,参见例如:https://base64.guru/converter/encode/audio/wav)。所有 javascript 函数都应作为 js 文件保存在名为 'www' 的文件夹中,该文件夹与您的应用位于同一工作目录中:

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();
}

简而言之,无论出于何种原因,在开始播放新声音的函数的开头调用 sound.pause() 似乎都行不通。相反,制作一个单独的函数来停止声音,然后 运行 之后的新声音。

我一直在研究 {howler}(目前仅在 GitHub 上可用),这是 howler.js 音频库的包装器。它可以处理 base64 声音,并通过 stopHowl.

停止播放服务器端的声音

这是一个例子;单击播放按钮时,声音将播放 0.5 秒,然后再次停止:

library(shiny)
library(howler)

ui <- fluidPage(
  title = "howler Base64 Example",
  useHowlerJS(),

  h3("howler Base64 Example"),
  howlerPlayer("sound", "data:audio/wav;base64,blablablabla"),
  howlerPlayButton("sound")
)

server <- function(input, output, session) {
  observeEvent(input$sound_play, {
    playHowl(session, "sound")
    Sys.sleep(0.5)
    stopHowl(session, "sound")
  })
}

shinyApp(ui, server)