需求背景:
要在网页上播放视频,视频是存储在文件系统( minIO )上,现在的做法是,前端请求后台的文件下载接口,将整个文件下载后返回给前端进行播放。但是这个视频大概有 140M ,整个过程耗时大概 1 分钟了。用户体验很差。
我的思路:
后端提供一个支持文件分片下载的方法,前端通过请求头设置 Range 参数传入指定的范围。比如一个 100M 的文件,每次请求 10M, 但是我不确定前端拿到这 10M 文件后,是否能够播放。。。 如果这个思路可行的话,前端需要用到哪些技术呢?
有没有大佬能够提供一下思路啊?
1 fiveStarLaoliang 2023-02-16 11:17:00 +08:00 走 nginx 转发不就行了,顶多加个鉴权,不需要自己去写切片播放 |
2 weixiaoyun 2023-02-16 11:17:04 +08:00 不用下载,minio 支持视频拉流的,给个视频预览源地址给前端播放器调用就好了 |
![]() | 3 Triump OP @weixiaoyun 就是让前端直接去访问 minio 吗?这样的话要把 桶的权限设置为公开,会不会很危险,因为这个项目要支持外网访问的。 |
![]() | 4 tool2d 2023-02-16 11:28:39 +08:00 "但是我不确定前端拿到这 10M 文件后,是否能够播放" 本来就无法确定。 MP4 有两种格式,头格式和尾格式。头格式把具体播放信息都放在头部,可以流式播放。尾格式是把详细信息都放在文件末尾,你比如下载视频 BT ,必须把整个文件拖下来后,才能播放。 当然有工具可以在这两种格式之间切换。 |
![]() | 5 MoonWalker 2023-02-16 11:29:48 +08:00 返回 206 状态码然后按 Range 解析字节范围就好了吧? |
7 registerrr 2023-02-16 11:31:00 +08:00 |
8 registerrr 2023-02-16 11:34:28 +08:00 要是访问也需要授权就用 6#的这个方法 |
9 duckyrain 2023-02-16 11:35:29 +08:00 走公有云 CDN ? 边下边播是视频格式决定的,和下载服务没关系。 |
![]() | 10 Triump OP @MoonWalker 我现在的思路就是这样,和前端小哥沟通了一下,他还不知道这种方式要怎么处理,所以不知道前端能不能去这个实现。 |
![]() | 11 Triump OP @registerrr 感谢,这个思路也可以。 |
12 okakuyang 2023-02-16 11:59:15 +08:00 边下边播要 Range 支持,不然苹果系可能播放不了。 |
13 niushuai 2023-02-16 13:31:03 +08:00 还是做切片比较合适 |
![]() | 14 rqxiao 2023-02-16 13:39:41 +08:00 m3u8 文件 |
![]() | 15 opengg 2023-02-16 13:44:47 +08:00 前端用 xgplayer https://v2.h5player.bytedance.com/ |
![]() | 16 luob 2023-02-16 13:46:17 +08:00 后端调用 ffmpeg 切成 dash ,然后前端直接 plyr 播放器,都是成熟方案不用自己写什么 |
![]() | 17 luob 2023-02-16 13:48:16 +08:00 ![]() 唯一缺点是担心客户看到 plyr 播放器的界面会不有什么奇怪的反应( |
![]() | 18 spike76 2023-02-16 13:50:43 +08:00 用 ffmpeg 将 mp4 转成流格式 ffmpeg -i #{video_path} -codec: copy -start_number 0 -hls_time 16 -hls_list_size 0 -f hls #{hls_index_path} 每个小块文件只有 16 秒内容,前端下载应该足够快了 |
19 wxd21020 2023-02-16 13:53:35 +08:00 学习学习,看大佬们有啥解决方案 |
![]() | 20 cheng6563 2023-02-16 14:16:33 +08:00 前端播放很难说的,你别看这些文件都是.mp4 ,其实内部差异大得很。 有必要的话还是要上 ffmpeg 重新封包(不是转码) |
![]() | 21 mmdsun 2023-02-16 14:32:46 +08:00 你是不是用 Java 先 download 文件,然后再 Response 写返回给页面的? 你应该用 gateway 代理直接转发给页面,这样后端你就需要先下载了 |
![]() | 22 mmdsun 2023-02-16 14:37:17 +08:00 var file = downloadFile("http://xxxxxxxxxx"); Response.write(file); 上面这种换成: /gateway/download/xxxxxxxxxx => http://file.download/xxxxxxxxxx 要是云存储那边要鉴权加什么请求头的,你网关直接给加上就好。 |
![]() | 23 zzl22100048 2023-02-16 15:11:35 +08:00 能用 m3u8 是最好 最省事就 presignedGetObjectUrl 期限设置一天 |
![]() | 24 mouyong 2023-02-16 15:20:14 +08:00 |
![]() | 25 mouyong 2023-02-16 15:22:39 +08:00 |
26 renmu 2023-02-16 15:23:38 +08:00 via Android 走 m3u8 ,很成熟了 |
![]() | 27 qfdk PRO m3u8 吧 多简单 流方案. m3u8 视频格式原理:将完整的视频拆分成多个.ts 视频碎片,.m3u8 文件详细记录每个视频片段的地址。 视频播放时,会先读取.m3u8 文件,再逐个下载播放.ts 视频片段 |
28 HTML001 2023-02-16 17:16:25 +08:00 后端将视频转 m3u8, 前端用 hls.js 或者 video.js 播放应该就可以满足 |
![]() | 29 wqhui 2023-02-16 17:31:26 +08:00 m3u8 ,大的在线视频网站都这样玩 |
30 HtPM 2023-02-16 18:00:02 +08:00 #16 楼是正规方案,现在基本上都是用 MPEG-DASH 方案,Youtube 采用的这种 |
31 123zouwen 2023-02-16 19:04:53 +08:00 前段时间刚做了类似需求, 简单做法就是后端返回给前端 mp4 的视频链接(如果桶不是 public 的话, 后端调用 minio 生成一个临时访问链接), 前端拿到链接即可播放视频, 快进等功能正常 |
![]() | 32 xylxAdai 2023-02-16 19:10:09 +08:00 m3u8 啊。切成流格式,直接播放。 |
![]() | 33 ryanbuu 2023-02-17 00:24:03 +08:00 转 dash + 1 |
![]() | 35 cephei 2023-02-17 10:49:38 +08:00 可以在后台做一层代理,把前端的 Http Range 请求转发到 MinIO |
36 Sum0l 2023-02-17 13:25:32 +08:00 推荐一个 java 版的 ffmpeg https://github.com/bytedeco/javacv |
![]() | 37 dudubaba 2023-02-17 14:53:08 +08:00 好像除了直接访问,没有一劳永逸的方法,得后端改造一下。 |
![]() | 38 lbunderway 2023-02-17 17:52:00 +08:00 ffmpeg 这个靠谱 |