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

Java 实现大文件(视频)的高效下载,并让前端播放,有什么思路吗?

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

    需求背景:

    要在网页上播放视频,视频是存储在文件系统( minIO )上,现在的做法是,前端请求后台的文件下载接口,将整个文件下载后返回给前端进行播放。但是这个视频大概有 140M ,整个过程耗时大概 1 分钟了。用户体验很差。

    我的思路:

    后端提供一个支持文件分片下载的方法,前端通过请求头设置 Range 参数传入指定的范围。比如一个 100M 的文件,每次请求 10M, 但是我不确定前端拿到这 10M 文件后,是否能够播放。。。 如果这个思路可行的话,前端需要用到哪些技术呢?

    有没有大佬能够提供一下思路啊?

    38 条回复    2023-02-17 17:52:00 +08:00
    fiveStarLaoliang
        1
    fiveStarLaoliang  
       230 天前
    走 nginx 转发不就行了,顶多加个鉴权,不需要自己去写切片播放
    weixiaoyun
        2
    weixiaoyun  
       230 天前
    不用下载,minio 支持视频拉流的,给个视频预览源地址给前端播放器调用就好了
    Triump
        3
    Triump  
    OP
       230 天前
    @weixiaoyun 就是让前端直接去访问 minio 吗?这样的话要把 桶的权限设置为公开,会不会很危险,因为这个项目要支持外网访问的。
    tool2d
        4
    tool2d  
       230 天前
    "但是我不确定前端拿到这 10M 文件后,是否能够播放"

    本来就无法确定。

    MP4 有两种格式,头格式和尾格式。头格式把具体播放信息都放在头部,可以流式播放。尾格式是把详细信息都放在文件末尾,你比如下载视频 BT ,必须把整个文件拖下来后,才能播放。

    当然有工具可以在这两种格式之间切换。
    MoonWalker
        5
    MoonWalker  
       230 天前
    返回 206 状态码然后按 Range 解析字节范围就好了吧?
    MoYi123
        6
    MoYi123  
       230 天前
    @Triump 用 presignedGetObjectUrl
    registerrr
        7
    registerrr  
       230 天前
    @Triump
    不用,把桶权限设置成 download (共有读私有写)就行了

    返回视频流时候你有业务要处理么?没有就是直接访问啊,前端只写个 video 标签都可以了
    registerrr
        8
    registerrr  
       230 天前
    要是访问也需要授权就用 6#的这个方法
    duckyrain
        9
    duckyrain  
       230 天前
    走公有云 CDN ?
    边下边播是视频格式决定的,和下载服务没关系。
    Triump
        10
    Triump  
    OP
       230 天前
    @MoonWalker 我现在的思路就是这样,和前端小哥沟通了一下,他还不知道这种方式要怎么处理,所以不知道前端能不能去这个实现。
    Triump
        11
    Triump  
    OP
       230 天前
    @registerrr 感谢,这个思路也可以。
    okakuyang
        12
    okakuyang  
       230 天前
    边下边播要 Range 支持,不然苹果系可能播放不了。
    niushuai
        13
    niushuai  
       230 天前
    还是做切片比较合适
    rqxiao
        14
    rqxiao  
       230 天前
    m3u8 文件
    opengg
        15
    opengg  
       230 天前
    luob
        16
    luob  
       230 天前
    后端调用 ffmpeg 切成 dash ,然后前端直接 plyr 播放器,都是成熟方案不用自己写什么
    luob
        17
    luob  
       230 天前   ❤️ 1
    唯一缺点是担心客户看到 plyr 播放器的界面会不有什么奇怪的反应(
    spike76
        18
    spike76  
       230 天前
    用 ffmpeg 将 mp4 转成流格式
    ffmpeg -i #{video_path} -codec: copy -start_number 0 -hls_time 16 -hls_list_size 0 -f hls #{hls_index_path}
    每个小块文件只有 16 秒内容,前端下载应该足够快了
    wxd21020
        19
    wxd21020  
       230 天前
    学习学习,看大佬们有啥解决方案
    cheng6563
        20
    cheng6563  
       230 天前
    前端播放很难说的,你别看这些文件都是.mp4 ,其实内部差异大得很。
    有必要的话还是要上 ffmpeg 重新封包(不是转码)
    mmdsun
        21
    mmdsun  
       230 天前
    你是不是用 Java 先 download 文件,然后再 Response 写返回给页面的?
    你应该用 gateway 代理直接转发给页面,这样后端你就需要先下载了
    mmdsun
        22
    mmdsun  
       230 天前
    var file = downloadFile("http://xxxxxxxxxx");
    Response.write(file);

    上面这种换成:

    /gateway/download/xxxxxxxxxx => http://file.download/xxxxxxxxxx

    要是云存储那边要鉴权加什么请求头的,你网关直接给加上就好。
    zzl22100048
        23
    zzl22100048  
       230 天前
    能用 m3u8 是最好
    最省事就 presignedGetObjectUrl 期限设置一天
    mouyong
        24
    mouyong  
       230 天前
    我有解决方案,可付费提供,见下方图。本地大文件视频在线播放。
    1. 大文件视频在线播放不卡顿
    2. 大文件视频本地存储,不用担心昂贵的云存储费用

    mouyong
        25
    mouyong  
       230 天前
    在线预览与管理管理本地文件、视频。

    renmu
        26
    renmu  
       230 天前 via Android
    走 m3u8 ,很成熟了
    qfdk
        27
    qfdk  
       230 天前
    m3u8 吧 多简单 流方案.
    m3u8 视频格式原理:将完整的视频拆分成多个.ts 视频碎片,.m3u8 文件详细记录每个视频片段的地址。 视频播放时,会先读取.m3u8 文件,再逐个下载播放.ts 视频片段
    HTML001
        28
    HTML001  
       230 天前
    后端将视频转 m3u8, 前端用 hls.js 或者 video.js 播放应该就可以满足
    wqhui
        29
    wqhui  
       230 天前
    m3u8 ,大的在线视频网站都这样玩
    HtPM
        30
    HtPM  
       230 天前
    #16 楼是正规方案,现在基本上都是用 MPEG-DASH 方案,Youtube 采用的这种
    123zouwen
        31
    123zouwen  
       230 天前
    前段时间刚做了类似需求, 简单做法就是后端返回给前端 mp4 的视频链接(如果桶不是 public 的话, 后端调用 minio 生成一个临时访问链接), 前端拿到链接即可播放视频, 快进等功能正常
    xylxAdai
        32
    xylxAdai  
       230 天前
    m3u8 啊。切成流格式,直接播放。
    q1angch0u
        33
    q1angch0u  
       230 天前
    转 dash + 1
    q1angch0u
        34
    q1angch0u  
       230 天前
    @q1angch0u 转完存一下,下次接着播
    cephei
        35
    cephei  
       230 天前
    可以在后台做一层代理,把前端的 Http Range 请求转发到 MinIO
    Sum0l
        36
    Sum0l  
       229 天前
    推荐一个 java 版的 ffmpeg https://github.com/bytedeco/javacv
    dudubaba
        37
    dudubaba  
       229 天前
    好像除了直接访问,没有一劳永逸的方法,得后端改造一下。
    lbunderway
        38
    lbunderway  
       229 天前
    ffmpeg 这个靠谱
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   2239 人在线   最高记录 6067   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 35ms · UTC 02:51 · PVG 10:51 · LAX 19:51 · JFK 22:51
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.