当前位置:网络安全 > 关于视频播放的新探索

关于视频播放的新探索

  • 发布:2023-09-29 14:37

-->

前端同学如果想使用HTML5播放视频,必然会用到video标签。然而,大多数学生只使用更简单的函数。事实上,它具有我们需要发现的非凡力量。

首先我们来看看视频最基本的用法:

  • 使用 src 属性

  • 使用源标签

这是 MDN 给出的有关视频的基本用例。这里我们简单介绍一下两种方法的区别。 src只能给视频一个播放地址。当浏览器不支持该视频格式的解码时,就会出现错误,导致视频无法播放。为了解决这个问题,使用了source标签。使用多个源标签来介绍不同格式的视频。他们从上到下解析,直到遇到上面的代码。当浏览器不支持ogg格式时,浏览器会自动播放www.sychzs.cn4。

实用技巧

我们会发现使用video:src属性播放视频时经常会出现播放失败的情况。我们可以做些什么来提高视频播放的质量?

这种情况一般采用CDN。为了更加安全,不同的CDN厂商一般分为主用CDN和备用CDN。那么问题来了,我们如何利用视频本身的特点,与CDN结合起来,保证我们视频播放的质量呢?

不难看出,source标签不仅支持不同视频格式的自动切换,还适用于同一视频格式切换失败的情况,即由于网络问题无法获取www.sychzs.cn4时,浏览器将自动切换到www.sychzs.cn4。

进阶技能

如果你浏览视频,你会发现很多网站上的视频都是这样的:

如果直接访问blob,你会发现这个地址不存在。

这个地址就是映射Blob对象的DOMString。事实上,视频属性src支持Blob,但新标准是使用srcObject属性来代替这个功能。目前的代码可以这样写:

const mediaSource = new MediaSource();
const video = document.createElement('video');
尝试一下{
video.srcObject = mediaSource;
} catch(错误){
video.src = URL.createObjectURL(mediaSource);
}

这段代码中除了Blob对象之外,还有一个MediaSource对象。赋予视频非凡力量的主要因素是浏览器对MediaSource对象的支持,这使得JavaScript有更大的空间来操作视频。如何使用MediaSource本文不做介绍。你可以自己检查一下。我们要讲的是视频与MediaSource结合可以做什么?

清晰度无缝切换

在点播领域,mp4是最常见、兼容性最好的视频容器。然而,mp4也有其局限性,例如通用清晰度切换。我们无法实现像YouTube那样的无缝切换。我们可以看一下普通mp4播放的网络请求和youtube视频播放的网络请求的区别。

图1.1普通mp4的下载请求流程

图1.2 Youtube视频下载请求流程

从这两张图就不难看出。默认情况下,mp4 使用 http 一次请求所有视频数据,而 Youtube 则多次请求。当然,这样的描述很不专业,但确实很生动。造成这种差异的原因是视频不支持流视频数据。 Youtube 使用流媒体视频容器 webm,而 mp4 是非流媒体。如何把流媒体视频数据解释清楚?从专业的角度来说,很难用三言两语解释清楚,但用白话翻译,流式视频数据支持分段独立播放,非流式则不行。也就是说,对于10M的视频文件,流媒体视频可以请求单独播放0~1M的数据,而非流媒体视频则不能。

我们在上面描述了不同的视频格式。接下来我们要说的是,第一张图片中的视频加载是由浏览器控制的。通过将视频地址配置到视频的src属性中,触发播放后浏览器就会启动。一旦下载,JS就无法干预。 Youtube视频加载是通过JS控制的。可以再看第二张图的网络请求类型:xhr,足以证明这一点。

明确了以上两点之后,我们就该谈谈分辨率切换了。这个需求大家都很熟悉,但是直接使用mp4格式无缝切换分辨率是相当困难的。我们先解释一下“无缝清晰度切换”的概念:在不停止画面和声音的情况下,从播放一种分辨率的视频到另一种分辨率的平滑切换过程。了解了这个概念之后,大家应该知道用视频无缝切换到mp4是多么困难的事情了。一方面,视频不支持流视频格式。另一方面,视频的加载不是由JS控制的。通过切换视频的src属性,必然会导致屏幕中断、重新请求视频数据等,有的同学想到了使用两个视频结合z-index,但是当你生成另一个视频来加载该视频时,出现了不保证两张图片严格一致。即使将原始图片暂停到某个时刻,使用另一个视频将其与currentTime属性同步,切换时仍然会看到屏幕闪烁,这基本上无法与Youtube的无缝切换体验竞争。也会造成更多的流量浪费。至于背后的原因,可以研究一下mp4容器和webm容器的异同,也可以阅读视频解码相关的文章。

还有一种方法是将所有mp4格式转码为hls、webm等流媒体视频格式。然而,这种看似可行的方法实际上会带来很大的成本开销。比如转码大量视频会消耗很高的机器资源,存储成本成倍增加,CDN成本成倍增加等等。其实正是在这样的背景下,我们开发了新的技术问题来解决清晰度的无缝切换。

首先我们改变了mp4视频的播放流程,不再直接使用视频的src来播放,因为我们没有任何空间可以操作。 Video不仅支持src属性,还支持Blob对象,我们使用后者。播放过程如下:

  • 请求mp4视频数据,可以与视频Range服务结合,实现精准加载。
  • 编写一个解析器来解复用加载的mp4视频数据
  • 将解复用的视频数据转换为fmp4格式并传递给MediaSource
  • 使用视频解码并完成播放

那么切换分辨率时,流程如下:

  • 请求mp4视频数据,可以与视频Range服务结合,实现精准加载。
  • 编写一个解析器来解复用加载的mp4视频数据
  • 将解复用的视频数据转换为fmp4格式并传递给MediaSource
  • 使用视频解码并完成播放

    那么切换分辨率时,流程如下:

    这个过程看似复杂,但所有操作都是在浏览器端完成的,也就是说都是由JS实现的。这样,之前提到的所有成本问题都不存在,并且可以实现相同YouTube体验的无缝切换。如果你也想使用这个功能而不需要自己实现上述过程,可以使用下面的代码:

    从“xgplayer”导入播放器;
    导入“xgplayer-mp4”; 让玩家=新玩家({
    el:document.querySelector('#mse'),
    url: [{src:'/mp4/',type:"video/mp4"},{src:'/mp5/',type:'video/mp4'}]
    }); player.emit('resourceReady', [{name: 'HD', url: '/mp4/',cname:'HD'}, {name: 'UHD', url: '/mp5/',cname:' Ultra高清'}]);

如果你对这段代码有任何疑问或者想了解更多它是如何实现的,可以参考文档或者Github。

保存视频数据

我们一般都是用video来直接加载视频,大概是这样的:

随机找到一个视频。视频总长度为02:08。当播放到 00:05 时,浏览器已将其下载到 01:30。如果用户停止观看,下载的视频就会显得浪费了。当然,不断的寻找也会造成大量的流量浪费。根据我们之前的统计,在短视频领域,用户查找的频率为80%,所以这部分流量是可以节省的。具体原则如下:

  • 设置每次负载的数据包大小
  • 设置预载持续时间
  • 打开加载队列,完成第一个数据包下载,判断缓冲时间和预加载时间是否满足。如果没有,请求下一个数据包

具体实现代码如下:

从'xgplayer'导入播放器;
导入'xgplayer-mp4';
const 玩家 = 新玩家({
id:'vs',
url:'//www.sychzs.cn/a/mp4',
预加载时间:10
});

这样在视频播放过程中始终只会预加载10秒的数据,从而保证流量的节省。

所有代码来自西瓜播放器,有解析器,可以节省流量,Github

本文转载于:视频播放新探索

-->

相关文章

最新资讯

热门推荐