问题描述
在我们的Java EE应用程序中,我们使用HTML5 <video>
标签来播放MP4视频。
我们使用JBoss 7作为应用程序服务器。
通过Struts2操作检索视频,如下所示: www.myproject.com/namespace/documents/3/zbRdTKQKLWnA2ZiY61Gx
其中zbRdTKQKLWnA2ZiY61Gx
是服务器上的视频名称。
struts.xml:
...
<action name="documents/*/*" class="namespace.action.GestionDocumentAction" method="obtain">
<param name="typeId">{1}</param>
<param name="identifiantDocument">{2}</param>
<result name="success" type="stream">
<param name="contentType">video/mp4</param>
<param name="inputName">flux</param>
<param name="allowCaching">true</param>
<param name="contentDisposition">inline;filename=${filename}</param>
</result>
</action>
...
它适用于Chrome和Firefox ,但不适用于Mac上的Safari 。
在Safari中,当我打开包含<video>
标记的页面时,会显示“正在加载”,但它不会加载视频。
这真是奇怪的事情 。
如果直接在浏览器中将链接粘贴到视频,则会正确播放。 然后,如果我用所述视频重新加载页面,它就可以正常播放。
应用程序中的所有视频都会发生同样的情况。
怎么了 ? 为什么视频最初没有播放?
Safari中的开发工具:
当我最初加载页面时,我得到以下结果:
所有警告都是针对CSS的。
为了第一次直接在浏览器中打开文件,我得到:
错误是“无法加载资源:模块负载处理”:
当我重新加载页面时,我得到相同的响应 ,但现在我可以播放视频:
我认为问题来自范围标题。 其实我用这个:
this.getServletResponse().setHeader("Accept-Ranges", "bytes");
this.getServletResponse().setHeader("Content-Type", "video/mp4");
this.getServletResponse().setHeader("Content-Length", "383631"); // 383631 - just for exemple, I use a real size
this.getServletResponse().setHeader("Content-Range", "bytes 0-383630/383631"); // 0-383630/383631 - the same
this.getServletResponse().setStatus(206);
1楼
如果请求的视频资源没有特别具有扩展名.mp4 ,即使正确设置了mime类型,Safari也存在问题。
我可以复制你的问题 - 如果视频资源只是一个字符串标识符(没有.mp4
),Safari会显示视频的预览,但它实际上不会播放。
当资源重命名为filename.mp4
,Safari开始按预期播放视频。
Chrome无论如何都能正常运行。
如果更改了namespace.action.GestionDocumentAction
类,那么当第二个参数以.mp4
结尾时,它会剥离扩展名以找到正确命名的本地资源,它应该能够返回带有以.mp4结尾的URL的视频Safari期望 - www.myproject.com/namespace/documents/3/zbRdTKQKLWnA2ZiY61Gx.mp4
。