Java 视频流分段返回

package com.example.demo.controller;

import ch.qos.logback.core.net.SyslogOutputStream;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.io.RandomAccessFile;

/**
 * Description: videoTest
 *
 * @author 
 * @CalssName: videoController
 * @Email 
 * @date 2021/6/29 15:06
 */
@RestController
public class videoController {
    @GetMapping("video")
    public void play(HttpServletRequest request, HttpServletResponse response) throws IOException {
        response.reset();
        File file = new File("F:\\test\\pyjwt_test\\1.mp4");
        long fileLength = file.length();
        // 随机读文件
        RandomAccessFile randomAccessFile = new RandomAccessFile(file, "r");

        //获取从那个字节开始读取文件
        String rangeString = request.getHeader("Range");
        System.out.println(rangeString);
        long range=0;
        if (rangeString!=null) {
            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);
        //设置此次相应返回的数据范围
        response.setHeader("Content-Range", "bytes "+range+"-"+(fileLength-1)+"/"+fileLength);
        // 将这1MB的视频流响应给客户端
        outputStream.write(bytes, 0, len);
        outputStream.close();
        randomAccessFile.close();

        System.out.println("返回数据区间:【"+range+"-"+(range+len)+"】");
    }
}

当你在Java后端通过`HttpServletResponse`将视频流直接发送到前端,可能会遇到视频不能拖动播放的问题。这通常是由于HTTP响应头设置不当,或者浏览器对于长连接处理限制导致的。以下是可能的原因和解决办法: 1. 设置正确的Content-Type和Content-Disposition: 流式媒体通常需要正确的MIME类型,如`video/mp4`,以及合适的文件名,可以设置`Content-Disposition`为“attachment; filename=video.mp4”。这告诉浏览器这是一个下载而不是页面内的资源。 ```java response.setContentType("video/mp4"); response.setHeader("Content-Disposition", "attachment; filename=video.mp4"); ``` 2. 长期保持连接(Keep-Alive): 默认情况下,浏览器会关闭HTTP连接,如果你想要支持断点续传,可以设置`Connection`头为`keep-alive`。 ```java response.setHeader("Connection", "keep-alive"); ``` 3. 使用ServletOutputStream: 直接操作`HttpServletResponse.getOutputStream()`可能导致连接关闭,建议使用`ServletOutputStream`配合`BufferedInputStream`或类似工具逐字节输出。 4. 使用范围请求(Range Header): 如果后端支持,允许客户端指定从哪一段开始请求视频内容,这对于分段加载大文件有帮助。 5. 跨域问题: 检查是否设置了正确的CORS策略,允许跨域访问视频资源。 如果以上步骤都做了,但还是无法拖动播放,可能是浏览器缓存或网络问题,尝试清除缓存或者检查网络状况。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值