You are looking for stream video over Http and hard to find how to stream over Http using java. This is pretty much playing with the header and all about status code. Here @RequestHeader is responsible for playing video over Http.
@RequestHeader(value = "Range", required = false) String httpRangeList
Range
The range header is requested by the client that the range of response data requested by the client. The client requests up to a certain range starting with 0. For example: Range 0 – 400000.
Lets start using spring boot
Create a simple spring boot application using start.spring.io or you can simply create a maven project.
Please add the following dependancy
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
Now create a simple controller class and add the following
package com.stream.controller;
import java.io.File;
import java.io.IOException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.support.ResourceRegion;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RestController;
import com.stream.service.VideoStreamingService;
@RestController
public class VideoStreamController {
@Autowired
VideoStreamingService service;
public static final String VideoUploadingDir = System.getProperty("user.dir") + "/Uploads/Posts/Videos";
@GetMapping(value = "/video", produces = "application/octet-stream")
public ResponseEntity<ResourceRegion> getVideo(@RequestHeader(value = "Range", required = false) String rangeHeader)
throws IOException {
if (!new File(VideoUploadingDir).exists()) {
new File(VideoUploadingDir).mkdirs();
}
return service.getVideoRegion(rangeHeader, VideoUploadingDir);
}
}
Accept-Range
Accept-Range header defines the type of data and range going to received by the client. Ex. Accept-Range = byte.
Content Range
Content-Range state the client that the range of byte that the server serve to the client.
Content-Type
This is the most important header that defines the type of the response.For the particular example the content-type is video/mp4
Lets create a service class for reading the file as byte
package com.stream.service;
import static java.lang.Math.min;
import java.io.IOException;
import org.apache.commons.lang3.StringUtils;
import org.springframework.core.io.FileUrlResource;
import org.springframework.core.io.UrlResource;
import org.springframework.core.io.support.ResourceRegion;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.MediaTypeFactory;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
@Service
public class VideoStreamingService {
private static final long CHUNK_SIZE = 1000000L;
public ResponseEntity<ResourceRegion> getVideoRegion(String rangeHeader ,String directory) throws IOException {
FileUrlResource videoResource = new FileUrlResource(directory + "/video.mp4");
ResourceRegion resourceRegion = getResourceRegion(videoResource, rangeHeader);
return ResponseEntity.status(HttpStatus.PARTIAL_CONTENT)
.contentType(MediaTypeFactory.getMediaType(videoResource).orElse(MediaType.APPLICATION_OCTET_STREAM))
.body(resourceRegion);
}
private ResourceRegion getResourceRegion(UrlResource video, String httpHeaders) throws IOException {
ResourceRegion resourceRegion = null;
long contentLength = video.contentLength();
int fromRange = 0;
int toRange = 0;
if (StringUtils.isNotBlank(httpHeaders)) {
String[] ranges = httpHeaders.substring("bytes=".length()).split("-");
fromRange = Integer.valueOf(ranges[0]);
if (ranges.length > 1) {
toRange = Integer.valueOf(ranges[1]);
} else {
toRange = (int) (contentLength - 1);
}
}
if (fromRange > 0) {
long rangeLength = min(CHUNK_SIZE, toRange - fromRange + 1);
resourceRegion = new ResourceRegion(video, fromRange, rangeLength);
} else {
long rangeLength = min(CHUNK_SIZE, contentLength);
resourceRegion = new ResourceRegion(video, 0, rangeLength);
}
return resourceRegion;
}
}
Content Length
It specify that the total amount of byte should transfer by the server to the client.
Status Code
Here in this example, the most important work is done by the status code. As we all know about the 200 status code i.e OK but here we use status code 206 which is called PARTIAL CONTENT. 206 status code widely used when we are requesting for header range on the server.

You can simply run the project and type http://localhost:8080/video on browser.
You can find the details of the code on git here
Thanks for visiting us.