使用safari读取通过servlet返回的MP4视频文件报错

发布于 2022-09-03 12:37:58 字数 3628 浏览 10 评论 0

有一问题求助各位大神,希望能提供解决思路!谢谢!
问题现象:
最近做的一个视频播放功能,前台使用的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; 

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

短暂陪伴 2022-09-10 12:37:58

直接注释掉访问资源的servlet,将要访问的资源直接配置成静态资源
方法如下在tomcat中配置web.xml文件加入
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.mp4</url-pattern>
</servlet-mapping>
后直接html5的video标签访问视频文件的url地址即可!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文