寻求方案,解决 WEB 端,循环播放固定的视频播放带来的大量的流量消耗问题。
问题产生:可视化大屏中有视频播放功能,每天会一直播放,消耗大量的流量。
需求:减少流量的消耗。
目前的方案:使用浏览器缓存,设置视频缓存过期时间。
有不有更好的方案?因为浏览器有缓存大小的限制,视频循环播放一轮之后,缓存会被清理。
![]() | 1 tomatocici2333 2023-12-18 13:48:41 +08:00 最简单的就是让视频读本地的。按照需求更新本地视频 |
![]() | 2 wangtian2020 2023-12-18 13:57:11 +08:00 最正确的方法是在资源的请求头上做设置 最保底的方法请求之后用 buffer 之类的变量存着 |
3 ntedshen 2023-12-18 13:59:12 +08:00 不刷新的话,直接 new 个 blob 丢内存里? |
![]() | 4 leyfung OP @wangtian2020 设置了缓存过期时间,但是浏览器对缓存大小有限制,要手动改浏览器配置,现在就是这么干的 |
5 qinjiang 2023-12-18 13:59:48 +08:00 首次加载使用远端视频,同时缓存到本地。读取本地是否存在视频文件,不要局限于浏览器本身,可以存放在磁盘里。 |
![]() | 6 leyfung OP @tomatocici2333 这样换了电脑就不行了 |
![]() |
![]() | 12 LancerComet 2023-12-18 14:04:30 +08:00 你可以使用 Cache API: ```html <html> <head></head> <body> <video id="some-video" width="400" cOntrols="controls"></video> <script> const makeCache = async () => { const cache = await window.caches.open('video-cache') const respOnse= await fetch('/some-video.mp4') await cache.put('video-data', response) } const loadFromCache = async () => { const cache = await window.caches.open('video-cache') return cache.match('video-data') } const main = async () => { let videoRespOnse= await loadFromCache() if (!videoResponse) { await makeCache() videoRespOnse= await loadFromCache() } const videoBlob = await videoResponse.blob() const url = window.URL.createObjectURL(videoBlob) const videoElement = document.getElementById('some-video') videoElement.src = url } main() </script> </body> </html> ``` 运行以上代码后,可以在开发者工具的 Application 里的 cache storage 中能看到被缓存的视频 |
![]() | 13 wangtian2020 2023-12-18 14:05:11 +08:00 我之前做大屏都是打包后 dist 文件塞进一个 webview apk 里,你先确定自己的看板运行在什么设备上。 普通的电视、安卓,可以自己打包成 apk ,然后你想干啥都行了。 |
![]() | 14 murmur 2023-12-18 14:08:04 +08:00 |
![]() | 15 leyfung OP @LancerComet 每个浏览器都硬性限制了一个域下缓存数据的大小,视频播放一轮就超过了浏览器的最大限制了。 |
16 drymonfidelia 2023-12-18 14:13:52 +08:00 ![]() 不该 electron 套壳的时候底下一堆人推荐 electron 这时候反而没人推荐了 |
17 lycpang 2023-12-18 14:14:19 +08:00 1. 压缩原始视频,做到最小不失真的效果 2. 视频分片,本地能缓存多少就缓存多少,缓存不了的用远端的 这样就从 100%流量消耗,变成了 10%。也不是也能优化 90%的流量问题么 |
![]() | 19 Cheons 2023-12-18 14:16:36 +08:00 via Android 预览选取界面用 gif 环视图 二级菜单再调用接口实时预览? 动效在 UI 动画上体现呗 |
![]() | 20 leyfung OP @tomatocici2333 还有个问题就是 浏览器好像是不让你直接读取本地文件的 |
![]() | 21 LancerComet 2023-12-18 14:17:07 +08:00 @leyfung 我认为您可以先试一下,这个不是默认的 http caching ,可以阅读一下文档: https://developer.mozilla.org/en-US/docs/Web/API/Cache |
![]() | 22 leyfung OP @LancerComet #21 好的 ,感谢,我测试一下吧,这个文档我也看了 |
![]() | 23 tool2d 2023-12-18 14:25:38 +08:00 超大文件不太适合用浏览器默认缓存。假设一个高清短视频 200M ,那么十几个要好几个 G 了, 最好就是本地启动一个 http web 代理服务器,有本地写入权限。 让 js 来访问本地服务器的视频,顺便把视频都缓存到用户磁盘上。 |
![]() | 24 leyfung OP 是个办法 |
![]() | 26 iosyyy 2023-12-18 14:41:00 +08:00 @drymonfidelia 你先搞清楚 electron 事干啥的好吗? 这 tm 是 web 端需要 electron 吗? |
![]() | 27 AllenCai 2023-12-18 14:41:14 +08:00 indexDB 试试 |
![]() | 28 tool2d 2023-12-18 14:41:26 +08:00 @jiangzm 有 API 的,只要用户点同意,就能读取了。 按照道理来说,JS 能访问本地系统文件并不安全,但是大屏应用无所谓的。 https://developer.chrome.com/docs/capabilities/web-apis/file-system-access |
29 drymonfidelia 2023-12-18 15:00:58 +08:00 @iosyyy 他不是说浏览器没权限吗 那就只能 electron 打包个客户端啊 |
![]() | 30 ZZITE 2023-12-18 15:03:28 +08:00 Service Worker 了解一下 简单的说可以代理你的请求,可以制定自己的缓存策略精细化管理缓存,可以把缓存的内容写到用户本地磁盘上 |
31 duke807 2023-12-18 15:04:21 +08:00 via Android 视频用 av1 压缩,大小直接变小很多,小于浏览器缓存大小的限制 |
34 jspatrick 2023-12-18 15:15:06 +08:00 你需要 indexedDB ,理论上浏览器所在盘有多大空间它就能吃多大,所以要记得清理过期数据 |
![]() | 35 MENGKE 2023-12-18 15:17:26 +08:00 循环播放就只加载一边就缓存了啊,为啥会消耗大量流量呢? |
37 Masoud2023 2023-12-18 15:20:38 +08:00 |
38 qinjiang 2023-12-18 15:20:48 +08:00 @leyfung 本地启 node 服务代理接口,读取本地文件传给 web ,或者使用新的浏览器 api 可以读取本地文件 |
39 Masoud2023 2023-12-18 15:21:22 +08:00 难道视频太大了这个会失效?我没试过,至少 youtube 我没遇到过这样的问题 |
41 ddch1997 2023-12-18 15:23:38 +08:00 赞同 30LService Worker 这个方案,这个方案出来是解决断网的情况下依旧能访问应用以及有最近的数据,缓存视频应该不是什么问题 |
![]() | 44 jazzg62 2023-12-18 15:48:08 +08:00 包装成 electron ,就能解决缓存限制 |
45 paopjian 2023-12-18 15:49:09 +08:00 压缩一下视频,是不是能降低一些大小 |
![]() | 46 iosyyy 2023-12-18 15:52:24 +08:00 |
47 wangmn 2023-12-18 15:58:00 +08:00 如果是 公开的把视频放流媒体平台 比如抖音 b 腾讯啥的,不是公开的 就放客户本地 |
![]() | 48 MENGKE 2023-12-18 16:02:25 +08:00 1. 压缩视频。 2. 切割视频。 3. 楼上给出过的 IndexedDB 等保存在本地。 这三种方法应该是相对你当前的项目改动最小的。 |
![]() | 49 luxferrew 2023-12-18 16:06:51 +08:00 资源又大,又要缓存,直接 indexDB ,挺方便的。 以前有个 web 项目要加载模型文件(接近 1G 了)就这么搞的 2333 。 如果还要省就考虑压缩视频、换 GIF 图等等...看你们领导需求了... |
![]() | 50 petergui 2023-12-18 16:07:02 +08:00 rsync + local_server |
51 ltmst 2023-12-18 16:20:40 +08:00 我倒是觉得可以写个服务放到大屏电脑上 就定时轮训服务器视频是否更新了,更新就下载到大屏服务器上 然后大屏 web 写逻辑直接获取本地视频 |
54 fengbjhqs 2023-12-18 16:30:43 +08:00 via Android 这个本地跑的服务,本地启动,浏览器打开本地地址, |
55 TsubasaHanekaw 2023-12-18 16:31:57 +08:00 那就不要用浏览器阿,最简单的 winform 套个 cerf 的壳都行 |
![]() | 56 leyfung OP 感谢大家的回复,下面是可以满足我需求的方案: 方案一:使用浏览器缓存,设置视频缓存过期时间;缺点是需要配置浏览器。 方案二:使用 IndexedDB 。 方案三:单独编写后端服务,后端读取在线文件后,将文件保存至本地,由前端页面请求本地后端服务获取文件。 方案四:Service Worker 。(查了一下,好像有大小限制,大屏上的视频加起来有五六百 M ) 接下来,试一下方案二。最后考虑方案三,或者就保持方案一。 |
![]() | 57 L1shen 2023-12-18 16:57:52 +08:00 Service Worker 的 cache 大小限制是跟着浏览器限制走的,一般来说可以很大 你可以通过 navigator.storage.estimate() 方法来查询可以用到多少,一般来说五六百 M 根本不是问题 |
![]() | 58 leyfung OP 找到了一个 DEMO ,有需要的可以参考 http://t.csdnimg.cn/kJqnn 实现图片本地化 ServiceWorker + IndexedDB |
59 xinghen57 2023-12-18 19:48:34 +08:00 via iPhone 本地搭个服务端可否? 视频换 vp9 等最新编码,体积能比 x.264 小一半。 |
![]() | 60 54xavier 2023-12-18 20:03:34 +08:00 @drymonfidelia #16 对啊,其实我觉得这搞个 electron 客户端不就好了吗?然后就可以 download 视频到磁盘,并且可以直接 读取磁盘文件,就可以用文件的方式来缓存视频了。 |
61 sub166 2023-12-18 20:04:16 +08:00 浏览器高版本的话可以试试 opfs |
![]() | 62 zeusho871 2023-12-18 20:11:12 +08:00 有的网站发现你视频在后台 它给你播放音频 不加载视频 等于他视频和音频是不同的流 |
![]() | 63 Tokin 2023-12-18 21:46:06 +08:00 多大的视频内容,试试存到 IndexDB ? |
64 kaneg 2023-12-18 21:53:43 +08:00 via iPhone 浏览器限制的是一个域名下的缓存大小,能不能切割成多个文件,分布在多个域名下,每个域名下不要超出限制,当然这个方案需要你能控制服务器的域名。 |
![]() | 65 dcdlove 2023-12-19 08:29:17 +08:00 浏览器缓存都没弄明白还说有大小限制,真是服了 |
![]() | 67 cherryas 2023-12-19 09:10:14 +08:00 多少年前就有的成熟方案,外接个硬件控制。你非要纯技术解决 |
68 vultr 2023-12-19 09:26:45 +08:00 你加个本地 cdn 服务器就好了,反正都用上大屏了,本地也应该有电脑的,配置个 cdn 就行了。 |
69 cijiugechu 2023-12-19 10:06:24 +08:00 把视频切成几块 Blob 或 ArrayBuffer 后存 IndexdDB 里,IndexedDB 几乎没有大小限制 |
![]() | 70 iosyyy 2023-12-19 10:10:16 +08:00 @54xavier 又刷到这个贴了 这么多人在这推荐什么 electron 是没做过项目吗..还是没上过班啊 这玩应是能随便改的? |
72 Huelse 2023-12-19 11:02:43 +08:00 ![]() 原生 video 标签和视频响应头中加 Cache-Control 不就可以了,还能有啥? |
73 |
![]() | 75 hongchends1 2023-12-19 11:15:44 +08:00 可以本地起个 server 或者 打包成应用 |
![]() | 76 suke119 2023-12-19 13:42:33 +08:00 推荐本地化磁盘文件的 api ,最差就纯内存那就 MEMFS+Wasm.. 1 个 G 视频绰绰有余,有单独的 memfs npm 包,不过我因为视频有其他操作直接用的 ffmpeg 的 ``` await ffmpeg.writeFile('input.mp4', inpf); //读取视频数据 let memfsData = ffmpeg.FS('readFile', 'suke.mp4'); //创建虚拟 URL this.transcodeUrl = URL.createObjectURL(new Blob([memfsData.buffer], { type: "video/mp4" })); ``` |
![]() | 77 leyfung OP |
![]() | 78 leyfung OP @leyfung #77 用的 yux-storage 是一个基于 HTML5 IndexedDB 封装的 Web 本地数据离线存储库。https://github.com/yued-fe/yux-storage 阅文前端团队开发的 |
79 uyoungco 2023-12-27 14:50:32 +08:00 前几天看了帖子没觉得什么,今天这也让我遇到了 感谢 op ,我学习了 |