如何将嵌入YouTube视频的本地VTT字幕同步显示在播放器外部?
实现嵌入YouTube视频与本地VTT字幕同步侧边显示
要把本地VTT字幕和嵌入的YouTube视频同步显示在侧边,方便用户复制,按以下步骤操作:
1. 解析VTT字幕为可处理的数据格式
先把VTT文本转换成JavaScript能识别的数组结构,每个元素包含字幕的开始时间、结束时间和内容:
// 解析VTT文本为字幕数组 function parseVTT(vttText) { const subs = []; const lines = vttText.split('\n').filter(line => line.trim() !== ''); let i = 0; // 跳过VTT开头标识行 while (i < lines.length && !lines[i].includes('-->')) { i++; } while (i < lines.length) { const timeLine = lines[i].trim(); const [startStr, endStr] = timeLine.split(' --> '); const text = lines[i+1].trim(); subs.push({ start: convertTimeToSeconds(startStr), end: convertTimeToSeconds(endStr), text: text }); i += 2; } return subs; } // 把VTT时间格式(mm:ss.sss)转换成秒数 function convertTimeToSeconds(timeStr) { const [minutes, rest] = timeStr.split(':'); const [seconds, milliseconds] = rest.split('.'); return parseInt(minutes) * 60 + parseInt(seconds) + parseInt(milliseconds) / 1000; }
2. 修改页面结构并启用YouTube API
要获取视频播放时间,必须使用YouTube IFrame API,修改iframe的URL并添加ID,同时给字幕显示区域加ID:
<div class="container"> <div class="row"> <div class="col-md-6"> <div class="thumbnail"> <div class="embed-responsive embed-responsive-4by3"> <!-- 启用API并添加播放器ID --> <iframe id="youtube-player" class="embed-responsive-item" src="<%= lugha.video %>?enablejsapi=1"></iframe> </div> <h4 class="title" style="font-weight: bold;"><%=lugha.title%></h4> </div> </div> <div class="col-md-6"> <div class="well well-lg"> <!-- 字幕显示容器 --> <div id="subtitle-display"></div> </div> </div> </div> </div>
3. 实现字幕与视频同步逻辑
初始化YouTube播放器,监听播放状态,实时更新显示对应字幕:
let subtitles = []; let player; // 替换为你的本地VTT内容,也可以通过文件上传读取 const vttContent = `WEBVTT - Some title 00:01.220 --> 00:03.100 You can't have my marriage. 00:03.680 --> 00:05.510 You can't have my daughter. 00:05.760 --> 00:07.575 And you sure can't have my man. 00:08.195 --> 00:10.425 This house is under new management. 00:10.715 --> 00:13.045 And that means you are out.`; // 解析字幕 subtitles = parseVTT(vttContent); // 初始化YouTube播放器 function onYouTubeIframeAPIReady() { player = new YT.Player('youtube-player', { events: { 'onStateChange': onPlayerStateChange } }); } // 视频播放时启动时间监听 function onPlayerStateChange(event) { if (event.data === YT.PlayerState.PLAYING) { setInterval(updateSubtitle, 100); // 每100ms更新一次字幕 } } // 更新当前显示的字幕 function updateSubtitle() { const currentTime = player.getCurrentTime(); const subtitleDisplay = document.getElementById('subtitle-display'); // 匹配当前时间对应的字幕 const currentSub = subtitles.find(sub => currentTime >= sub.start && currentTime <= sub.end); if (currentSub) { // 添加样式方便用户复制 subtitleDisplay.innerHTML = `<p style="font-size:1.2em; padding:10px; background:#f5f5f5; border-radius:5px;">${currentSub.text}</p>`; } else { subtitleDisplay.innerHTML = ''; } } // 动态引入YouTube IFrame API脚本 const tag = document.createElement('script'); tag.src = "https://www.youtube.com/iframe_api"; const firstScriptTag = document.getElementsByTagName('script')[0]; firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
4. 加载本地VTT文件(可选)
如果不想把VTT内容写死在代码里,可添加文件上传控件让用户选择本地文件:
<!-- 页面添加上传按钮 --> <input type="file" id="vtt-upload" accept=".vtt" style="margin:10px 0;">
// 监听文件上传事件 document.getElementById('vtt-upload').addEventListener('change', function(e) { const file = e.target.files[0]; if (file) { const reader = new FileReader(); reader.onload = function(event) { subtitles = parseVTT(event.target.result); alert('字幕加载完成'); }; reader.readAsText(file); } });
这样就能实现视频播放时侧边同步显示对应字幕,用户可直接复制文本使用。
内容的提问来源于stack exchange,提问作者Mata28
相关产品推荐
相关产品推荐

