0

I have a method which accepts a file in form of InputStream and returns this InputStream back to the user. When a user saves the video file back from the InputStream the video file cannot be played. The method which receives and returns the file looks like this one:

@RequestMapping(value = "/file_redirect", method = RequestMethod.POST)
public ResponseEntity fileRedirect(HttpServletRequest request) throws Exception{

    InputStreamResource inputStreamResource = new InputStreamResource(request.getInputStream());

    return new ResponseEntity(inputStreamResource, HttpStatus.OK);
}

I'm using curl to send request and receive the file:

curl -X POST -H "content-length: 389907412" -H "Content-Type: multipart/form-data" -F "data=@/path/to/file/myVideo.mp4" -o returnedVideo.mp4 localhost/file_redirect

I also tried this method (the file size is correct):

@RequestMapping(value = "/file_redirect", method = RequestMethod.POST)
public ResponseEntity fileRedirect(HttpServletRequest request) throws Exception{

    InputStreamResource inputStreamResource = new InputStreamResource(request.getInputStream());

    HttpHeaders httpHeaders = new HttpHeaders();
    httpHeaders.setContentLength(389907412);
    httpHeaders.setContentType(new MediaType("video", "mp4"));

    return new ResponseEntity(inputStreamResource, httpHeaders, HttpStatus.OK);    
}

Both methods "works" and the file is saved successfully but it cannot be played after that. The file size of the returned file is correct. Metadata of the returned file is lost. The file type on both original and returned file is MPEG-4 video (video/mp4). Checksums of the original file and returned file are different.

What am I doing wrong when saving the file? Why the metadata is lost in the returned file?

Oleksandr
  • 3,574
  • 8
  • 41
  • 78
  • Year, Video duration, Container, Dimensions, Video Codec, Framerate, Audio Codec, Channels, Sample rate. Those are metadata which are present in the original file but missing in the returned file. – Oleksandr Dec 06 '18 at 00:03
  • When I try to retrieve metadata of the returned file with ffmpeg it shows: moov atom not found. returnedVideo.mp4: Invalid data found when processing input – Oleksandr Dec 06 '18 at 00:07
  • @ElliottFrisch , There are also additional metadata returned by ffmpeg but I believe the problem is that the returned file isn't stored properly. – Oleksandr Dec 06 '18 at 00:19
  • Possible duplicate of [How to upload files to server using JSP/Servlet?](https://stackoverflow.com/questions/2422468/how-to-upload-files-to-server-using-jsp-servlet) – dnault Dec 06 '18 at 01:10
  • You'll need to process the `multipart/form-data` content to access the raw bytes of the uploaded file. See https://stackoverflow.com/a/2424824/611819 – dnault Dec 06 '18 at 01:11
  • Also, looks like you're using Spring MVC, so maybe this guide will help: https://www.baeldung.com/spring-file-upload – dnault Dec 06 '18 at 01:15
  • @dnault , Thank you for that information! The problem was in the `curl` request itself. I've posted the answer. – Oleksandr Dec 06 '18 at 15:37

1 Answers1

0

The problem was in the curl request itself and not in the controller. Seems that the data were sent as a field data that is why when I was getting the InputStream in the controller, the InputStream contained the field data with the value (file) itself. To send the data without fields we need to use the next command:

curl -X POST -H "content-length: 389907412" --data-binary "@/path/to/file/myVideo.mp4" -o returnedVideo.mp4 localhost/file_redirect
Oleksandr
  • 3,574
  • 8
  • 41
  • 78