1. 首页
  2. >
  3. 前端开发
  4. >
  5. HTML5

H5聊天video标签和视频文件下载那些怪事

最近在做一个即时聊天项目,用户要求除了可以发送图文,还要发送视频信息。刚开始觉得很简单呐,和普通文件下载不是一样?!谁知联调过程中就垮了,视频加载贼慢,根本无法观看。有的视频还没法加载,你知道的,前端直接裂了!!!

<video autoplay loop >     <source src="//localhost:8080/gesture.mp4" type="video/mp4"> </video>

原来是保存文件时,没有存储文件的content-type,读取的时候都默认成oct-stream文件下载了。但是一个2分钟的视频加载了半天,才能播放。肿么回事啊?

刚开始以为是nginx代理设置的响应时间短,没有缓存。一番搜索后,nginx有slice模块和proxy_cache模块,可以缓存后端文件到前端,而且可以按照大小区缓存。那就上吧!

#查看nginx是否已经有slice模块,这里我的nginx已经安装 nginx -V  #配置nginx.conf #配置缓存区路径,缓存区大小 proxy_cache_path /tmp/cache levels=1:2 keys_zone=cacheName:200m inactive=10m max_size=5g; location ^~ /im {        #打开proxy代理缓存       proxy_buffering on;       proxy_buffer_size 512k;       proxy_buffers 8 10M; 		  proxy_busy_buffers_size 20M;       #开启slice切割       slice 1m;#每个缓存大小       proxy_cache cacheName;#与keys_zone对应 		  proxy_cache_key    $host$uri$is_args$args$slice_range; 		  proxy_cache_valid 200 206 301 5m; 		  proxy_cache_use_stale updating error timeout invalid_header http_500 http_502 http_503 http_504; 		  proxy_cache_lock on; 		  proxy_cache_lock_timeout 0s; 		  proxy_cache_lock_age 200s; 		  expires 1m;##超时设置 		  proxy_set_header Range $slice_range; 	    .... }

配置之后,第一次访问还是比较慢,后续访问飕飕滴!但是用户体验太差了,继续优化!连我自己都交代不下去。怎么优化呢?没思路了,网上找了个视频网站,看人家咋加载的吧。

F12看看请求咋回事吧,不看不知道,一看吓一跳,返回码不是200吗!!!这206是个神马!!

请求和响应似乎多了点东西,而且一个视频会发起好多次请求!!

请原谅我的无知!

H5聊天video标签和视频文件下载那些怪事

General: Request Method: GET Status Code: 206   Request Headers: range: bytes=1901568-2559999  Response Headers: cache-control: max-age=10368000 Content-Length: 658432 Content-Range: bytes 1901568-2559999/4499732 content-type: video/mp4 date: Tue, 02 Feb 2021 15:06:20 GMT etag: "586fabca-44a914" expires: Wed, 02 Jun 2021 15:06:20 GMT last-modified: Fri, 06 Jan 2017 14:38:02 GMT

原来这Http状态码206是一种专门的响应码,表示服务端内容还没有传输结束,告诉客户端继续请求。原来H5中的video标签加载视频有一种原生的支持方式,而且video会自动判断服务端是不是支持这种服务,不支持就等待整个src加载完,支持就一部分一部分下载,byte serving,progressive download。w3c牛逼!

我的后端服务直接返回的是200和整个文件流,这个想想应该就是随机读取文件,只是这个读取范围是客户端发送过来的。通过增加请求头:range: bytes=1901568-2559999。服务端返回206,并增加一些关键字:文件大小,本次返回的字节范围,content-type等。

这有点断点下载的意思,而且用户可以拖动进度条,而且加载很快!这个方法简直不要不要的。

播放起来很流畅!!!

             response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT); 						out = new BufferedOutputStream(response.getOutputStream());             in = resource.getInputStream();             in.skip(pos);//跳过上次读取位置,直接读取本次内容             byte[] buffer = new byte[1024];             int length = 0;             while (sum < rangLength) {                 length = in.read(buffer, 0, ((rangLength - sum) <= buffer.length ? ((int) (rangLength - sum)) : buffer.length));                 sum = sum + length;                 out.write(buffer, 0, length);             }             out.flush();

但是这个播放还是不够流畅,有没有更好的解决方案了?!

发现还有一种点播方案,前端直接拉流,不过这要引入流媒体服务器了。这活越干越大了!