当前位置: 首页 > wzjs >正文

深圳网站建设深圳网百度官方营销推广平台加载中

深圳网站建设深圳网,百度官方营销推广平台加载中,百度关键词优化和百度推广,临沂市兰山区建设局网站在前面的文章说,说明了服务端如何生成雪碧图/WebVTT,那如何在 Web 点播播放器上加载缩略图呢? 无论使用西瓜播放器,Video.js,Shaka Player,Plyr,DPlayer 等,以下方法都可以参考,有…

在前面的文章说,说明了服务端如何生成雪碧图/WebVTT,那如何在 Web 点播播放器上加载缩略图呢?

无论使用西瓜播放器,Video.js,Shaka Player,Plyr,DPlayer 等,以下方法都可以参考,有些播放器内置了支持雪碧图,有些播放器通过插件支持 WebVTT,但都无法达到我们想要的效果,那就…自己实现吧!

以下方案以 DPlayer 为例。

在视频元数据加载完成时,加载缩略图

initializeThumbnailPreview 用于初始化缩略图,有 4 个参数,分别是

  • webvtt 文件路径
  • 播放器的 video 标签
  • 父级容器( 可以对 div 设置 ref,通过 ref 获取 )
  • 错误回调
    // 播放器基础事件player.on('loadedmetadata', async () => {logger.info('🍒 视频元数据加载完成', {duration: player.video.duration.toFixed(2),videoWidth: player.video.videoWidth,videoHeight: player.video.videoHeight});// 初始化缩略图预览功能if (vttPath && player.video && container) {try {const thumbnailState = await initializeThumbnailPreview({vttPath,videoElement: player.video,videoContainer: container,onError});resolve(thumbnailState);} catch (error) {logger.error('🍒 缩略图预览初始化失败', error);resolve(null);}} else {resolve(null);}});

重点要关注的是 setupThumbnailPreviewupdateThumbnailContent 函数,简单来说做了以下几个步骤

  1. 计算鼠标在进度条上的位置
  2. 在该位置上方显示缩略图
  3. 在缩略图里面显示进度

那么如何确定显示雪碧图中的哪个 tile 呢?

遍历 webvtt 文件,找到对应播放时间的缩略图,缩略图的后缀有 #xywh,之前的文章中有提到这个用于定位。图片元素显示是固定的 160*90,通过设置像素的位置对小图定位显示。

/*** 初始化缩略图预览功能* 这是主要的导出函数,供外部组件调用*/
export const initializeThumbnailPreview = async (config: ThumbnailPreviewConfig): Promise<ThumbnailPreviewState> => {const { vttPath, videoElement, videoContainer, onError } = config;try {logger.info('🍒 开始初始化缩略图预览功能', {vttPath,videoElementReady: !!videoElement,containerReady: !!videoContainer});// 设置容器为相对定位videoContainer.style.position = 'relative';// 创建缩略图预览元素const { thumbnailElement, timeElement } = createThumbnailElements(videoContainer);// 加载 WebVTT 轨道await loadWebVTTTrack(vttPath, videoElement);// 设置缩略图预览功能await setupThumbnailPreview(videoElement, thumbnailElement, timeElement, videoContainer);// 创建清理函数const cleanup = () => {if (thumbnailElement && thumbnailElement.parentNode) {thumbnailElement.parentNode.removeChild(thumbnailElement);logger.info('🍒 缩略图预览元素已清理');}};logger.info('🍒 缩略图预览功能初始化完成');return {thumbnailElement,timeElement,cleanup};} catch (error) {const errorMessage = `缩略图预览功能初始化失败: ${error}`;logger.error('🍒 缩略图预览功能初始化失败', { error, vttPath });onError?.(errorMessage);throw error;}
};

loadWebVTTTrack 在 video 标签中添加 dom 元素,用于存储 webvtt 信息,方便后续读取与显示。

/*** 加载 WebVTT 缩略图轨道*/
const loadWebVTTTrack = async (vttUrl: string, videoElement: HTMLVideoElement): Promise<void> => {try {logger.info('🍒 开始加载 WebVTT 缩略图', { vttUrl });// 使用 fetch 加载 WebVTT 内容const response = await fetch(vttUrl, {mode: 'cors',credentials: 'omit'});if (!response.ok) {throw new Error(`HTTP ${response.status}: ${response.statusText}`);}const vttContent = await response.text();logger.info('🍒 WebVTT 内容加载成功', {size: vttContent.length,firstLine: vttContent.split('\n')[0]});// 创建 Blob URLconst blob = new Blob([vttContent], { type: 'text/vtt' });const blobUrl = URL.createObjectURL(blob);// 创建轨道元素const track = document.createElement('track');track.kind = 'metadata';track.label = 'thumbnails';track.default = true;track.src = blobUrl;// 添加轨道到视频元素videoElement.appendChild(track);// 监听轨道加载事件return new Promise((resolve, reject) => {track.addEventListener('load', () => {logger.info('🍒 WebVTT 轨道加载完成', { vttUrl });URL.revokeObjectURL(blobUrl);resolve();});track.addEventListener('error', (e) => {logger.error('🍒 WebVTT 轨道加载失败', { vttUrl, error: e });URL.revokeObjectURL(blobUrl);reject(new Error('WebVTT 轨道加载失败'));});});} catch (error) {logger.error('🍒 加载 WebVTT 失败', { vttUrl, error });throw error;}
};

setupThumbnailPreview 用于设置缩略图预览功能,主要是操作 dom 元素,修改 css 等。

为保证代码的完整性,我将在此处贴出完整函数,并通过注释的方式讲解内部设计。

/*** 设置缩略图预览功能(带重试机制)*/
const setupThumbnailPreview = (videoElement: HTMLVideoElement,thumbnailElement: HTMLDivElement,timeElement: HTMLDivElement,videoContainer: HTMLElement
): Promise<void> => {return new Promise((resolve, reject) => {const attemptSetup = (attempt: number = 1): void => {const progressBar = findProgressBar();if (progressBar) {setupProgressBarEvents(progressBar, videoElement, thumbnailElement, timeElement, videoContainer);logger.info('🍒 缩略图预览功能设置成功', { attempt });resolve();return;}if (attempt <= RETRY_CONFIG.maxAttempts) {const delay = attempt * RETRY_CONFIG.baseDelay;logger.info('🍒 进度条元素未找到,延迟重试', {attempt,delay,maxAttempts: RETRY_CONFIG.maxAttempts});setTimeout(() => {// 调试信息:打印当前 DOM 中的相关元素const debugInfo = {dplayerElements: Array.from(document.querySelectorAll('[class*="dplayer"]')).map(el => ({tagName: el.tagName,className: el.className,visible: (el as HTMLElement).offsetParent !== null})),barElements: Array.from(document.querySelectorAll('[class*="bar"]')).map(el => ({tagName: el.tagName,className: el.className,visible: (el as HTMLElement).offsetParent !== null}))};logger.info('🍒 DOM 调试信息', { attempt, ...debugInfo });attemptSetup(attempt + 1);}, delay);} else {const error = new Error(`已达到最大重试次数 ${RETRY_CONFIG.maxAttempts},缩略图功能无法正常工作`);logger.warn('🍒 缩略图功能设置失败', { maxAttempts: RETRY_CONFIG.maxAttempts });reject(error);}};attemptSetup();});
};

更新缩略图的内容

/*** 更新缩略图内容和位置*/
const updateThumbnailContent = (videoElement: HTMLVideoElement,thumbnailElement: HTMLDivElement,timeElement: HTMLDivElement,seekTime: number,thumbnailX: number
): void => {// 获取视频的文本轨道const tracks = videoElement.textTracks;if (!tracks || tracks.length === 0) {logger.warn('🍒 没有找到文本轨道', { tracksLength: tracks?.length });return;}const track = tracks[0];if (track.mode !== 'showing') {track.mode = 'showing';}if (!track.cues) {logger.warn('🍒 文本轨道没有 cues', {trackMode: track.mode,trackKind: track.kind});return;}// 查找当前时间对应的缩略图信息let activeCue = null;for (let i = 0; i < track.cues.length; i++) {const cue = track.cues[i];if (seekTime >= cue.startTime && seekTime <= cue.endTime) {activeCue = cue;break;}}if (!activeCue) {logger.warn('🍒 未找到对应时间的缩略图', { seekTime: seekTime.toFixed(2) });return;}// @ts-expect-error - VTTCue.text 包含缩略图信息const cueText = activeCue.text;// 解析 WebVTT 缩略图信息// 格式:image.jpg#xywh=160,90,160,90 或 url(image.jpg)let imageUrl = '';let xywh = '';if (cueText.includes('#xywh=')) {const parts = cueText.split('#xywh=');imageUrl = parts[0];xywh = parts[1];} else {const match = cueText.match(/url\(([^)]+)\)/);if (match) {imageUrl = match[1];} else {imageUrl = cueText.trim();}}if (!imageUrl) {logger.warn('🍒 无法解析缩略图URL', { cueText });return;}// 设置缩略图样式和位置if (xywh) {// 雪碧图模式:使用坐标信息const [x, y, w, h] = xywh.split(',').map(Number);thumbnailElement.style.backgroundImage = `url(${imageUrl})`;thumbnailElement.style.backgroundPosition = `-${x}px -${y}px`;thumbnailElement.style.backgroundSize = 'auto';thumbnailElement.style.width = `${w}px`;thumbnailElement.style.height = `${h}px`;logger.info('🍒 缩略图更新(雪碧图模式)', {seekTime: seekTime.toFixed(2),imageUrl: imageUrl.substring(imageUrl.lastIndexOf('/') + 1),spritePosition: `${x},${y}`,spriteSize: `${w}x${h}`,thumbnailX: thumbnailX.toFixed(1)});} else {// 单图模式thumbnailElement.style.backgroundImage = `url(${imageUrl})`;thumbnailElement.style.backgroundSize = 'cover';thumbnailElement.style.backgroundPosition = 'center';thumbnailElement.style.width = '160px';thumbnailElement.style.height = '90px';logger.info('🍒 缩略图更新(单图模式)', {seekTime: seekTime.toFixed(2),imageUrl: imageUrl.substring(imageUrl.lastIndexOf('/') + 1),thumbnailX: thumbnailX.toFixed(1)});}// 设置位置和时间thumbnailElement.style.left = `${thumbnailX}px`;timeElement.textContent = formatTime(seekTime);
};

希望你会喜欢 EasyDSS 点播模块

上面贴了很多代码,作为用户可以直接嵌入 iframe, 接入我们实现的播放器,开发者可以使用 EasyPlayer 。

点击查看 easydss 论坛

欢迎来到论坛一起讨论

http://www.dtcms.com/wzjs/19553.html

相关文章:

  • 网站搭建的策略与方法电商线上推广
  • 政府网站建设地方标准外贸营销型网站建设公司
  • asp如何做网站北京seo服务商
  • 平面图设计软件有哪些seo托管公司
  • nas 可以做网站吗潍坊seo网络推广
  • 建设网站纳什么税微信搜一搜怎么做推广
  • vr全景网站开发制作沧州网站优化
  • 网站开发长沙黄冈便宜的网站推广怎么做
  • 企业网站怎样做seo外包杭州
  • 做网站能改吗怎样在百度上注册自己的店铺
  • 做织梦网站的心得体会阿里云域名注册入口官网
  • 网站备案 通知青岛官网seo方法
  • 淮南网站优化seo点击软件哪个好用
  • 重庆交通大学官网网站营销推广公司
  • 新网站应该怎么做可以排名靠前百度指数官网查询入口
  • 自己做手机网站广州现在有什么病毒感染
  • 网站五合一建设广告推广平台赚取佣金
  • 专门教人做点心的网站小说搜索风云榜排名
  • 天津做网站找哪家公司好seo是怎么优化推广的
  • 企业网站托管哪家好百度客服系统
  • 做风控的网站网络营销的四个特点
  • 有哪些做任务网站广告投放网站平台
  • 政府网站wap门户建设方案什么是核心关键词
  • 360建筑网官网下载平台网站优化方法
  • 跟男友做网站百度大搜是什么
  • 专门做批发的网站客户引流推广方案
  • 网站建设谁家好深圳全网营销哪里好
  • 如何做视频解析网站seo推广优势
  • 重庆做网站的网站接广告
  • 两个公司的网站建设浙江seo