Java后端返回视频流
⚠️:返回的状态码需要是206的,此状态可以让用户决定视频流是播放还是下载,默认状态200访问会直接下载
视频格式需要是浏览器支持播放的格式:ACC(音频) H264(视频)
这个方法前端用video标签的话是会自动多次调用方法,做视频缓存,不会直接一次性加载全部。
前端代码:
<video class="box" controls="controls" autoplay="autoplay">
<source
src="/getVideo?fileName=/video/movie.mov"
type="video/mp4" class="">
</video>
后台接口:
/**
* 获取视频流
* @param response
* @param fileName 视频存放信息索引
* @return
* @author xWang
* @Date 2020-05-20
*/
@RequestMapping("/getVideo")
public void getVideo(HttpServletRequest request, HttpServletResponse response,String fileName) {
//视频资源存储信息
response.reset();
//获取从那个字节开始读取文件
String rangeString = request.getHeader("Range");
log.info("getVideo获取视频资源:{},读取文件字节:{}",fileName,rangeString);
try {
//获取响应的输出流
OutputStream outputStream = response.getOutputStream();
File file = new File(fileName);
if(file.exists()){
RandomAccessFile targetFile = new RandomAccessFile(file, "r");
long fileLength = targetFile.length();
//播放
if(rangeString != null){
long range = Long.parseLong(rangeString.substring(rangeString.indexOf("=") + 1, rangeString.indexOf("-")));
//设置内容类型
response.setHeader("Content-Type", "video/mov");
//设置此次相应返回的数据长度
response.setHeader("Content-Length", String.valueOf(fileLength - range));
//设置此次相应返回的数据范围
response.setHeader("Content-Range", "bytes "+range+"-"+(fileLength-1)+"/"+fileLength);
//返回码需要为206,而不是200
response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);
//设定文件读取开始位置(以字节为单位)
targetFile.seek(range);
}else {//下载
//设置响应头,把文件名字设置好
response.setHeader("Content-Disposition", "attachment; filename="+fileName );
//设置文件长度
response.setHeader("Content-Length", String.valueOf(fileLength));
//解决编码问题
response.setHeader("Content-Type","application/octet-stream");
}
byte[] cache = new byte[1024 * 300];
int flag;
while ((flag = targetFile.read(cache))!=-1){
outputStream.write(cache, 0, flag);
}
}else {
String message = "file:"+fileName+" not exists";
//解决编码问题
response.setHeader("Content-Type","application/json");
outputStream.write(message.getBytes(StandardCharsets.UTF_8));
}
outputStream.flush();
outputStream.close();
} catch (FileNotFoundException e) {
} catch (IOException e) {
}
}