【问题标题】:Extract the duration of hosted audio files in R (without downloading the file)提取R中托管音频文件的持续时间(不下载文件)
【发布时间】:2022-01-01 21:49:55
【问题描述】:

我有一个托管音频文件的列表,我想获得其持续时间,而无需自己下载文件。

我可以通过创建html DOM element <audio> 并使用duration attribute 提取持续时间来做到这一点。这在以下 Shinyapp 中效果很好:单击“单击我”按钮时,持续时间会在警报中返回。

shinyApp(
  ui = fluidPage(
    useShinyjs(), 
    actionButton("btn", "Click me"),
    tags$audio(id = "myaudio", 
               src = "https://download.samplelib.com/mp3/sample-3s.mp3",
               type = "audio/mp3", autoplay = NA, controls = NA)
  ),
  server = function(input, output) {
    observeEvent(input$btn, {
      runjs("alert(myaudio.duration);")
    })
  }
)

这是我卡住的地方:如何利用这种方法提取多个 (> 1'000) mp3 的持续时间?

  1. 如何替换 src= 并迭代 mp3 列表?
  2. 如何写出持续时间,以便在R 中进一步处理?

【问题讨论】:

    标签: javascript r shiny shinyjs


    【解决方案1】:

    此答案仅适用于一个音频文件

    要获取音频的时长并打印出来,我们需要使用jsshinyjs中的环境如下:

    get_duration 定义为我们的JS,并通过Shiny.onInputChange 指定输入更改时会发生什么。在这里,我还使用了reactiveValues 来存储更改的持续时间。

    library(shinyjs)
    library(shiny)
    
    get_duration <- 'shinyjs.aud_duration = function(params) {
      var duration = myaudio.duration;
      Shiny.onInputChange("aud_duration", duration);
    }' 
    
    ui <- fluidPage(
        useShinyjs(), 
        extendShinyjs(text = get_duration, functions = "aud_duration"),
        actionButton("btn", "Click me"),
        tags$audio(id = "myaudio", 
                   src = "https://download.samplelib.com/mp3/sample-3s.mp3",
                   type = "audio/mp3", autoplay = NA, controls = NA),
        verbatimTextOutput("aud_duration")
      )
    
    server <- function(input, output) {
      js$aud_duration()
      durations <- reactiveValues(duration = NA)
     
     observeEvent(input$btn,
                  durations$duration <- input$aud_duration
                   
             
     )
      output$aud_duration <- renderText(durations$duration)
    }
    
    shinyApp(ui, server)
    

    【讨论】:

    • 感谢您的意见!我能够将这个想法扩展到处理多个文件(请参阅我的答案)。您知道为什么我的方法适用于我最初提供的示例文件,但不适用于其他文件吗?
    • 这有点难以判断,因为由于某种原因,我无法在网络浏览器中浏览此页面。您是否有指向它的链接(所有这些文件都存在的地方)?它可能只是不存在@Ratnanil
    • 我会进一步研究这个,但似乎这可能与一些尚未加载的元数据有关,因此您可能需要在 aud_duration 函数中为此添加一个处理程序。 @Ratnanil
    【解决方案2】:

    感谢@NelsonGon 的回答,它解决了部分问题,我能够为我的问题开发一个解决方案,该解决方案可以扩展并适用于多个网址。它解决了以下问题:

    1. 它不会等待用户单击按钮,而是尝试每秒获取持续时间,直到成功(因为下载元数据需要一段时间)
    2. 闪亮的应用被包装成一个函数,这样就可以输入源的url了
    3. 成功后返回持续时间值
    get_duration <- function(src){
      library(shinyjs)
      library(shiny)
      
      get_duration <- 'shinyjs.aud_duration = function(params) {
      var duration = myaudio.duration;
      Shiny.onInputChange("aud_duration", duration);
    }' 
      
      ui <- fluidPage(
        useShinyjs(), 
        extendShinyjs(text = get_duration, functions = "aud_duration"),
        tags$audio(id = "myaudio", 
                   src = src),
      )
      
      server <- function(input, output) {
        js$aud_duration()
        durations <- reactiveValues(duration = NA)
        
        observe({
          invalidateLater(1000)
         
          if(!is.null(isolate(input$aud_duration))){
            stopApp(input$aud_duration)
          }
        })
      }
      
      shiny::runGadget(ui, server)
    }
    

    运行如下:

    get_duration("https://download.samplelib.com/mp3/sample-3s.mp3")
    [1] 3.239184
    
    

    【讨论】:

      猜你喜欢
      • 2013-03-01
      • 2014-02-08
      • 2010-11-17
      • 2020-06-02
      • 1970-01-01
      • 2015-07-25
      • 1970-01-01
      • 1970-01-01
      • 2019-03-18
      相关资源
      最近更新 更多