Search code examples
spring-mvcyoutubevideo-streamingspring-websockettwitch

How to build a stream website like twitch with spring


I am building the WebSocket chatroom with spring message already.

Now I want to build the streaming website like Twitch. I search a lot of way on stream. They always provide the framework of Andriod.

In first I want to use binary to transit my stream.

But I afraid my stream will crash if too many connections.

So I go to youtube and twitch.tv I see twitch use fragmentation of m3u8 and using WebSocket to get information and using get or option get the m3u8 file to make a video.

Can springMVC build like DFS?

Or I need too read some manual of API?

Can someone point me a direct let me figure out how to build a streaming website?


Solution

  • There is the Spring community project called Spring Content. It supports byte-range request and therefore html5 video controls out of the box. I am not sure if that is good enough?

    Regardless, when paired it Spring Data (and Spring Boot), this project makes it extremely easy to build contentful applications and services. It has the same programming model as Spring Data and essentially is to content (or unstructured data) what Spring data is to structured data. Even if it isn't good enough for streaming (and we would be delighted to work with you on enhancing this), it will certainly help you accelerate the build of your "content management" platform overall as presumably, you need user/admin pages that allow folks up upload and manage your video streams too.

    This might look something like the following:-

    pom.xml

       <!-- Spring Boot/ Spring Data dependencies -->
       ...
    
       <!-- Java API -->
       <dependency>
          <groupId>com.github.paulcwarren</groupId>
          <artifactId>spring-content-fs-boot-starter</artifactId>
          <version>0.7.0</version>
       </dependency>
    
       <!-- REST API -->
       <dependency>
          <groupId>com.github.paulcwarren</groupId>
          <artifactId>spring-content-rest-boot-starter</artifactId>
          <version>0.7.0</version>
       </dependency>
    

    Video.java

    @Entity
    public class Video {
       @Id
       @GeneratedValue
       private long id;
    
       ...other existing fields...
    
       @ContentId
       private String contentId;
    
       @ContentLength
       private long contentLength = 0L;
    
       @MimeType
       private String mimeType = "text/plain";
    
       ...
    }
    

    VideoContentStore.java

    @StoreRestResource(path="videoStreams")
    public interface VideoContentStore extends ContentStore<Video, String> {
    }
    

    This is all you need to do to get REST Endpoints that will allow you to store and retrieve content associated with each Video entity. As mentioned how this actually works is very much like Spring Data. When your application starts Spring Content will see the spring-content-fs-boot-starter dependencies, know that you want to store content on your filesystem and inject a filesystem (or JPA/GridFS/S3) implementation of the VideoContentStore interface. It will also see the spring-content-rest-boot-starter and will inject REST endpoints that talk to this content store interface. Meaning you don't have to do any of this yourself.

    So, for example:

    curl -X POST /videoStreams/{videoId} -F "file=@/path/to/video.mp4"

    will store the video on the filesystem and associate it with the video entity whose id is videoId.

    curl /videoStreams/{videoId}

    will fetch it again and so on...supports full CRUD and this is the endpoint also supports video streaming (or byte range-requests).

    There is an example here.

    You could also decide to store the contents elsewhere like in the database with your entities, or in S3 by swapping the spring-content-fs-boot-starter dependency for the appropriate Spring Content Storage module. Examples for every type of storage are here.

    HTH P.S. Dont be shy about raising issues/features request and /or PRs we are actively looking for engagement.