描述
最近在做H5的video和audio播放视频或音频流的时候遇到问题:在chrome里和安卓里播放都没有问题,但是放到safari和iOS里播放就播放不出来.
接口代码
@RequestMapping(value = "/getVideo", method = RequestMethod.GET)
public void getVideo(HttpServletRequest re , HttpServletResponse resp)
{
JSONObject backJO = new JSONObject();
try {
FileInputStream file = null ;
OutputStream out = null;
file = new FileInputStream("/Users/xxxxx/video.mp4");
int sizi = file.available();
byte[] data = new byte[sizi];
file.read(data);
file.close();
String re_range = re.getHeader("range");
//chrome里每次这个range都是0-到所有,一次性获取所有的文件流;在safari里这个range第一次是0-1,后面是分段获取,所以这里根据request的range的分段,再组装一个content-range放入到response里去;这里代码只适配了safari,如需适配chrome,请加判断,走chrome流程
String sub_range = re_range.substring(6);
String[] strs = sub_range.split("-");
String range = "bytes "+sub_range+"/"+data.length;
resp.addHeader("content-range",range);
resp.setContentType("video/mp4");
int contentLength = Integer.parseInt(strs[1])-Integer.parseInt(strs[0])+1;
System.out.println("实际长度 = "+contentLength);
resp.setContentLength(contentLength);
out = resp.getOutputStream();
//视频流写的大小,是这次获取的视频流从那个字节位置和这次请求的数据的长度;但是在本地请求一次性获取了所有数据成功了.如果服务部署在服务器上,这时候有一个中间请求全部文件会失败,然后进行了分段获取会成功,至于为什么中间有一次请求会失败(原因未知)
out.write(data,Integer.parseInt(strs[0]),contentLength);
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
return ;
}
提醒
我在这里主要遇到两个问题:
1.一开始不清楚chrome和safari对video和audio标签对视频流的分段获取规则不一样,导致content-range配置的不对.
2.out.write()的时候也根据当前流分段位置,从那到那将数据写入response里,如果写乱了,可能导致播放的时候音频视频顺序错乱.
问题
1.本地服务器是一次性获取,分段的少
2.部署到服务器上(分段获取,中间有一段会失败)
虽然有一段获取失败了,但是播放是正常的,为啥这一段失败原因没有继续深究了,如有谁知道,也请不吝赐教.