Spring Boot serving an m3u8 playlist - java

I'm trying to serve an m3u8 playlist through Spring Boot. I have a running ffmpeg process that is transcoding a multicast in real-time and sending the files to /src/resources/public/output.m3u8. I see the playlist updating and the new .ts files being generated correctly however when trying to watch the stream in a video player, it only plays a certain amount of video. Is there a way to properly serve up a running playlist in Java instead of serving it statically?
EDIT: When starting a basic http server with python python3 -m http.server, I'm able to view the stream perfectly fine. Is there a Spring Boot way to accomplish the same task?

With Spring 4.1 your approach will work there is no issue in it. Here below is another approach in case if you want to look
#RequestMapping(value = "/VMS-49001/playlist/{listName:.+}")
public ResponseEntity<byte[]> testphoto() throws IOException {
InputStream in = servletContext.getResourceAsStream("/images/no_image.jpg");
final HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.parseMediaType("application/vnd.apple.mpegurl"));
headers.setContentDispositionFormData(fileName, fileName);
return new ResponseEntity<byte[]>(IOUtils.toByteArray(in), headers, HttpStatus.CREATED);
}

Related

Spring Boot Multipart File Upload - Tips to Improve Performance

I am exposing RESTful API to the reactjs front end application which is used to upload a file to Database.
Server Side Controller Code:
#RequestMapping(value = "/api/upload", method = RequestMethod.POST, consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public UploadResponse uploadDocument(#RequestParam("doc") MultipartFile doc,
#RequestParam("metaData") String metaData, HttpServletResponse response) {
// logic to save in DB
return new UploadResponse();
}
Client Side JS Code:
uploadDocument(formData, callback) {
instance.post('/api/upload', formData)
.then((response) => {
callback(response);
})
.catch((error) => {
const errorObj = {
status: error.response.status,
data: {
message: error.response.data.message,
},
};
callback(errorObj);
});
}
application.properties
spring.http.multipart.max-file-size=20MB
spring.http.multipart.max-request-size=20MB
I am trying to upload a 20MB file (CSV or any other) , it is taking too much time to reach the controller side. (~ 1-2 minutes )
Please suggest some good techiniques or tips to improve the performance using same multipart request.
(ex: Chunking or Compressing or Streaming)
I think the easiest way would be to just zip content at javascript side and upload it to you spring boot application.
react js parts: please read upload zip file from reactjs to nodejs
spring boot multipart octet stream handling - necessary classes, test mocks etc. are described at How to go from spring mvc multipartfile into zipinputstream
Using this you should be able to zip content at react side and use it at your spring application.
Or you just zip at react side and upload the file in a normal way without any special octet stream handling in spring boot but just using java zip package classes to unzip files.

Stream content from external http resource

I am trying to use my spring boot application as a proxy for certain image or video content hosted externally.
#GetMapping("/video.mp4")
public ResponseEntity<Resource> getVideo(#PathVariable String filename) {
HttpHeaders headers = getHttpHeaders(filename);
ResponseEntity<Resource> exchange = restTemplate.exchange("https://sample-videos.com/video123/mp4/720/big_buck_bunny_720p_30mb.mp4", HttpMethod.GET, entity, Resource.class);
return ResponseEntity.ok().headers(headers).body(exchange.getBody());
}
I want to stream the content from the external resource to the client without downloading it first. My sample code above seems to first download the full content in to memory and then serves it.
How can I proxy the content directly without downloading it first?

Java Spark REST api upload file

I'm working with java using java-spark to create the Rest Api and I'm having trouble figuring out how to receive a file so then I can process it. Haven't found anything as like in Spring that handles MultipartFile. Also this proyect is ran on a Tomcat server.
As per the official documentation, the following code you get you started:
post("/yourUploadPath", (request, response) -> {
request.attribute("org.eclipse.jetty.multipartConfig", new MultipartConfigElement("/temp"));
try (InputStream is = request.raw().getPart("uploaded_file").getInputStream()) {
// Use the input stream to create a file
}
return "File uploaded";
});

Deserialize Google Web Kit Response (Java) and Java Servlets

I have a monolithic legacy application that I need to read and submit data to. It's using Google Web Kit and Java Servlets.
I have access to the source code, but I'm new to both Servlets and GWT.
I'm trying to encapsulate a rest client in my project that can communicate with GET/POST rest calls to the legacy server.
I've been able to send a POST request using Postman, and then used Reactive Spring 5.0 framework to sending that request.
When I try to deserialize the response, I'm running into a ton of errors.
How would I deserialize this payload?
7|0|7|http://localhost:8080/testproject/
|29F4EA1240F157649C12466F01F46F60|
com.test.client.GreetingService|greetServer|java.lang.String|
myInput1|myInput2|1|2|3|4|2|5|5|6|7|
I've searched all day, and followed a few blogs like these:
https://docs.google.com/document/d/1eG0YocsYYbNAtivkLtcaiEE5IOF5u4LUol8-LL0TIKU/edit#
https://blog.gdssecurity.com/labs/2009/10/8/gwt-rpc-in-a-nutshell.html
I'm not sure code wise how I can serialize them into my own object for my new service.
static WebClient webClient = WebClient.create();
public static void main(String[] args) {
Mono<String> body = Mono.just("7|0|7|http://localhost:8080/testproject/|29F4EA1240F157649C12466F01F46F60|com.test.client.GreetingService|greetServer|java.lang.String|myInput1|myInput2|1|2|3|4|2|5|5|6|7|");
Mono<String> response = webClient.post()
.uri("http://localhost:8080/testproject/")
.header("Content-Type", "text/x-gwt-rpc;charset=UTF-8")
.header("X-GWT-Module-Base", "http://localhost:8080/testproject/")
.header("X-GWT-Permutation", "29F4EA1240F157649C12466F01F46F60")
.cookie("JSESSIONID", "2BCEBF12GE2C3A0335F5012812A73638")
.body(body, String.class)
.retrieve()
.bodyToMono(String.class);
String unBlocked = response.block();
System.out.println(unBlocked);
//OK[1,1,["java.lang.Integer/3438228391"],0,2]
try {
ServerSerializationStreamReader streamReader = new ServerSerializationStreamReader(
Thread.currentThread().getContextClassLoader(), null);
streamReader.prepareToRead(unBlocked);
System.out.println(streamReader.readObject());
} catch ( Exception e) {
e.printStackTrace();
}
}
Error:
com.google.gwt.user.client.rpc.IncompatibleRemoteServiceException: This application is out of date, please click the refresh button on your browser. ( Malformed or old RPC message received - expecting version between 5 and 7 )
I've tried every version of GWT because of the malformed RCP message.
Also, I tried to stick it into a string, which I'm sure is failing on its own.
You are trying to decode the server response with the code meant decode the client request. At present they use a different format for historical reasons - note how the response starts with "//OK", but the request has the version/flags/stringcount "7|0|7" beginning.
In at least a small part this is because when a client calls a server, it needs to describe what version it is speaking and where the server should find the file listing the set of classes that the client expects are allowed to be serialized. When the server responds, since the client already told it about the typed that can be serialized, it doesn't need to tell the client the same thing again.
Reading the com.google.gwt.user.client.rpc.impl.ClientSerializationStreamReader class and its docs will show the response format and how it can be decoded into objects. There is presently no server-side code that I'm aware of that is intended to do this job, but could probably be written with fairly little difficulty, just some persistence.

Return video with Javax Rest Api

I'm working on android app and back-end server Rest API part.
I'm at the point where i need to return some video files from the server back to my android device. How can i do that?
I looked up jersey documantation https://jersey.java.net/documentation/1.19/jax-rs.html#d4e142
and http://www.vogella.com/tutorials/REST/article.html#restjersey_annotations
but din't have any luck figuring this out..
For images i've been using the
#Produces(image/jpg)
Is there a similar way i can do to share mpeg4 or any other video files?
What would be the best approach there?
As android client can stream the video content, try something like this
#GET
#Path("video")
#Produces(MediaType.APPLICATION_OCTET_STREAM)
public Response video() {
File file = new File("C:/Data/video.mp4");
return Response.ok(file, MediaType.APPLICATION_OCTET_STREAM)
.build();
}

Categories