vue+spring boot 利用ffmpeg实现大视频切片
vue+spring boot 利用ffmpeg实现大视频切片
一般来讲为了提升用户的观影体验,大的文件传输较慢,这时可以将大文件分段传输来做到边看边下载。
最常用的是HLS 分片(.m3u8 + .ts)尤其是在线视频网站(B 站、爱奇艺、腾讯视频等)。
优点:
支持大文件播放、直播、拖动进度条
支持多码率、自适应网络
浏览器兼容性好(通过 Hls.js)
弹幕、广告等功能容易实现
缺点:
需要先切片(ffmpeg 或后台批处理)
多文件管理复杂
一、下载ffmpeg
下载地址
发布 ·BtbN/FFmpeg 构建
这里我们在window环境测试,下载windos版本:
下载后解压、添加到环境变量:
如图为成功:
二、提前将大视频分片并存储
后端:
这里可以上传大视频到服务器:
// 处理 HLS 文件请求@GetMapping("/stream/hls/{videoName}/{fileName:.+}")public void streamHls(@PathVariable String videoName,@PathVariable String fileName,HttpServletResponse response) throws IOException {File file = new File(VIDEO_PATH + "hls/" + videoName + "/" + fileName);if (!file.exists()) {response.setStatus(HttpServletResponse.SC_NOT_FOUND);return;}
//设置 Content-TypeString contentType;if (fileName.endsWith(".m3u8")) {contentType = "application/vnd.apple.mpegurl";} else if (fileName.endsWith(".ts")) {contentType = "video/mp2t";} else {contentType = "application/octet-stream";}response.setContentType(contentType);response.setHeader("Access-Control-Allow-Origin", "*");
//设置返回的文件流try (InputStream in = new FileInputStream(file);OutputStream out = response.getOutputStream()) {byte[] buffer = new byte[8192];int len;while ((len = in.read(buffer)) != -1) {out.write(buffer, 0, len);}}}
将大视频切分:
到视频的同级目录下(这里 我们将其放到了项目里)
进行分片
ffmpeg -i bbb.mp4 -hls_time 10 -hls_list_size 0 -f hls hls/bbb/index.m3u8
如图为成功:
如此在浏览器访问http://localhost:6789/api/videos/hls/bbb/index.m3u8
就会下载index文件:
三、前端获取
这里我们利用开源播放器dplayer演示:
onMounted(() => {dp = new DPlayer({container: document.getElementById('dplayer'),autoplay: false,theme: 'lightblue',lang: 'zh-cn',video: {url: '/api/videos/hls/bbb/index.m3u8', // HLS m3u8 文件type: 'customHls',customType: {customHls(video, player) {// HLS 播放if (Hls.isSupported()) {const hls = new Hls()hls.loadSource(video.src)hls.attachMedia(video)hls.on(Hls.Events.ERROR, function (event, data) {console.error('HLS 错误:', data)})} else if (video.canPlayType('application/vnd.apple.mpegurl')) {video.src = video.src} else {player.notice('浏览器不支持 HLS')}}}},danmaku: {id: '1', // 视频唯一 IDapi: '/api/danmaku/', // 弹幕接口user: '游客', // 默认用户名bottom: '15%', // 弹幕显示位置unlimited: true // 不限制弹幕数量},// 可选:高亮时间点提示highlight: [{ time: 50, text: '第 50 秒' },{ time: 100, text: '第 100 秒' }]})
})