We have an MP4 video on our site; it plays fine in IE9+, Firefox, Chrome, and Chrome on mac. However, on Safari, the video doesn\'t play at all - it does trigger a \"stalled
Safari and iPhone require the "Range" request header to play your media content. you have to handle Range on the server-side.
if (request.getHeader("Range") != null) {
System.out.println("Inside range ");
System.out.println("range value "+request.getHeader("range"));
// String fileLocation = melpUploadFiles.getFilethumbPath();
resfilename=melpUploadFiles.getFilename();
response.setStatus(206);
String rangeValue = request.getHeader("range").trim().substring("bytes=".length());
File fileloc= new File(melpUploadFiles.getFilePath());
long fileLength = fileloc.length();
long start, end;
if (rangeValue.startsWith("-")) {
end = fileLength - 1;
start = fileLength - 1 - Long.parseLong(rangeValue.substring("-".length()));
} else {
String[] range = rangeValue.split("-");
start = Long.parseLong(range[0]);
end = range.length > 1 ? Long.parseLong(range[1]) : fileLength - 1;
}
if (end > fileLength - 1) {
end = fileLength - 1;
}
if (start <= end) {
System.out.println("inside response block");
long contentLength = end - start + 1;
response.setHeader("Content-Length", contentLength + "");
response.setHeader("Content-Range", "bytes " + start + "-" + end + "/" + fileLength);
response.setHeader("Content-Type", "video/mp4");
response.setHeader("Accept-Ranges","bytes");
response.setHeader("ETag","\"a226e70476837efa4df4b4bfd75366c4\"");
response.setHeader("Server", "Apache");
response.setHeader("Last-Modified",System.currentTimeMillis()+"");
response.setDateHeader("Expires", System.currentTimeMillis() + 604800000L);
// response.setHeader("Content-Disposition", "inline; filename="+resfilename+"");
RandomAccessFile raf = new RandomAccessFile(fileloc, "r");
raf.seek(start);
output = response.getOutputStream();
byte[] buffer = new byte[2096];
int bytesRead = 0;
long totalRead = 0;
System.out.println("content length "+contentLength);
while(totalRead<contentLength) {
bytesRead = raf.read(buffer);
totalRead += bytesRead;
output.write(buffer, 0, bytesRead);
}
}
}
else { for other browser }
What happens if you add these to your .htaccess
?
AddType video/ogg .ogv
AddType video/mp4 .mp4
AddType video/webm .webm
Make sure controls='true' type='video/mp4' is given in your html code.
<video loop controls='true' width='100%' height='100%' src='//some_video.mp4' type='video/mp4'></video>
I ran into the same problem and solved it but no other answer here is not involved to mine, so I'll remain the solution here for someone following.
I've been making my own video streaming server, which, in the questioned case, simply returns a "Ranged" mp4 file, and I found Safari does not play video carried in HTTP response lacking of "Connection" response header for some reason.
Recently, my team ran into a particular issue that resulted in the same behavior. We were using Apache 2.4 and noticed that if we had an authentication layer such as .htpasswd enabled, Safari would not display videos at all even after authenticating. It's almost as if it does not continue to honor the initial authentication clearance for certain types of subsequent HTTP requests.
Sorry I don't have anything more technical to provide, but it's something to check for anyone experiencing video issues only in Safari.
Safari requires webserver to support "Range" request header in order to play your media content.
https://developer.apple.com/library/safari/documentation/AppleApplications/Reference/SafariWebContent/CreatingVideoforSafarioniPhone/CreatingVideoforSafarioniPhone.html#//apple_ref/doc/uid/TP40006514-SW6
For a legit "Range" request response, your webserve need to return status code "206".