需求背景:
要在网页上播放视频,视频是存储在文件系统( 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 1
唯一缺点是担心客户看到 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 2023-02-16 15:24:31 +08:00
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
q1angch0u 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 这个靠谱
|