This may be a long post so please bear with me as I am looking for an instructed type response to learn the concept in order to solve my issue. I have the responsibility of creating a video playback feature in html5 using chrome that involves a very large software package that includes a jetty server. The basic use case is a user has a list of videos to playback that includes an audio file separately. Once the user clicks on the playback button it creates a pop up window for playback with a chrome video and audio control.
The backend request is sent to a servelet that makes two separate requests (video & audio) then sends the requests synchronously to a dataserver which downloads the file and audio streams and transmits the response back to the servlet and then to the client (pop up window) for playback.
I figured how to do this but since chrome does not allow seek feature, I have to redo this to allow the seek feature in order to be able to eventually synch the audio and video when a user moves the video control forward or backward.
I did some research and found that I needed to send the Content-Length, Accept-Range and Content-Range headers in the response as well as a 206 status response. Amazingly this seemed to work for small videos. I tried testing with larger videos and found that after a while probably after mid way through the following error occurs:
HTML Code:
net::ERR_CONTENT_LENGTH_MISMATCH
I used the following code to determine the content-range bytes for both audio and video and for the first half it works fine, seeking forward and back but then fails in the later part.
String range =parameters.get("Range").toString();
String[] ranges = range.split("=")[1].split("-");
final int from = Integer.parseInt(ranges[0]);
if(parameters.containsKey("Content-Length")) {
int sLength = (int) parameters.get("Content-Length");
int to = 1025 + from;
if (to >= sLength) {
to = (int) (sLength - 1);
}
if (ranges.length == 2) {
to = Integer.parseInt(ranges[1]);
}
final String responseRange = String.format("bytes %d-%d/%d", from, to, sLength);
I did all this with the simple understanding that whatever handles the response will send the byte ranges, thinking the jetty web service handles all this somehow. With no documentation I have to figure out the code, determine what works where with no assistance as the people here roll their eyes when I ask basic questions. Yes, I do not know much about the theoretical parts of development ( I should!) but I code a solution based on existing stuff done out there. Which I know I will get slack for that too but yes I am a copy and paste programmer starting late in life.
InputStream is= null;
is = new FileInputStream(ndirectory + "\\" + this.videoID.toString() + ".webm");
return is;
This inputstream goes through a bunch of other classes before being sent to the servlet or client. Now do I change it as follows and it works the same? Or how will the dataserver send the partial stream instead of the full stream as it does now:
OutputStream output;
byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
int read;
if (input.length() == length) {
// Write full range.
while ((read = input.read(buffer)) > 0) {
output.write(buffer, 0, read);
}
} else {
// Write partial range.
input.seek(start);
long toRead = length;
while ((read = input.read(buffer)) > 0) {
if ((toRead -= read) > 0) {
output.write(buffer, 0, read);
} else {
output.write(buffer, 0, (int) toRead + read);
break;
}
}
}
My question is whether and how I am supposed to transmit the stream as partial bytes rather then send the full stream as I do now? Will that resolve my issue or is this error above not related. My understanding was basically interpreted on how firefox handled the playback with no issues and came to the conclusion, that I should not have to do much code changes to get it to work in chrome, but I guess I have to. Firefox downloads the entire file or stream first I was told.
Please advise and perhaps confirm or argue my understanding on how this works. Any links or documentation would be helpful too. Thanks