Rumah > Soal Jawab > teks badan
有一问题求助各位大神,希望能提供解决思路!谢谢!
问题现象:
最近做的一个视频播放功能,前台使用的video.js播放框架播放mp4视频,后台使用java写的servlet接收请求的MP4文件名等参数,经过处理后读取播放本地的视频文件。经过验证后发现如果使用chrome,firefox等浏览器访问都没有问题,前台都可以播放,但是使用safari浏览器会读取文件失败,报文件不存在或网络链接有问题。包括使用ios和mac的safari都不行。初步认为和safari的版本无关。其中的servlet的处理主要就是获取本地mp4文件的fileinputstream,然后赋值给outputstream然后再response输出。
但是当我把视频源地址换成如http://xxx.com/yy.mp4格式的地址时,是可以直接播放的。
简单说,就是用safari的html5的video标签引用需要通过servlet处理的视频源,是无法播放对应视频的。
问题分析过程:
期间经过调试,网上搜索,貌似能查到的类似问题不太多。目前调试时,后台会报这个错,期间获取的range的值为“range="bytes=0-1"; 尝试过修改为chrome访问时的数据段的值继续执行还是不行。感觉是浏览器关闭了进程,服务器无法返回数据。但不知如何解决。
ClientAbortException: java.net.SocketException: Software caused connection abort: socket write error
at org.apache.catalina.connector.OutputBuffer.realWriteBytes(OutputBuffer.java:388)
最后附上后台处理代码:
String localPath = "/";
boolean isError = false;
String fileName = request.getParameter("videopath");
String strPath = localPath + fileName;
String suffix = "";
if (strPath.lastIndexOf(".") != -1) {
suffix = strPath.substring(strPath.lastIndexOf(".") + 1);
}
BufferedInputStream is = null;
try {
fiStream = new FileInputStream(inFile);
} catch (IOException e) {
log.warn(strPath + " " + e.getMessage());
}
final long fileLen = fiStream.available();
String range=request.getHeader("Range");
response.setHeader("Accept-Ranges","bytes");
OutputStream out=response.getOutputStream();
if(range==null)
{
range="bytes=0-";
}
long start=Integer.valueOf(range.substring(range.indexOf("=")+1, range.indexOf("-")));
long count=fileLen-start;
long end;
if(range.endsWith("-"))
end=fileLen-1;
else
end=Integer.valueOf(range.substring(range.indexOf("-")+1));
String ContentRange="bytes "+String.valueOf(start)+"-"+end+"/"+String.valueOf(fileLen);
response.setStatus(206);
response.setContentType("video/mpeg4");
response.setHeader("Content-Range",ContentRange);
byte[] buffer = new byte[1024*10];
int length=0;
fiStream.skip(start);
try{
while((length=fiStream.read(buffer))!=-1)
{
out.write(buffer,0,length);
}
}
catch(Exception e)
{
log.debug("failed to read.",e);
}
fiStream.close();
fiStream = null;
out.close();
out = null;