Provided that I have a video HTTP stream broadcasted on a server that is on the same network as my Spring Webserver is, for instance in some url such as:
http://localhost:9090/httpstream
How can I proxy this video stream to any amount of clients, using Spring? The following example demonstrates the wanted flow:
This is needed because the HTTPStream is an unsecured and not authenticated host, and I wanted to wrap it around a Spring Webserver
, so that I could use some form of Security, such as a Basic Auth
.
I tried requesting some form of mapping, but I couldn't find what kind of object to return, nor how to make the connection, but the expected behaviour should be something like this:
@Controller
public class HttpStreamProxyController {
@RequestMapping("/spring") {
public /*Stream Object?*/ getSecuredHttpStream() {
if (clientIsSecured) {
//... Security information
return //What should be returned?
}
}
}
I am not sure what kind of source you are using for generating your video stream (live camera or a video file or youtube video or ..)
You can probably use StreamingResponseBody (requires Spring 4.2+). Refer following links
http://www.logicbig.com/tutorials/spring-framework/spring-web-mvc/streaming-response-body/
http://shazsterblog.blogspot.in/2016/02/asynchronous-streaming-request.html
Try this -
@GetMapping("/stream1")
@ResponseBody
public StreamingResponseBody getVidoeStream1(@RequestParam String any) throws IOException {
/* do security check before connecting to stream hosting server */
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<Resource> responseEntity = restTemplate.exchange( "http://localhost:8080/stream", HttpMethod.GET, null, Resource.class );
InputStream st = responseEntity.getBody().getInputStream();
return (os) -> {
readAndWrite(st, os);
};
}
private void readAndWrite(final InputStream is, OutputStream os)
throws IOException {
byte[] data = new byte[2048];
int read = 0;
while ((read = is.read(data)) > 0) {
os.write(data, 0, read);
}
os.flush();
}
It should work. You can write your own implementation of readAndWrite() depending on your requirements.
So, your spring proxy controller could be something like this...
@Controller
public class HttpStreamProxyController {
@RequestMapping("/spring")
@ResponseBody
public StreamingResponseBody getSecuredHttpStream() {
if (clientIsSecured) {
//... Security information
RestTemplate restTemplate = new RestTemplate();
// get video stream by connecting to stream hosting server like this
ResponseEntity<Resource> responseEntity = restTemplate.exchange( "https://ur-to-stream", HttpMethod.GET, null, Resource.class );
InputStream st = responseEntity.getBody().getInputStream();
// Or if there is any other preferred way of getting the video stream use that. The idea is to get the video input stream
// now return a StreamingResponseBody object created by following lambda
return (os) -> {
readAndWrite(st, os);
};
} else {
return null;
}
}
}
The StreamingResponseBody returned by your rest endpoint will work fine with HTML5, which could be something like ..
<video width="320" height="240" controls>
<source src="/spring" type="video/mp4">
Your browser does not support the video tag
</video>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With