Search code examples
amazon-web-servicesspring-bootamazon-s3video-streamingamazon-kinesis-video-streams

Spring Boot Video Streaming from S3 Bucket


I want to create a youtube like Video streaming application but in a small scale. I am using Spring boot for backend rest endpoints and amazon S3 bucket for storing video files. I am able to upload and download video files to S3 bucket. But I am confused in streaming side. I want to show those video files in jsp page to play. I heard about Aws video on demand, aws kinesis, etc. Can someone suggest me or share some link which will be the best approach to follow for video streaming with spring boot. Or is there any other service apart from aws services which can be useful in this scenario. I am totally confused. Please help me out. Thank you.


Solution

  • I have created a sample project for streaming the AWS s3 resources using spring boot.

    You can set a controller with mapping as required.

    For this demo code the endpoint is http://localhost:port/bucket_name/object_key

        @RestController("/")
        public class ApiController {
    
        @Value("${aws.region}")
        private String awsRegion;
    
        @GetMapping(value = "/**", produces = { MediaType.APPLICATION_OCTET_STREAM_VALUE })
        public ResponseEntity<StreamingResponseBody> getObject(HttpServletRequest request) {
            try {
                AmazonS3 s3client = AmazonS3ClientBuilder.standard().withRegion(awsRegion).build();
    
                String uri = request.getRequestURI();
                String uriParts[] = uri.split("/", 2)[1].split("/", 2);
                String bucket = uriParts[0];
                String key = uriParts[1];
                System.out.println("Fetching " + uri);
                S3Object object = s3client.getObject(bucket, key);
                S3ObjectInputStream finalObject = object.getObjectContent();
    
                final StreamingResponseBody body = outputStream -> {
                    int numberOfBytesToWrite = 0;
                    byte[] data = new byte[1024];
                    while ((numberOfBytesToWrite = finalObject.read(data, 0, data.length)) != -1) {
                        outputStream.write(data, 0, numberOfBytesToWrite);
                    }   
                    finalObject.close();
                };
                return new ResponseEntity<StreamingResponseBody>(body, HttpStatus.OK);
            } catch (Exception e) {
                System.err.println("Error "+ e.getMessage());
                return new ResponseEntity<StreamingResponseBody>(HttpStatus.BAD_REQUEST);
            }
    
        }
    }
    

    You need to use StreamingResponseBody in your ResponseEntity. If you need a ready to use microservice feel free to explore the github project s3-streamer I wrote for very same purpose.