Reputation:
I've been learning the Spring boot framework recently and so far I'm fairly impressed by it.
However, I've been trying to write a basic media server application and I'm not entirely sure what the correct way is to implement a controller endpoint which serves an HTML 5 video source. I've currently implemented this like so:
@GetMapping(value = "/videosrc", produces = "video/mp4")
@ResponseBody
public FileSystemResource videoSource(@RequestParam(value="id", required=true) int id) {
return new FileSystemResource(new File("path to mp4 file"));
}
And the HTML 5 video element looks like this: (using Thymeleaf)
<video width="auto" height="240" controls style=" margin-left: auto; margin-right: auto; display: block;">
<source th:src="@{/videosrc(id=${video.id})}" type="video/mp4">
</video>
The video displays, however I've noticed that if I skip the video a few times it eventually slows down and then freezes up the browser. I'm not sure why this is happening but I'm assuming it's because I'm not handling the request correctly?
Thanks
Upvotes: 9
Views: 18375
Reputation: 2479
You should consider a Spring Boot companion project called Spring Content that allows you to create digital asset management applications with very little code.
To give you the basic idea that would look something like this:-
pom.xml
<dependency>
<groupId>com.github.paulcwarren</groupId>
<artifactId>spring-content-rest-boot-starter</artifactId>
<version>0.0.10</version>
</dependency>
<dependency>
<groupId>com.github.paulcwarren</groupId>
<artifactId>content-fs-spring-boot-starter</artifactId>
<version>0.0.10</version>
</dependency>
SpringBootApplication.java
@SpringBootApplication
public class YourSpringBootApplication {
public static void main(String[] args) {
SpringApplication.run(YourSpringBootApplication.class, args);
}
@Configuration
@EnableFilesystemStores
public static class StoreConfig {
File filesystemRoot() {
// return the root of your video store
}
// this bean is the spring resource loader that will be used by
// the product store
@Bean
public FileSystemResourceLoader fsResourceLoader() throws Exception
{
return new FileSystemResourceLoader(filesystemRoot().getAbsolutePath());
}
}
@StoreRestResource(path="videosrc")
public interface VideoStore extends Store<String> {
//
}
}
Note that you are not writing any controller code here but this is enough to create a REST video service at /videosrc
that supports full CRUD and video streaming (i.e. byte ranges). Create == POST, Read == GET (include byte-range support), Update == PUT, Delete == DELETE.
e.g.
POST /videosrc/some/path/video1.mp4
would store the uploaded multipart video to /some/path/video.mp4.
Spring Content can also be combined with Spring Data to store and search metadata about these videos too. If that is of interest then take a look at the Getting Started guides here and here.
Upvotes: 7
Reputation:
It looks like this might just be an issue with Firefox (Quantum) - it works OK but after skipping a few times seems to freeze up.
I tested this on Google chrome and it works fine. Also works fine on a mobile browser.
I also checked it was sending the correct HTTP headers - mainly 'Accept-Ranges: bytes' (which it was).
Upvotes: 1