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

点播视频预览是怎么做到的?

image-20250607162712644

看进度条上的小窗口,你有没有想过,哔哩哔哩是如何在进度条上显示视频预览的? 这个功能非常有用,尤其是在播放长视频时。

如何才能实现?

实现这一点有三种方法。

  • 预先为视频生成 CSS sprites,并通过 API 获取
  • 预先为视频生成 WebVTT 文件,并通过 API 获取
  • 在播放器端实时取快照显示出来,这个过程需要客户端投入大量计算资源,在 web 浏览器中实时显示效果比前两者差,且略过。

CSS sprites

我们想象一个场景,进度条上每秒对应一个图片,那么就要将上百张甚至上千张图片打包,提供给客户端播放器,那要发出多少请求和消耗多少流量,不如将它们合并成一个文件发送,更节省内存和带宽。使用图片尺寸和位置信息来区分一张图片的各个 tile。

sprites,精灵图,也称为雪碧图,即一张图片由 n 个 tile 组合而成。

如下图所示,是一个 8*8 的矩阵,每个 tile 宽高是常见的 160*80,可以通过工具生成雪碧图。

image-20250607163254027

然后通过以下 css 来控制显示哪个,这会将 btn1 的元素背景图片的起点向左滑动 160px,将 btn2 的元素背景图片的起点向左滑动 320px,即分别显示第一行第二列 (1,2) 和第一行第三列 (1,3) 的图片。

.tool-btn {background: url(myfile.png)  top left no-repeat;display: inline-block;height: 80px;width: 160px;
}#btn1 {background-position: -160px 0px;
}#btn2 {background-position: -320px 0px;
}

WebVTT

Web 视频文本轨道 (WebVTT) 是提供特定文本 “提示” 的文本轨道。WebVTT API 主要用于显示与视频内容叠加的字幕,但它还有其他用途:提供章节信息以便于导航,以及提供需要与音频或视频内容时间对齐的通用元数据。

WebVTT 的 MIME 格式是 text/vtt

一个 WebVTT 文件(.vtt)包含一行或者多行的时间提示性内容(cue),如下所示:

WEBVTT00:00:00.000 --> 00:00:02.000
/vo4susu/sprites/sprite_01.webp#xywh=0,0,160,9000:00:02.000 --> 00:00:04.000
/vo4susu/sprites/sprite_01.webp#xywh=160,0,160,90

其组成结构

  • “WEBVTT” 固定关键词
  • 空白行,相当于两个连续的换行符
  • 任意数量的 cue

每个 cue 第一行以时间开始,表示字幕/缩略图显示的时间,如 00:00:00.000 --> 00:00:02.000 表示在视频前 2 秒都显示指定缩略图。

每个 cue 的第二行是缩略图的访问地址,如 /voolyab/sprites/sprite_01.webp#xywh=xywh=0,0,160,90 表示 /voolyab/sprites/sprite_01.webp 图片,xywh=xywh=0,0,160,90 是图片坐标信息

  • x 轴偏移 0px
  • y 轴偏移 0px
  • 宽 160
  • 高 90

即图片中的第一行第一列,在第二个 cue 中 xywh=160,0,160,90,即 x 轴偏移 160,偏移量第一个图片的宽度,跳过它即第一行第二列,以此类推。

生成雪碧图时,需要提供行列数和宽高。根据 xywh 四个参数,即可快速生成 webvtt。

EasyDSS 是怎么实现点播进度条预览的?

EasyDSS 采用 WEBVTT 的方案,提供进度条预览图。

如果你对具体实现很感兴趣,可以查看下一期文章了解更多。

点击查看 easydss 论坛

欢迎来到论坛一起讨论

参考

WebVTT API

Implementing image sprites in CSS

http://www.xdnf.cn/news/1359199.html

相关文章:

  • VsCode使用SFTP连接Linux
  • 使用 Golang 的 Gin 框架实现一周极限编程计划:全网 AIGC 项目热点追踪应用
  • MATLAB 与 Simulink 联合仿真:控制系统建模与动态性能优化
  • yggjs_rlayout框架v0.1.2使用教程 02 TechLayout 布局组件
  • 上科大解锁城市建模新视角!AerialGo:从航拍视角到地面漫步的3D城市重建
  • nginx部署goaccess监控
  • 【C语言强化训练16天】--从基础到进阶的蜕变之旅:Day12
  • leetcode 1493 删掉一个元素以后全为1的最长子数组
  • mybatis过渡到mybatis-plus过程中需要注意的地方
  • 《Distilling the Knowledge in a Neural Network》论文PDF分享, 2015 年,谷歌提出了 “知识蒸馏” 的概念
  • 06 - spring security角色和权限设置
  • vulnhub-billu_b0x靶机渗透
  • GPT-5国内免费体验
  • k8s下的网络通信之calico与调度
  • sqlite创建数据库,创建表,插入数据,查询数据的C++ demo
  • 最新sa-token的oauth2封装免密和密码登录
  • 【高等数学】第十章 重积分——第一节 二重积分的概念与性质
  • MinIO03-Linux安装
  • Docker安装RocketMQ
  • 征程 6X 常用工具介绍
  • AI大模型应用开发面试:深入解析技术点
  • 每日算法题【链表】:相交链表、环形链表、环形链表II
  • 鸿蒙中点击完成时延分析
  • LeetCode 42.接雨水
  • response对象的elapsed属性
  • Elasticsearch Ruby 客户端故障排查实战指南
  • Bright Data MCP:突破AI数据获取限制的革命性工具
  • 阿里云 OSS 前端直传实战:表单上传 + Policy 模式详解
  • GD32VW553-IOT 测评和vscode开发环境搭建
  • 硬件开发_基于物联网的宠物猫饲养系统