如何在Shiny中实现视频播放完成前禁用操作按钮
问题:Shiny应用中如何在音视频播放完成后启用操作按钮
我正在构建一个包含嵌入视频和音频文件的Shiny应用,设有用于向前导航的操作按钮,需要将这些按钮置灰禁用,直到嵌入的音视频播放完成。
对于需要用户输入的场景,我可以轻松使用shinyjs的启用/禁用/切换功能实现,但不知道如何处理嵌入文件的情况。我设想可以使用observeEvent,但不清楚需要监听什么事件——视频播放完成是否有唯一的隐藏ID?
以下是示例代码:
library(shiny) ui <- fluidPage( HTML('<iframe width="560" height="315" src="https://www.youtube.com/embed/Hrc1WrC8ihE" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>'), #无版权随机YouTube视频 br(), br(), actionButton("test", "test") #需在视频播放完成前禁用此按钮 ) server <- function(input, output, session) { } shinyApp(ui, server)
这可能可以用JavaScript解决,但我没有相关经验。
补充说明:为保证可复现性,示例中的视频嵌入方式与我实际代码不同。我实际嵌入的是已保存的MP4文件,而非YouTube链接。
解决方案
针对本地MP4视频的实现方式
因为你实际使用的是本地MP4文件,我们可以直接用HTML5的<video>标签替代iframe,这样就能监听视频的ended事件,再通过Shiny的JS通信机制通知R端启用按钮。
步骤1:修改UI部分
把原来的HTML()替换为带ID的<video>标签,同时初始禁用按钮:
library(shiny) library(shinyjs) ui <- fluidPage( useShinyjs(), # 加载shinyjs依赖 # 嵌入本地MP4视频,添加ID用于JS监听 tags$video( id = "local_video", width = "560", height = "315", controls = TRUE, # 显示播放控件 tags$source(src = "your_video.mp4", type = "video/mp4") # 替换为你的本地MP4文件路径 ), br(), br(), actionButton("test", "test", disabled = TRUE) # 初始状态禁用按钮 )
步骤2:添加JavaScript监听与R端响应
在server端通过runjs()添加事件监听代码,当视频播放结束时向R端发送信号,再通过observeEvent接收信号并启用按钮:
server <- function(input, output, session) { # 监听视频播放结束事件 runjs(' document.getElementById("local_video").addEventListener("ended", function() { Shiny.setInputValue("video_ended", true); // 向R端传递播放完成信号 }); ') # 接收信号后启用按钮 observeEvent(input$video_ended, { enable("test") }) } shinyApp(ui, server)
关键点说明
- HTML5的
<video>元素原生支持ended事件,视频播放完成时会自动触发 - 通过
Shiny.setInputValue()可以实现JavaScript与R端的双向通信 - 借助
shinyjs的enable()/disable()方法,能便捷控制按钮的启用/禁用状态
内容的提问来源于stack exchange,提问作者Casper
相关产品推荐
相关产品推荐

