Video Stream over HTTP using Spring Boot
Have done a POC to stream video over the http and hard to find the details about the HTTP streaming using JAVA. So thought to share this details. This is pretty much playing around the HTTP headers and the HTTP status code. Described the headers in details which is widely used to stream the video.
Request Headers
Range
Range header is requested by the client that range of response data is needed by the client. In the below example client is requesting the response data from the 0 to 2000 bytes.
E.g Range: bytes=0–2000.
Response Headers
Accept-Ranges
Accept Ranges header to mention the type of data and ranges going to receive by the client.
E.g Accept-Ranges: bytes
Content-Range
Content range header tells the client that range of bytes that server sending out to the client.
E.g Content-Range: bytes 0–2000/2001
Content-Type
Content type is most widely used headers, reiterating that this header is to specify the what is the type of response. In the below example the response object will be like video mp4 format.
E.g Content-Type: video/mp4
Content-Length
Content Length specifies that total length response data is sending from server to client. In the below example total response content length is 2000 bytes.
Content-Length: 2000
After we discussed all about the headers would like to share the details about the HTTP status code. There is status code is used 200 and 206. All we know that 200 is OK but 206 is the Partial content. 206 status widely used when client requesting for the Range(partial) of content to the server.
Theoretical part is over let’s go the some practical. Thinking that readers have some basic understanding of the Spring Boot.
if (range == null) {
return ResponseEntity.status(HttpStatus.OK)
.header("Content-Type", "video/" + fileType)
.header("Content-Length", String.valueOf(fileSize - 1))
.body(readByteRange(fullFileName, rangeStart,fileSize)); // Read the object and convert it as bytes
}
When the Range header is NULL read the full response video as bytes and attach with the body
public byte[] readByteRange(String filename, long start, long end) throws IOException {
FileInputStream inputStream = new FileInputStream(VIDEO_PATH + filename);
ByteArrayOutputStream bufferedOutputStream = new ByteArrayOutputStream();
byte[] data = new byte[1024];
int nRead;
while ((nRead = inputStream.read(data, 0, data.length)) != -1) {
bufferedOutputStream.write(data, 0, nRead);
}
bufferedOutputStream.flush();
byte[] result = new byte[(int) (end - start)];
System.arraycopy(bufferedOutputStream.toByteArray(), (int) start, result, 0, (int) (end - start));
return result;
}
Above method is to read the video file as the byte array.
If the range is coming from the client read the data from the video byte array according the range header.
Full source code in the below github:
https://github.com/saravanastar/video-streaming
Here is the screenshot of the video playing