R Shiny页面切换媒体无法停止:HTML5音视频播放/暂停方案问询
解决Shiny中shiny.router页面切换时音视频持续播放的问题
场景1:页面切换时自动暂停所有媒体
由于shiny.router通过隐藏/显示DOM元素实现页面切换,我们可以监听路由变化或页面容器的状态变更,触发媒体暂停操作。
实现方案
通过监听路由的hashchange事件(shiny.router切换页面时会更新URL哈希),遍历所有音视频元素并暂停正在播放的内容:
library(shiny) library(shiny.router) library(shinyjs) ui <- fluidPage( useShinyjs(), tags$script(HTML(" $(window).on('hashchange', function() { // 暂停所有处于播放状态的音视频 $('audio, video').each(function() { if (!this.paused) { this.pause(); } }); }); ")), router_ui( route("/", div(h3("首页"))), route("/media", div( tags$audio(src = "audio1.mp3", controls = TRUE), tags$video(src = "video1.mp4", controls = TRUE, width = "400") )) ) ) server <- function(input, output, session) { router_server() } shinyApp(ui, server)
如果哈希事件不生效,可改用MutationObserver监听页面容器的显示状态(假设页面容器统一使用.page-container类):
$(document).ready(function() { const observer = new MutationObserver(mutations => { mutations.forEach(mutation => { if (mutation.attributeName === 'style') { const $container = $(mutation.target); if ($container.css('display') === 'none') { $container.find('audio, video').each(function() { !this.paused && this.pause(); }); } } }); }); $('.page-container').each(function() { observer.observe(this, { attributes: true }); }); });
场景2:点击新媒体播放时自动暂停其他媒体
保留原生控件的前提下,通过监听音视频的play事件,实现“播放新内容时自动暂停其他媒体”的逻辑:
tags$script(HTML(" $(document).on('play', 'audio, video', function() { const currentMedia = this; // 暂停当前媒体以外的所有播放中内容 $('audio, video').not(currentMedia).each(function() { !this.paused && this.pause(); }); }); "))
这段代码利用事件委托,对动态生成的音视频元素也能生效——只要有媒体开始播放,就会遍历其他所有媒体并暂停正在播放的项。
额外适配:折叠面板内的媒体
如果媒体放在折叠面板中,可结合面板的收起事件暂停媒体(以Bootstrap折叠面板为例):
$(document).on('hidden.bs.collapse', '.collapse', function() { $(this).find('audio, video').each(function() { !this.paused && this.pause(); }); });
内容的提问来源于stack exchange,提问作者user22460492
相关产品推荐
相关产品推荐

