如何在Reveal.js中实现多视频同步播放与切换显示?
Reveal.js 多视频同步播放实现方案
一、同一幻灯片的前景/背景视频同步控制
实现同一幻灯片加载时前景、背景视频同时启动,切换幻灯片后隐藏前景视频、保留背景视频播放的效果。
1. 幻灯片结构定义
在目标幻灯片中同时配置背景视频和前景视频,通过ID标记前景视频方便后续控制:
<section data-background-video="background.mp4" data-background-video-loop data-background-video-muted> <video id="foreground-video" src="foreground.mp4" muted></video> </section> <section> <!-- 下一张幻灯片内容 --> </section>
给前景视频添加样式,让它覆盖在幻灯片上层:
#foreground-video { position: absolute; top: 0; left: 0; width: 100%; height: 100%; object-fit: cover; }
2. 同步控制逻辑
利用Reveal.js的事件监听,实现视频同步启动和前景视频的隐藏:
let bgVideo, fgVideo; // 幻灯片加载完成后,获取视频实例并同步播放 Reveal.on('ready', () => { const currentSlide = Reveal.getCurrentSlide(); // 获取背景视频实例(Reveal会把背景视频挂载到幻灯片的父容器) bgVideo = currentSlide.parentElement.querySelector('video'); fgVideo = currentSlide.querySelector('#foreground-video'); if (bgVideo && fgVideo) { // 用Promise.all确保两个视频同时启动 Promise.all([bgVideo.play(), fgVideo.play()]).catch(err => console.error('视频播放失败:', err)); } }); // 切换幻灯片时隐藏前景视频,背景视频默认继续播放 Reveal.on('slidechanged', event => { const prevFgVideo = event.previousSlide?.querySelector('#foreground-video'); if (prevFgVideo) { prevFgVideo.style.display = 'none'; } });
二、跨幻灯片的视频进度同步
实现第一张幻灯片的展示时长,作为第二张幻灯片视频的起始播放位置。
1. 幻灯片结构定义
给计时用的第一张幻灯片添加ID标记,第二张幻灯片的视频也添加ID:
<section id="timer-slide"> <!-- 第一张幻灯片内容 --> </section> <section> <video id="sync-video" src="target-video.mp4" muted controls></video> </section>
如果第二张用背景视频,结构如下:
<section id="timer-slide"> <!-- 第一张幻灯片内容 --> </section> <section data-background-video="target-video.mp4" data-background-video-muted> <!-- 第二张幻灯片内容 --> </section>
2. 进度同步逻辑
通过监听幻灯片的进入/离开事件,计算停留时长并设置视频起始位置:
let slideEnterTime; let stayDuration = 0; // 进入第一张幻灯片时记录时间 Reveal.on('slidein', event => { if (event.currentSlide.id === 'timer-slide') { slideEnterTime = Date.now(); } }); // 离开第一张幻灯片时计算停留时长 Reveal.on('slideout', event => { if (event.currentSlide.id === 'timer-slide') { stayDuration = (Date.now() - slideEnterTime) / 1000; } }); // 进入第二张幻灯片时设置视频起始进度 Reveal.on('slidein', event => { // 处理普通视频 const syncVideo = event.currentSlide.querySelector('#sync-video'); if (syncVideo && stayDuration > 0) { syncVideo.currentTime = stayDuration; syncVideo.play().catch(err => console.error('视频播放失败:', err)); } // 处理背景视频 const bgVideo = event.currentSlide.parentElement.querySelector('video'); if (bgVideo && stayDuration > 0) { bgVideo.currentTime = stayDuration; bgVideo.play().catch(err => console.error('视频播放失败:', err)); } });
内容的提问来源于stack exchange,提问作者WakanaYuki
相关产品推荐
相关产品推荐

