自存,关于RandomAccessFile和response实现视频播放

 RandomAccessFile类是随机读取文件类可以支持读和写,还可以冲指定位置开始读,从我在网上查到的资料来看,RandomAccessFile一般是用于视频播放的实现,

一般来说,前端在播放视频时请求头会携带range这个参数,这个参数记录了,当前播放到了哪一个字节

 如下所示:

所以我们可以通过request来拿取这个数据然后字符串切割得到要播放的具体位置

然后response要返回两个东西,一是响应状态码206,表示只是上传部分请求

还有一个是响应体  Content-Rang 意思是,确立起始位置,终止位置以及整个视频所需字节长度

格式例如 Content-Range: bytes 0-169704/169705

range是播放到的具体位置,fileLength是这个文件的长度

response.setHeader("Content-Range", "bytes "+range+"-"+(fileLength-1)+"/"+fileLength);
 @GetMapping("/play")
        public void play( String Md5, String fileName,HttpServletRequest request, HttpServletResponse response) throws IOException{
            File file = new File(PATH + Md5 + "\\" + fileName);
            long fileLength = file.length();
            // 随机读文件
            RandomAccessFile randomAccessFile = new RandomAccessFile(file, "r");
            //获取从那个字节开始读取文件
            String rangeString = request.getHeader("Range");
            //拿取range
            long range = Long.valueOf(rangeString.substring(rangeString.indexOf("=") + 1, rangeString.indexOf("-")));
            //获取响应的输出流
            OutputStream outputStream = response.getOutputStream();
            //设置内容类型(注释也可以)
            response.setHeader("Content-Type", "video/mp4");
            //返回码需要为206,代表只处理了部分请求,响应了部分数据(必须)
            response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);
            // 移动访问指针到指定位置
            randomAccessFile.seek(range);
            // 每次请求只返回1MB的视频流
            byte[] bytes = new byte[1024 * 1024];
            int len = randomAccessFile.read(bytes);
            //设置此次相应返回的数据长度(注释也可以)
           response.setContentLength(len);
            //设置此次相应返回的数据范围(必须,和返回状态码206相对应)
           response.setHeader("Content-Range", "bytes "+range+"-"+(fileLength-1)+"/"+fileLength);
//            System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>.");
//            System.out.println("bytes "+range+"-"+(fileLength-1)+"/"+fileLength);
            // 将这1MB的视频流响应给客户端
           outputStream.write(bytes, 0, len);
           outputStream.close();
           randomAccessFile.close();
        }

我是根据文件md5和名字存文件的,这里可以忽略,

应该是只能用RandomAccessFile来读分片读文件,如果我用InputStream就只能读取整个文件了,这样子视频就不能拖动进度条了,因为inputstrem不能指定要读取的位置

这是用inputstrem来读取

@GetMapping("/preview")
    public void preview(String Md5, String fileName,HttpServletResponse response) throws IOException {
        File file = new File(PATH + Md5 + "\\" + fileName);
        String filename = file.getName();
        byte[] bytesArray = new byte[(int) file.length()];
        FileInputStream fis = new FileInputStream(file);
        fis.read(bytesArray);
        fis.close();
        OutputStream os = response.getOutputStream();
        os.write(bytesArray);
        //attachment表示以附件方式下载   inline表示在线打开   "Content-Disposition: inline; filename=文件名.mp3"
        // filename表示文件的默认名称,因为网络传输只支持URL编码的相关支付,因此需要将文件名URL编码后进行传输,前端收到后需要反编码才能获取到真正的名称
        response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(filename, "UTF-8"));
        os.close();
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值