Video streaming using AWS SDK - Second byte range call not working

30 views Asked by At

I was fetching a chunk of 2MB on each call using AWS SDK for Java 2.x :

Total file size = 12MB
Chunk size = 2MB

For the first call:
Range from browser bytes=0- and calculated the the range based on chunk size and sent req with bytes=0-2097151. For this call I was able to fetch the response and stream the part of video in browser

For the second call:
Range from browser bytes=2097152- and I calculated the range and sent req with bytes=2097152-4194302 in this case I was getting response from AWS SDK where while sending the response to browser I was getting the below error:

java.lang.IllegalArgumentException:
position exceeds the resource length 2097152.

Full error log:

java.lang.IllegalArgumentException: 'position' exceeds the resource length 2097152
    at org.springframework.util.Assert.isTrue(Assert.java:121) ~[spring-core-5.3.19.jar:5.3.19]
    Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException: 
Error has been observed at the following site(s):
    *__checkpoint ⇢ Handler com.example.demo.Application#getVideoFromS3(String) [DispatcherHandler]
    *__checkpoint ⇢ HTTP GET "/video/s3" [ExceptionHandlingWebHandler]
Original Stack Trace:
        at org.springframework.util.Assert.isTrue(Assert.java:121) ~[spring-core-5.3.19.jar:5.3.19]
        at org.springframework.http.HttpRange.toResourceRegion(HttpRange.java:68) ~[spring-web-5.3.19.jar:5.3.19]
        at org.springframework.http.HttpRange.toResourceRegions(HttpRange.java:183) ~[spring-web-5.3.19.jar:5.3.19]
        at org.springframework.http.codec.ResourceHttpMessageWriter.lambda$write$3(ResourceHttpMessageWriter.java:213) ~[spring-web-5.3.19.jar:5.3.19]

My code:
Using below sample code in service:

EcsObject ecsObject = awsEcsRepository.getObjectByRange(fileName, bucketName, null, contentRange, correlationId);
ByteArrayResource videoResponse = new ByteArrayResource(ecsObject.getInputStream().readAllBytes());

HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.valueOf("video/webm"));
headers.setContentLength(ecsObject.getContentLength());
headers.set(HttpHeaders.CONTENT_RANGE, "bytes " + rangeStart + "-"+rangeEnd+"/"+fileSize);
headers.set(HttpHeaders.ACCEPT_RANGES, "bytes");

return ResponseEntity.status(HttpStatus.PARTIAL_CONTENT)
        .headers(headers)
        .body(videoResponse);

controller:
public ResponseEntity<ByteArrayResource> getVideoFromS3(@RequestHeader("Range") String range)
{
    return streamingService.getVideoFromS3(range);
}

I tried tweaking the byte ranges, but its not working. Looking for a solution to fix the issue and i should be able to stream the video in browser by fetching chunks using range request.

0

There are 0 answers