How do I return a video with Spring MVC so that it can be navigated using the html5 <video> tag?
A simple solution for handling non-static resources:
@SpringBootApplication
public class DemoApplication {
private final static File MP4_FILE = new File("/home/ego/bbb_sunflower_1080p_60fps_normal.mp4");
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
@Controller
final static class MyController {
@Autowired
private MyResourceHttpRequestHandler handler;
// supports byte-range requests
@GetMapping("/")
public void home(
HttpServletRequest request,
HttpServletResponse response
) throws ServletException, IOException {
request.setAttribute(MyResourceHttpRequestHandler.ATTR_FILE, MP4_FILE);
handler.handleRequest(request, response);
}
// does not support byte-range requests
@GetMapping(path = "/plain", produces = "video/mp4")
public FileSystemResource plain() {
return new FileSystemResource(MP4_FILE);
}
}
@Component
final static class MyResourceHttpRequestHandler extends ResourceHttpRequestHandler {
private final static String ATTR_FILE = MyResourceHttpRequestHandler.class.getName() + ".file";
@Override
protected Resource getResource(HttpServletRequest request) throws IOException {
final File file = (File) request.getAttribute(ATTR_FILE);
return new FileSystemResource(file);
}
}
}
(inspired by Spring Boots LogFileMvcEndpoint and more or less equal to Paul-Warrens (@paul-warren) StoreByteRangeHttpRequestHandler which I found later on).
Hopefully this is something which Spring will support in the near future, see https://jira.spring.io/browse/SPR-13834 (please vote for it).
The HTTP resume download function might be your friend. I had the same problem before. After implementing http range the navigation in the video was possible:
http://balusc.blogspot.com/2009/02/fileservlet-supporting-resume-and.html
I know this is an old post but in case it is useful to anyone else out there asking the same/similar questions.
Now-a-days there are projects like Spring Content that natively support video streaming. All the code you would need for the simplest implementation would be:-
@StoreRestResource(path="videos")
public interface VideoStore extends Store<String> {}
And this would be enough to create a Java API and a set of REST endpoints that would allow you to PUT/POST, GET and DELETE streams of video. GET support byte ranges and will play properly in HTML5 video players and such like.