iPhone Safari上的付费视频
我们有定制的web应用程序,并提供视频内容。我们已经成功地在网络浏览器上播放视频内容,但没有在iPhone Safari、谷歌和Firefox浏览器上 我收到的意见是,媒体服务器需要支持内容范围。所以在这个问题上,我们创建了定制的SpringRESTAPI,并将视频内容下载到输入流中。我们正在检查,如果请求来自iPhone设备,则发送部分内容响应 @RequestMapping(value=“{key}”,method=RequestMethod.GET) @应答器 public final ResponseEntity retrieveResource(@PathVariable(value=“key”)final字符串键, @RequestHeader(value=“Range”,required=false)字符串范围, @RequestHeader(value=PortalParam.USER\u AGENT,required=false)字符串userAgent)引发异常{ log.info(“范围\t”+范围); log.info(“用户代理\t”+用户代理)iPhone Safari上的付费视频,iphone,safari,video-streaming,spring-rest,Iphone,Safari,Video Streaming,Spring Rest,我们有定制的web应用程序,并提供视频内容。我们已经成功地在网络浏览器上播放视频内容,但没有在iPhone Safari、谷歌和Firefox浏览器上 我收到的意见是,媒体服务器需要支持内容范围。所以在这个问题上,我们创建了定制的SpringRESTAPI,并将视频内容下载到输入流中。我们正在检查,如果请求来自iPhone设备,则发送部分内容响应 @RequestMapping(value=“{key}”,method=RequestMethod.GET) @应答器 public final R
long-rangeStart=0L;
长程端=0升;
HttpHeaders=新的HttpHeaders();
headers.set(“Expires”、“0”);
set(“缓存控制”、“无缓存、无存储”);
headers.set(“连接”、“保持活动”);
headers.set(HttpHeaders.ACCEPT_范围,“字节”);
headers.set(“内容传输编码”、“二进制”);
//.openStream();
URL myURL=新URL(“我的URL”);
HttpURLConnection myURLConnection=(HttpURLConnection)myURL.openConnection();
long contentLength=myURLConnection.getContentLength();
InputStream InputStream=myURLConnection.getInputStream();
if(范围!=null&(userAgent.indexOf(“iPhone”)!=-1 | | userAgent.indexOf(“curl”)!=-1)){
ByteArrayOutputStream输出=新建ByteArrayOutputStream();
ByteArrayInputStream inStream=null;
字符串rangeValue=range.trim().substring(“bytes=.length());
字符串myvideo=key.replaceAll(“.mp4”,”)+“”+新的随机字符串(12.nextString();
字符串outputFile=PortalParam.getRandomAccessFile()+PortalParam.SLASH+myvideo+“.part”;
myvideo=myvideo+“.mp4”;
漫长的开始,漫长的结束;
if(rangeValue.startsWith(“-”){
end=contentLength-1;
start=contentLength-1-Long.parseLong(rangeValue.substring(“-”.length());
}否则{
字符串[]myrange=rangeValue.split(“-”);
start=Long.parseLong(myrange[0]);
end=myrange.length>1?Long.parseLong(myrange[1]):contentLength-1;
}
如果(结束>内容长度-1){
end=contentLength-1;
}
if(开始0)&(totalRead
curl请求提供以下输出
curl-k——范围0-99-o/dev/null
%总接收百分比%x平均速度时间电流
数据加载上载总左速度
100 100 0 0 237 0--:::::::::::::::--243
旋度-k——范围0-99
给予
HTTP/1.1 206部分内容
日期:2019年9月4日星期三16:37:46 GMT
服务器:Apache
X-Frame-Options:SAMEORIGIN
过期日期:0
内容传输编码:二进制
缓存控制:无缓存,无存储
接受范围:字节
内容范围:字节0-99/100
内容类型:视频/mp4
内容长度:100
这是我们从服务器访问时得到的响应
2019-09-04 16:38:33信息视频流:77-用户代理Mozilla/5.0(iPhone;CPU iPhone OS 12_4,如Mac OS X)AppleWebKit/605.1.15(KHTML,如Gecko)版本/12.1.2 Mobile/15E148 Safari/604.1
2019-09-04 16:38:33信息视频流:136-内容长度2
2019-09-04 16:38:33信息视频流:138-缓冲区读取2
2019-09-04 16:38:33信息视频流:140-总读取量2
2019-09-04 16:38:33信息视频流:143-总计读取2
2019-09-04 16:38:33信息视频流:159-标题[过期:“0”,缓存控制:“无缓存,无存储”,连接:“保持活动”,接受范围:“字节”,内容传输编码:“二进制”,内容长度:“2”,内容范围:“字节0-1/2”,内容类型:“视频/mp4”]
仍然无法在iPhone Safari上渲染视频。非常感谢您的帮助。内容范围中斜杠后的值应该是对象的大小,而不是范围的大小谢谢@szatmary并更正了此问题。我们正在获取视频的长度,但没有音频和视频
long rangeStart = 0L;
long rangeEnd = 0L;
HttpHeaders headers = new HttpHeaders();
headers.set("Expires", "0");
headers.set("Cache-Control", "no-cache, no-store");
headers.set("Connection", "keep-alive");
headers.set(HttpHeaders.ACCEPT_RANGES, "bytes");
headers.set("Content-Transfer-Encoding", "binary");
// .openStream();
URL myURL = new URL("my URL");
HttpURLConnection myURLConnection = (HttpURLConnection) myURL.openConnection();
long contentLength = myURLConnection.getContentLength();
InputStream inputStream = myURLConnection.getInputStream();
if (range != null && (userAgent.indexOf("iPhone") != -1 || userAgent.indexOf("curl") != -1 )) {
ByteArrayOutputStream output = new ByteArrayOutputStream();
ByteArrayInputStream inStream = null;
String rangeValue = range.trim().substring("bytes=".length());
String myvideo = key.replaceAll(".mp4", "") + "_" + new RandomString(12).nextString();
String outputFile = PortalParam.getRandomAccessFile() + PortalParam.SLASH + myvideo + ".part";
myvideo = myvideo + ".mp4";
long start, end;
if (rangeValue.startsWith("-")) {
end = contentLength - 1;
start = contentLength - 1 - Long.parseLong(rangeValue.substring("-".length()));
} else {
String[] myrange = rangeValue.split("-");
start = Long.parseLong(myrange[0]);
end = myrange.length > 1 ? Long.parseLong(myrange[1]) : contentLength - 1;
}
if (end > contentLength - 1) {
end = contentLength - 1;
}
if (start <= end) {
contentLength = end - start + 1;
headers.set(HttpHeaders.CONTENT_LENGTH, contentLength + "");
headers.set(HttpHeaders.CONTENT_RANGE, "bytes " + start + "-" + end + "/" + contentLength);
headers.set(HttpHeaders.CONTENT_TYPE, "video/mp4");
// headers.set(HttpHeaders.CONTENT_DISPOSITION, "inline; filename=" + myvideo);
byte[] buffer = new byte[1024*8];
int bytesRead = 0;
int totalRead = 0;
log.info("Content Length \t" + contentLength);
while (((bytesRead = inputStream.read(buffer, (int)start, (int)contentLength)) > 0) && (totalRead < contentLength)) {
log.info("BUffer Read \t" + bytesRead);
totalRead = totalRead + bytesRead;
log.info("Total Read \t" + totalRead);
output.write(buffer, 0, bytesRead);
}
log.info("Total Read \t" + totalRead);
//inStream = new ByteArrayInputStream(output.toByteArray());
}
headers.setContentType(MediaType.valueOf("video/mp4"));
log.info("Headers \t" + headers.toString());
InputStream myStream = new ByteArrayInputStream(output.toByteArray());
return new ResponseEntity<>(new InputStreamResource(myStream), headers, HttpStatus.PARTIAL_CONTENT);
} else {
log.info("Headers \t" + headers.toString());
headers.setContentType(MediaType.valueOf("video/mp4"));
return new ResponseEntity<>(new InputStreamResource(inputStream), headers, HttpStatus.OK);
}
}