Skip to content

flower0wine/stream-video

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

1. 项目创建时间

项目于 2024年 01月 11日 创建。 耗时一到两个星期完成。

2. 项目说明

最初是想实现视频的流式传输, 但是浏览器的视频控件又十分的 low, 所以我就想弄一个自己的视频播放器, 当然也并不是那么好弄得, 我模仿的是哔哩哔哩的视频播放器 所以实现的方向基本是确定的。 实现了一些通用的效果, 以及将共同代码进行提取、封装, 提高代码的可维护性, 同时让代码更清晰易懂。 简单来说就是提升编程水平。

2.1. 后面添加的功能

  • 添加了视频帧预览(2024年 01月 18日)
  • 视频弹幕随视频时间展示(2024年 01月 22日)

3. 项目解释

3.1. 项目训练到的方面

下面的每个部分都可以单独写一张文章加以解释。

3.1.1. getBoundingClientRect().width 与 offsetWidth 的区别

3.1.2. offsetWidth、clientWidth、scrollWidth 的区别

3.1.3. 浏览器的渲染流程

3.1.4. 拖动进度条、以及分段进度条的实现

3.1.5. 移入图标渐现展示面板, 移出面板渐隐, 透明度不允许存在骤然变化

3.1.6. canvas 画出色板

3.1.7. 弹幕相关: 弹幕防碰撞, 弹幕速度, 字体样式, 弹幕位置, 弹幕过滤

3.2. 总结的技巧:

3.2.1. 如果在一个含有子元素的父元素上做拖动或者是点击事件, 要求只在父元素上触发

由于是拖动事件, 可以在父元素中加上一个 position: absolute 的元素, 设置其大小与父元素 大小相同, 以这个元素作为可拖动区域, 这样拖动事件就会简单很多, 因为如果不设置这么一个区域, 之后点击或者移动的 target 元素会发生变化, 十分的繁琐。

3.2.2. 属性的封装, 要求外部可以对内部指定的属性进行更改, 但是部分属性是只读的

如果你需要返回一个配置对象给外部, 外部可以修改这个配置对象的属性, 内部可以根据外部的更改 来对这个对象的属性来做相应的处理, 但是有些属性是只读的, 不能让外部修改, 这里我的思路如下:

  • 首先我从只读属性上来看, 认为可以使用 Object.defineProperties 来定义, 但是编写 过程中发现一个问题, 就是当设置了只读后, 内部也无法进行修改了, 这个属性是内部给外部 的一个标志, 内部可以修改, 但是外部不能修改, 但是使用 writable: false, 内部也不能 修改了, 所以这种方式不行。

  • 然后我想到另一个办法, 就是使用 Object.defineProperties 中的 setter 来限制修改, 但是又出现了一个问题, 就是 value, writable 与 setter, getter 不能一起使用, 导致这个属性就只是一个属性访问器, 它是不保存内容的, 虽然也可以再定义一个属性, 但是 我想了一下, 这样与未设置只读属性无异, 因为外部可以直接访问并修改这个属性, 绕过我们 定义的 setter, 所以这个办法也不行。

  • 最后我想到的是使用 Proxy, 为配置对象创建一个代理对象, 内部使用的是源对象, 可以做 任意的修改, 外部使用的是代理对象, 内部会对外部的访问和修改进行限制, 通过 Proxy 内部对源对象的修改外部能获取到, 外部对源对象的修改内部也能获取到, 不过没有设置 vue 的 那种响应式。

3.3. 遇到的问题:

3.3.1. 子元素的 transform 过渡的同时父元素透明度渐变过渡, 导致父元素无法过渡 (已解决)

我在制作元素的透明度渐变动画做好了之后, 在一个子元素上加了一个 transform 的过渡, 发现当鼠标在父元素进行透明度渐变过渡时快速移动到它的子元素上, 并触发了子元素的 transform 过渡, 父元素的透明度会突然变为 1, 导致父元素的透明度无法过渡。

解决方法我是找到了, 但是原因我倒是没发现, 向 ChatGPT 询问了一下原因以及解决方法, ChatGPT 给了我三个方法:

  • 在子元素上加上 will-change: transform;。
  • 或者是在子元素上加上 translate3d(0, 0, 0);。
  • 在子元素上使用动画帧 @keyframes。

试了一下只有第三种方式是管用的, ChatGPT 给出的原因可能是硬件加速的导致的, 应该使 子元素处于单独的图层, 由于前两种方式都没有效果, 所以原因我也不太确定, 不过使用 @keyframes 能解决问题。

3.3.2. 在 firebox 中 canvas 创建锥形渐变, 制作的颜色选择器颜色较暗 (未解决)

在 firebox 中使用 canvas 创建颜色选择器, 使用的是 CanvasRenderingContext2D.createConicGradient() 方法, 在 firebox 中制成的 色板颜色较暗, 在 edge 中测试为正常, 目前未发现其原因。

由于 firebox 有上述问题, 所以我使用 polyfill 来代替 firebox 浏览器原生的 API,

3.3.3. CanvasRenderingContext2D.createConicGradient 方法要求版本较高

CanvasRenderingContext2D.createConicGradient() 要求浏览器的版本较高, 目前我只在 Edge 版本 120.0.2210.91 (正式版本) (64 位) 中测试成功过, 在 FireBox 121.0.1 (64 位) 中虽然也测试成功, 但是颜色较暗. 在 Chrome 版本 97.0.4692.99(正式版本) (64 位)中未 测试成功, 需要至少 99 版本的 Chrome。

具体的 API 解释可以查看 MDN -- CanvasRenderingContext2D.createConicGradient

由于有些浏览器版本较低并不支持这个 API, 所以我选择使用 polyfill 来代替, 但是 polyfill 在视觉上有些灰色波纹, 使用起来是与原生的 API 无异的。

3.4. 当前未实现的功能

3.4.1. 弹幕未实现的功能

  • 非滚动弹幕防碰撞, 目前非滚动的弹幕发送时是会在同一位置的。
  • 弹幕的稀疏, 目前还不能控制弹幕稀疏程度, 虽然弹幕相隔距离已经设置了随机, 但是这个 随机不能控制。
  • 弹幕按照视频的播放时间来展示, 目前的弹幕都是在固定的时间展示的。
  • 弹幕的过滤, 当前弹幕还未实现弹幕的过滤功能。

3.4.2. 视频未实现的功能

  • 视频的清晰度切换。
  • 视频的流式传输, 有了这个功能就支持直播了。
  • 视频的字幕. video 标签有字幕轨道。

Releases

No releases published

Packages

No packages published