V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
leyfung
V2EX  ›  程序员

寻求方案,解决 WEB 端,循环播放固定的视频播放带来的大量的流量消耗问题。

  •  
  •   leyfung · 350 天前 · 7633 次点击
    这是一个创建于 350 天前的主题,其中的信息可能已经有所发展或是发生改变。

    寻求方案,解决 WEB 端,循环播放固定的视频播放带来的大量的流量消耗问题。

    问题产生:可视化大屏中有视频播放功能,每天会一直播放,消耗大量的流量。

    需求:减少流量的消耗。

    目前的方案:使用浏览器缓存,设置视频缓存过期时间。

    有不有更好的方案?因为浏览器有缓存大小的限制,视频循环播放一轮之后,缓存会被清理。

    79 条回复    2023-12-27 14:50:32 +08:00
    tomatocici2333
        1
    tomatocici2333  
       350 天前
    最简单的就是让视频读本地的。按照需求更新本地视频
    wangtian2020
        2
    wangtian2020  
       350 天前
    最正确的方法是在资源的请求头上做设置
    最保底的方法请求之后用 buffer 之类的变量存着
    ntedshen
        3
    ntedshen  
       350 天前
    不刷新的话,直接 new 个 blob 丢内存里?
    leyfung
        4
    leyfung  
    OP
       350 天前
    @wangtian2020 设置了缓存过期时间,但是浏览器对缓存大小有限制,要手动改浏览器配置,现在就是这么干的
    qinjiang
        5
    qinjiang  
       350 天前
    首次加载使用远端视频,同时缓存到本地。读取本地是否存在视频文件,不要局限于浏览器本身,可以存放在磁盘里。
    leyfung
        6
    leyfung  
    OP
       350 天前
    @tomatocici2333 这样换了电脑就不行了
    murmur
        7
    murmur  
       350 天前
    大屏不一般是本地部署么,直接弄一个电脑接上去想干啥干啥
    leyfung
        8
    leyfung  
    OP
       350 天前
    @qinjiang JS 不能直接读取本地文件
    murmur
        9
    murmur  
       350 天前
    @leyfung 思路狭窄了,大屏比电脑贵多了,那种只能跑一个程序的小电脑想做多便宜多便宜,120gssd 还不够缓存视频的么
    leyfung
        10
    leyfung  
    OP
       350 天前
    @murmur 大屏不止一个地方用,所以不是本地
    leyfung
        11
    leyfung  
    OP
       350 天前
    @murmur #9 目前就是用的缓存方案,领导觉得不好,需要用户配置浏览器
    LancerComet
        12
    LancerComet  
       350 天前
    你可以使用 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 中能看到被缓存的视频
    wangtian2020
        13
    wangtian2020  
       350 天前
    我之前做大屏都是打包后 dist 文件塞进一个 webview apk 里,你先确定自己的看板运行在什么设备上。
    普通的电视、安卓,可以自己打包成 apk ,然后你想干啥都行了。
    murmur
        14
    murmur  
       350 天前
    @leyfung 那就是我思路狭隘了,如果中间是动画或者企业宣传 logo 本地缓存就可以了,甚至可以把中间改成 gif 或者 css 动画来规避流量

    如果是生产实时监控那就只能让流量跑着
    leyfung
        15
    leyfung  
    OP
       350 天前
    @LancerComet 每个浏览器都硬性限制了一个域下缓存数据的大小,视频播放一轮就超过了浏览器的最大限制了。
    drymonfidelia
        16
    drymonfidelia  
       350 天前   ❤️ 2
    不该 electron 套壳的时候底下一堆人推荐 electron 这时候反而没人推荐了
    lycpang
        17
    lycpang  
       350 天前
    1. 压缩原始视频,做到最小不失真的效果
    2. 视频分片,本地能缓存多少就缓存多少,缓存不了的用远端的

    这样就从 100%流量消耗,变成了 10%。也不是也能优化 90%的流量问题么
    leyfung
        18
    leyfung  
    OP
       350 天前
    @murmur #14 也不是实时吧,就是放了十几个的短视频,视频是在线的。定时会更换一批视频。
    Cheons
        19
    Cheons  
       350 天前 via Android
    预览选取界面用 gif 环视图
    二级菜单再调用接口实时预览?

    动效在 UI 动画上体现呗
    leyfung
        20
    leyfung  
    OP
       350 天前
    @tomatocici2333 还有个问题就是 浏览器好像是不让你直接读取本地文件的
    LancerComet
        21
    LancerComet  
       350 天前
    @leyfung 我认为您可以先试一下,这个不是默认的 http caching ,可以阅读一下文档: https://developer.mozilla.org/en-US/docs/Web/API/Cache
    leyfung
        22
    leyfung  
    OP
       350 天前
    @LancerComet #21 好的 ,感谢,我测试一下吧,这个文档我也看了
    tool2d
        23
    tool2d  
       350 天前
    超大文件不太适合用浏览器默认缓存。假设一个高清短视频 200M ,那么十几个要好几个 G 了,

    最好就是本地启动一个 http web 代理服务器,有本地写入权限。

    让 js 来访问本地服务器的视频,顺便把视频都缓存到用户磁盘上。
    leyfung
        24
    leyfung  
    OP
       350 天前
    是个办法👍
    jiangzm
        25
    jiangzm  
       350 天前
    @qinjiang #5 牛逼! 请教下怎么通过浏览器读取本地是否存在某文件?
    iosyyy
        26
    iosyyy  
       350 天前
    @drymonfidelia 你先搞清楚 electron 事干啥的好吗? 这 tm 是 web 端需要 electron 吗?
    AllenCai
        27
    AllenCai  
       350 天前
    indexDB 试试
    tool2d
        28
    tool2d  
       350 天前
    @jiangzm 有 API 的,只要用户点同意,就能读取了。

    按照道理来说,JS 能访问本地系统文件并不安全,但是大屏应用无所谓的。

    https://developer.chrome.com/docs/capabilities/web-apis/file-system-access
    drymonfidelia
        29
    drymonfidelia  
       350 天前
    @iosyyy 他不是说浏览器没权限吗 那就只能 electron 打包个客户端啊
    ZZITE
        30
    ZZITE  
       350 天前
    Service Worker 了解一下
    简单的说可以代理你的请求,可以制定自己的缓存策略精细化管理缓存,可以把缓存的内容写到用户本地磁盘上
    duke807
        31
    duke807  
       350 天前 via Android
    视频用 av1 压缩,大小直接变小很多,小于浏览器缓存大小的限制
    leyfung
        32
    leyfung  
    OP
       350 天前
    @tool2d #28 感谢,我写个 DEMO 试试
    leyfung
        33
    leyfung  
    OP
       350 天前
    @AllenCai 所有视频加起来比较大,我看这个大小有限制,并且还受到浏览器的限制
    jspatrick
        34
    jspatrick  
       350 天前
    你需要 indexedDB ,理论上浏览器所在盘有多大空间它就能吃多大,所以要记得清理过期数据
    MENGKE
        35
    MENGKE  
       350 天前
    循环播放就只加载一边就缓存了啊,为啥会消耗大量流量呢?
    jiangzm
        36
    jiangzm  
       350 天前
    @tool2d #28 不是一回事, 上传文件也是问询, 做不到主动读取
    Masoud2023
        37
    Masoud2023  
       350 天前
    <video>我记得设置 loop 是不会再次请求的啊?

    https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/video#loop
    qinjiang
        38
    qinjiang  
       350 天前
    @leyfung 本地启 node 服务代理接口,读取本地文件传给 web ,或者使用新的浏览器 api 可以读取本地文件
    Masoud2023
        39
    Masoud2023  
       350 天前
    难道视频太大了这个会失效?我没试过,至少 youtube 我没遇到过这样的问题
    qinjiang
        40
    qinjiang  
       350 天前
    @jiangzm 大屏的网页有个好处在于,他运行的电脑比较固定,在那个电脑上启个服务代理接口,用服务去读本地文件。
    ddch1997
        41
    ddch1997  
       350 天前
    赞同 30LService Worker 这个方案,这个方案出来是解决断网的情况下依旧能访问应用以及有最近的数据,缓存视频应该不是什么问题
    cuicuiv5
        42
    cuicuiv5  
       350 天前
    @iosyyy 反正都是全屏播放, electron 也没啥问题啊
    leyfung
        43
    leyfung  
    OP
       350 天前
    @jiangzm #36
    @MENGKE 视频播放一轮大概六七百 M ,就会超过浏览器缓存最大的限制,然后就被清理了
    jazzg62
        44
    jazzg62  
       350 天前
    包装成 electron ,就能解决缓存限制
    paopjian
        45
    paopjian  
       350 天前
    压缩一下视频,是不是能降低一些大小
    iosyyy
        46
    iosyyy  
       350 天前
    @cuicuiv5 electron 需要用户下载客户端的..完全不一样好吧
    @drymonfidelia #29 需求都变了你觉得这种事是你一句打包个客户端就行的吗
    wangmn
        47
    wangmn  
       350 天前
    如果是 公开的把视频放流媒体平台 比如抖音 b 腾讯啥的,不是公开的 就放客户本地
    MENGKE
        48
    MENGKE  
       350 天前
    1. 压缩视频。
    2. 切割视频。
    3. 楼上给出过的 IndexedDB 等保存在本地。

    这三种方法应该是相对你当前的项目改动最小的。
    luxferrew
        49
    luxferrew  
       350 天前
    资源又大,又要缓存,直接 indexDB ,挺方便的。

    以前有个 web 项目要加载模型文件(接近 1G 了)就这么搞的 2333 。

    如果还要省就考虑压缩视频、换 GIF 图等等...看你们领导需求了...
    petergui
        50
    petergui  
       350 天前
    rsync + local_server
    gbw1992
        51
    gbw1992  
       350 天前
    我倒是觉得可以写个服务放到大屏电脑上
    就定时轮训服务器视频是否更新了,更新就下载到大屏服务器上
    然后大屏 web 写逻辑直接获取本地视频
    leyfung
        52
    leyfung  
    OP
       350 天前
    @wangmn 也是个办法
    fengbjhqs
        53
    fengbjhqs  
       350 天前 via Android
    @leyfung js 可以读取本地文件,
    fengbjhqs
        54
    fengbjhqs  
       350 天前 via Android
    这个本地跑的服务,本地启动,浏览器打开本地地址,
    TsubasaHanekaw
        55
    TsubasaHanekaw  
       350 天前
    那就不要用浏览器阿,最简单的 winform 套个 cerf 的壳都行
    leyfung
        56
    leyfung  
    OP
       350 天前
    感谢大家的回复,下面是可以满足我需求的方案:
    方案一:使用浏览器缓存,设置视频缓存过期时间;缺点是需要配置浏览器。
    方案二:使用 IndexedDB 。
    方案三:单独编写后端服务,后端读取在线文件后,将文件保存至本地,由前端页面请求本地后端服务获取文件。
    方案四:Service Worker 。(查了一下,好像有大小限制,大屏上的视频加起来有五六百 M )

    接下来,试一下方案二。最后考虑方案三,或者就保持方案一。🤝
    L1shen
        57
    L1shen  
       350 天前
    Service Worker 的 cache 大小限制是跟着浏览器限制走的,一般来说可以很大
    你可以通过 navigator.storage.estimate() 方法来查询可以用到多少,一般来说五六百 M 根本不是问题
    leyfung
        58
    leyfung  
    OP
       350 天前
    找到了一个 DEMO ,有需要的可以参考 http://t.csdnimg.cn/kJqnn 实现图片本地化 ServiceWorker + IndexedDB
    xinghen57
        59
    xinghen57  
       350 天前 via iPhone
    本地搭个服务端可否?
    视频换 vp9 等最新编码,体积能比 x.264 小一半。
    54xavier
        60
    54xavier  
       350 天前
    @drymonfidelia #16 对啊,其实我觉得这搞个 electron 客户端不就好了吗?然后就可以 download 视频到磁盘,并且可以直接 读取磁盘文件,就可以用文件的方式来缓存视频了。
    sub166
        61
    sub166  
       350 天前
    浏览器高版本的话可以试试 opfs
    zeusho871
        62
    zeusho871  
       350 天前
    有的网站发现你视频在后台 它给你播放音频 不加载视频 等于他视频和音频是不同的流
    Tokin
        63
    Tokin  
       350 天前
    多大的视频内容,试试存到 IndexDB ?
    kaneg
        64
    kaneg  
       350 天前 via iPhone
    浏览器限制的是一个域名下的缓存大小,能不能切割成多个文件,分布在多个域名下,每个域名下不要超出限制,当然这个方案需要你能控制服务器的域名。
    dcdlove
        65
    dcdlove  
       350 天前
    浏览器缓存都没弄明白还说有大小限制,真是服了
    xuanbg
        66
    xuanbg  
       350 天前
    @leyfung 一个视频分几段存本地存储空间不行吗
    cherryas
        67
    cherryas  
       350 天前
    多少年前就有的成熟方案,外接个硬件控制。你非要纯技术解决
    vultr
        68
    vultr  
       350 天前
    你加个本地 cdn 服务器就好了,反正都用上大屏了,本地也应该有电脑的,配置个 cdn 就行了。
    cijiugechu
        69
    cijiugechu  
       349 天前
    把视频切成几块 Blob 或 ArrayBuffer 后存 IndexdDB 里,IndexedDB 几乎没有大小限制
    iosyyy
        70
    iosyyy  
       349 天前
    @54xavier 又刷到这个贴了 这么多人在这推荐什么 electron 是没做过项目吗..还是没上过班啊 这玩应是能随便改的?
    dode
        71
    dode  
       349 天前
    @leyfung 新的 api 接口授权后可以读本地文件夹
    Huelse
        72
    Huelse  
       349 天前   ❤️ 1
    原生 video 标签和视频响应头中加 Cache-Control 不就可以了,还能有啥?
    dode
        73
    dode  
       349 天前
    前端实现多个视频播放组件,轮流播放,隐藏切换布局,
    qsnow6
        74
    qsnow6  
       349 天前
    @Huelse #72 +1 通过 Response cache 控制应该是最简单的
    hongchends1
        75
    hongchends1  
       349 天前
    可以本地起个 server 或者 打包成应用
    suke119
        76
    suke119  
       349 天前
    推荐本地化磁盘文件的 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" }));

    ```
    leyfung
        77
    leyfung  
    OP
       349 天前
    经过测试,可以使用 indexedDB 存储比较大的视频文件,感谢各位的耐心解答
    leyfung
        78
    leyfung  
    OP
       349 天前
    @leyfung #77 用的 yux-storage 是一个基于 HTML5 IndexedDB 封装的 Web 本地数据离线存储库。https://github.com/yued-fe/yux-storage 阅文前端团队开发的
    uyoungco
        79
    uyoungco  
       341 天前
    前几天看了帖子没觉得什么,今天这也让我遇到了 感谢 op ,我学习了
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5945 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 46ms · UTC 01:58 · PVG 09:58 · LAX 17:58 · JFK 20:58
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.