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

Posted

技术标签:

【中文标题】在播放下一个声音之前在 javascript 中停止任何以前播放的声音(base64)的方法【英文标题】:Way to stop any previously playing sounds (base64) in javascript before playing next sound 【发布时间】:2022-01-02 04:49:08 【问题描述】:

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

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

任何帮助都会很棒!

【问题讨论】:

您需要将new Audio 实例存储在更高的范围内,以便您可以在其上调用stop(),例如在数组中的全局范围内 谢谢@PatrickEvans 你有建议的资源,我可以在哪里看到如何做到这一点? @PatrickEvans 你能提供更多指导吗?我已经研究了一些创建全局变量的方法,其中一些暗示仅使用 var 就可以创建一个全局变量。我也尝试使用“window.snd”,但也没有取得任何成果。 【参考方案1】:

“具体的js代码”***的重点不是别人给你写代码;这样你什么都学不到。这是为您指明正确的方向。但是哦哦

// 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 了解有关作用域工作原理的更多信息

【讨论】:

感谢您的回复。我已经尝试了几个小时寻找自己的解决方案,然后才首先提出我的问题,并在获得有关范围的初步回复之后。有没有办法做到这一点,但只能在函数内工作? - 即,在一个函数中设置一个仍然可以被其他函数引用的全局变量?问题是,使用我在这里使用的 R Shiny,您实际上不能只在 js 函数之外键入 javacript 代码。 例如,我尝试在不使用 'var' 的情况下定义变量,即使在函数中,这也应该使它成为全局变量,但是像 snd.pause() 或 snd.stop( ) 似乎仍然无法捕捉到声音并停止播放【参考方案2】:

使用 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();
  

然后两个声音函数如下,但您在“新音频”部分插入自己的 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() 似乎都不起作用。相反,制作一个单独的函数来停止声音,然后再运行新的声音。

【讨论】:

【参考方案3】:

我一直致力于 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)

【讨论】:

以上是关于在播放下一个声音之前在 javascript 中停止任何以前播放的声音(base64)的方法的主要内容,如果未能解决你的问题,请参考以下文章

在 JavaScript \ jQuery 上播放游戏声音

在 JavaScript 中播放一段声音时如何获取回调?

使用 Javascript 在 iPhone 网络应用程序中播放声音?

等到声音结束才能使用网页

在播放另一个声音之前停止一个声音

在javascript中同时播放多个声音