在 R 中提取托管音频文件的持续时间(无需下载文件)
Extract the duration of hosted audio files in R (without downloading the file)
我有一个托管音频文件列表,我想获取这些文件的持续时间,而无需自己下载文件。
我可以通过创建 html DOM element <audio>
and extracting the duration with the 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 的持续时间?
- 如何替换
src=
并迭代 mp3 列表?
- 如何写出持续时间,以便在
R
中进一步处理?
此答案仅适用于一个音频文件
要获取音频的持续时间并打印它,我们需要使用js
,shinyjs
中的一个环境如下:
定义 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)
感谢@NelsonGon 的回答,它解决了部分问题,我能够针对我的问题开发一个解决方案,该解决方案可以扩展并因此适用于多个 urls。它解决了以下问题:
- 它不会等待用户单击按钮,而是尝试每秒获取持续时间直到成功(因为下载元数据需要一段时间)
- 闪亮的应用程序被包装成一个函数,因此可以输入源的url
- 成功后返回时长值
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
我有一个托管音频文件列表,我想获取这些文件的持续时间,而无需自己下载文件。
我可以通过创建 html DOM element <audio>
and extracting the duration with the 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 的持续时间?
- 如何替换
src=
并迭代 mp3 列表? - 如何写出持续时间,以便在
R
中进一步处理?
此答案仅适用于一个音频文件
要获取音频的持续时间并打印它,我们需要使用js
,shinyjs
中的一个环境如下:
定义 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)
感谢@NelsonGon 的回答,它解决了部分问题,我能够针对我的问题开发一个解决方案,该解决方案可以扩展并因此适用于多个 urls。它解决了以下问题:
- 它不会等待用户单击按钮,而是尝试每秒获取持续时间直到成功(因为下载元数据需要一段时间)
- 闪亮的应用程序被包装成一个函数,因此可以输入源的url
- 成功后返回时长值
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