springboot编写mp4视频播放接口

简单粗暴方式

直接读取指定文件,用文件流读取视频文件,输出到响应中

    @GetMapping("/display1/{fileName}")
    public void displayMp41(HttpServletRequest request, HttpServletResponse response,@PathVariable("fileName") String fileName) throws IOException {
        File file=new File("D:/Download/"+fileName+".mp4");
        if(!file.exists()){
            response.getOutputStream().close();
            return;
        }
        InputStream inStream=new FileInputStream(file);
        byte[] buffer = new byte[1024];
        int len;
        while ((len = inStream.read(buffer)) != -1) {
            response.getOutputStream().write(buffer, 0, len);
        }
        inStream.close();
        response.getOutputStream().flush();
        response.getOutputStream().close();
    }

这种方式很尴尬,可以播放视频,然而你会发现视频自带的进度条无法拖动。。。。。。。,只能暂停播放,没办法前进,也没办法后退。。。。。。

高端优雅方式

需要加一个断点续传的规范,实现很简单

注:如果你是用的h5原生的

实现一共两点:

(1)响应头部添加如下格式响应头

Content-Range: bytes 589824-32153693/32153694

大概就是:Content-Range: bytes 请求头指定的开始字节数-本次返回的文件字节位置/总共多少字节,值得注意的是,本次返回的文件字节位置一定要比总字节数至少少一个字节,否则视频缓存结束的最后一次数据无法播放,可能是浏览器出了异常,视频会重新播放。本次返回的文件字节位置可以不准,因为浏览器会自动记录真实拿到的字节数量,但一定要少一个字节。

(2)响应码改为206

有了这两点就可以实现正常的视频播放接口了。

优化

考虑到视频的进度条很大概览是会被拖来拖去的,导致频繁请求接口。

假设你的文件200MB,频繁的请求每次都会把整个文件读入http流中,如果用户网速慢,或者浏览器的缓存策略会阻塞http请求,慢慢从http响应中读取这部分数据,这可能就会使数据都堆积到服务器内存里(本人毫无根据瞎想的),浪费资源。

(1)因为需要指定字节位置读取视频文件,使用随机读取RandomAccessFile类来操作。

(2)既然支持分段获取数据,不如每次返回定量的字节数即可。我这里设置成每次获取1MB,浏览器播放完了会自动接着调用。根据实际情况考虑,内网环境使用可以设大一些,如果数值设置的小,这请求频率会变的很多,得不偿失。

    @GetMapping("/display/{fileName}")
    public void displayMp4(HttpServletRequest request, HttpServletResponse response, @PathVariable("fileName") String fileName) throws IOException {
        File file = new File("D:/Download/" + fileName + ".mp4");
        if (!file.exists()) {
            response.getOutputStream().close();
            return;
        }
        String range = request.getHeader("Range");
        long lenStart = 0;
        if (range != null && range.length() > 7) {
            range = range.substring(6, range.length() - 1);
            lenStart = Long.parseLong(range);
        }
        int size = 1048576;
        response.setHeader("Content-Range", "bytes " + lenStart + "-" + ((file.length() - lenStart-2 < size)?file.length()-1:lenStart+size- 1) +"/" + file.length());
        response.setHeader("Content-Type", "video/mp4");
        response.setStatus(HttpStatus.PARTIAL_CONTENT.value());//响应码206表示响应内容为部分数据,需要多次请求
        RandomAccessFile randomAccessFile = new RandomAccessFile(file, "rw");
        randomAccessFile.seek(lenStart);//设置读取的开始字节数
        //视频每次返回一兆数据
        byte[] buffer = new byte[size];
        int len = randomAccessFile.read(buffer);
        if (len != -1) {
            response.getOutputStream().write(buffer, 0, len);
        }
        randomAccessFile.close();
        response.getOutputStream().flush();
        response.getOutputStream().close();
    }

 附上测试的vue代码,当然里面有丰富的video的监听事件





springboot编写mp4视频播放接口_第1张图片

 

 

你可能感兴趣的:(Java,spring,boot,音视频,java)