当前位置:首页 > 技术分析 > 正文内容

springboot+vue播放视频流(无需下载,可以拖动进度、倍速播放)

ruisui885个月前 (01-24)技术分析39

介绍

最近因为想做个在手机上播放电脑上视频的软件,所以就去了解了一下springboot播放视频流的技术实现。网上查了很多资料,发现都有问题:

  1. 最低级的,直接在springboot中读取了整个视频文件,然后把读取到的文件流,写入HttpServletResponse的OutputStream。这种方案问题很大,服务器耗内存,客户端卡顿,因为客户端得把整个视频下载好才能播放。
  2. 稍好一点的,意识到要使用http的range来实现分片加载,就是客户端无需下载整个视频了,可以拖动进度条,分段请求服务器。但是,网上的教程,都是自己动手实现的,代码逻辑大概是这样:根据客户端要的文件片段,springboot加载本地文件,切分出具体那段文件,返回给客户端。逻辑没问题,就是没必要这么干~因为,springboot自己本身就有这方面的代码。自己写又不稳定,又麻烦。

ResourceHttpRequestHandler


ResourceHttpRequestHandler是springboot加载静态资源的一个类,平时是用来从你resources/statics等目录加载文件的。所以,这个类本身就是支持range请求数据的。我们要做的,就是把要播放的文件File传递给
ResourceHttpRequestHandler就行,三五行代码搞定!

springboot服务端代码

第一步,先自定义实现一个
ResourceHttpRequestHandler。代码如下:

package com.tec666.moviebar.config;

import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.resource.ResourceHttpRequestHandler;

import javax.servlet.http.HttpServletRequest;

/**
 * @author longge93
 */
@Component
public class NonStaticResourceHttpRequestHandler extends ResourceHttpRequestHandler {

    public final static String ATTR_FILE = "NON-STATIC-FILE";

    @Override
    protected Resource getResource(HttpServletRequest request) {
        String filePath =  (String) request.getAttribute(ATTR_FILE);
        return new FileSystemResource(filePath);
    }
}

上面代码的意思是:从HttpServletRequest的attribute中读取文件path,然后返回给
ResourceHttpRequestHandler处理。当然,这个attribute是我们后面传进来的。

第二步,在视频播放controller中,把本地文件路径传入
ResourceHttpRequestHandler。代码如下:

@Controller
@RequestMapping(value = "/api/baseResource")
public class BaseSourceApiController {

  
    @Autowired
    private NonStaticResourceHttpRequestHandler nonStaticResourceHttpRequestHandler;


    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @RequestMapping(value = "/video", method = RequestMethod.GET)
    public void video(
            HttpServletRequest request,
            HttpServletResponse response
    ) {
        try {
            String path = "D:/abc.mp4";
            File file = new File(path);
            if (file.exists()) {
                request.setAttribute(NonStaticResourceHttpRequestHandler.ATTR_FILE, path);
                nonStaticResourceHttpRequestHandler.handleRequest(request, response);
            } else {
                response.setStatus(HttpServletResponse.SC_NOT_FOUND);
                response.setCharacterEncoding(StandardCharsets.UTF_8.toString());
            }
        } catch (Exception e) {

        }
    }
}

参数解释:记得把上面代码中的path替换成你的路径,或者从controller请求参数里获取。

到此,整个springboot播放视频流的功能就实现了,感觉是全网最最简便的了。因为可以根据range返回视频流片段,所以客户端是可以随意拖动进度条,可以倍速播放的。相比把整个视频下载好再播放,这个方案才是yyds!

Vue前端播放器

我使用的是vue-video-player这个开源组件,你可以自己用npm安装一下,然后在你的项目中直接用就行。配置参数的时候,视频地址就填上面springboot的这个controller地址。

java截取视频生成图片封面、GIF封面

主要分为两个功能:

  1. java截取视频,把视频帧拆分成几张图片,用作视频封面。
  2. java把几张图片拼接成一个gif图片。

这两个功能是在做播放器的时候,一起顺手实现的,网上的教程相对挺多的,如果有需要请点击右侧“联系作者”联系我,我再开单独的文章介绍。

播放器效果展示

我们打开chrome的开发者工具,查看播放视频时的网络请求,可以发现视频是被切分成小片段,根据你当前的播放进度,分片下载的。请看下图:

版权声明:《springboot+vue播放视频流(无需下载视频,可以拖动进度、倍速播放)》为CoderBBB作者「???」的原创文章,转载请附上原文出处链接及本声明。

原文链接:
https://www.coderbbb.com/articles/39

扫描二维码推送至手机访问。

版权声明:本文由ruisui88发布,如需转载请注明出处。

本文链接:http://www.ruisui88.com/post/522.html

分享给朋友:

“springboot+vue播放视频流(无需下载,可以拖动进度、倍速播放)” 的相关文章

财务未来:数字化全流程自动化报销,让预算管理更轻松

财务管理是企业经营的重中之重,费控管理则是财务管理的核心之一。上至管理层下至普通员工,面对繁琐的费控管理却是“家家有本难念的经”。举个常见的例子:在传统企业的费用管理模式下,员工在进行商务活动时,通常需要自行垫资,之后再经过一系列繁杂的报销审批流程,才能最终实现打款。对于普通员工来说,申报流程繁琐,...

基于gitlab的PR操作教程

基于gitlab的PR操作教程注:该教程主要基于git命令行操作,其他图形化工具也可完成以下所有操作步骤,顺手即可。推荐工具:Source Tree ,TortoiseGit参考:gitflow一 . 基于分支的PR操作1. 本地切换到master分支1. 拉取最新代码2. 基于master创建ho...

快速掌握 Git:程序员必会的版本控制技巧

在现代软件开发中,版本控制系统(VCS)是开发人员不可或缺的工具。无论是个人项目,还是多人协作的团队开发,良好的版本控制都能确保代码管理的高效性与稳定性。而在版本控制系统中,Git 凭借其分布式、灵活性和高效性,成为了最流行的工具之一。几乎所有的开发团队都在使用 Git 来管理代码版本、协作开发和追...

你感动了吗?佳能超规格镜头 RF 24-105mm F2.8深度测评

如果要你选一支用作多题材创作的挂机镜头,那我相信很多人会选择24-105mm这个焦段的镜头。作为一支可以实现从广角到长焦的变焦镜头,24-105mm有着丰富的焦段选择。只是基于镜头体积以及光学结构上的限制,此前的24-105mm镜头只能恒定在F4的光圈。而佳能打破了这一限制,将实用焦段和恒定光圈完美...

Python中的11 种数组算法

1. 创建数组 创建数组意味着留出一个连续的内存块来存储相同类型的元素。在大多数语言中,您可以在创建数组时指定数组的大小。假设您正在书架上整理一组书籍,并且您需要为正好 10 本书预留空间。功能架上的每个空间都对应于数组中的一个索引。# Example in Python arr = [1, 2,...

Vue进阶(二十六):详解router.push()

在Vue2.0路由跳转中,除了使用 <router-link> 声明式创建 a 标签来定义导航链接,还可以借助 router 的实例方法,通过编码式编写代码来实现。router.push(location)想要导航到不同的 URL,则使用 router.push 方法。这个方法会向 hi...