• 请不要在回答技术问题时复制粘贴 AI 生成的内容
Triump
V2EX  ›  程序员

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

  •  
  •   Triump · Feb 16, 2023 · 7171 views
    This topic created in 1358 days ago, the information mentioned may be changed or developed.

    需求背景:

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

    我的思路:

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

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

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

    本来就无法确定。

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

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

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

    上面这种换成:

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

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

    mouyong
    mouyong
    Feb 16, 2023
    25
    在线预览与管理管理本地文件、视频。

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