1

I'm using AWS Kinesis Video Stream service to get my video recordings. So due to the Kinesis Video Stream fragment limitation, it turns out I can only retrieve up to ~30 minutes video at one request. And I was intend to retrieve a 2 hour video.

So I loop the request and get all 4 response into a List of InputStream, then I turn them into SequenceInputStream because I try to chain them all together.

However when I success uploaded them to S3 bucket and try to download from there. It shows me file are corrupted. I researched on SequenceInputStream however it seems that my design was okay.

Furthermore, if I extend my video length, let say I have 24 InputStream, and I chained them all to a single SequenceInputStream, it will encounter the SSL Socket Exception: Connection Reset when I run the readAllBytes operation on the sequence input stream.

Is there any way I can achieve what I want or something wrong in my code to cause this?

Here are my source code:

private String downloadMedia(Request request, JSONObject response, JSONObject metaData, Date startDate, Date endDate) throws Exception {
        long duration  = endDate.getTime() - startDate.getTime();
        long durationInMinutes = TimeUnit.MILLISECONDS.toMinutes(duration);
        long intervalsCount = durationInMinutes / 30;

        ArrayList<GetClipResult> getClipResults = new ArrayList<>();

        for (int i = 0; i < intervalsCount; i++){
            Media currentMedia = constructMediaAfterIntervalsBreakdown(metaData, request, startDate, endDate);

            String deviceName = metaData.getString("name") + "_" + request.getId();
            Stream stream = getStreamByName(name, request.getId());

            String endPoint = getDataEndpoint(stream.getStreamName());
            GetClipResult clipResult = downloadMedia(currentMediaDto, endPoint, stream.getStreamName());
            if(clipResult != null){
                getClipResults.add(clipResult);
            }

            startDate = currentMediaDto.getEndTime();
        }

        //Get presigned URL from S3 service response
        String url = response.getJSONArray("data").getJSONObject(0).getJSONArray("parts").getJSONObject(0).getString("url");

        if (getClipResults.size() > 0) {
            Vector<InputStream> inputStreams = new Vector<>();
            for (GetClipResult clipResult : getClipResults){
                InputStream videoStream = clipResult.getPayload();
                inputStreams.add(videoStream);
            }
            Enumeration<InputStream> inputStreamEnumeration = inputStreams.elements();;
            SequenceInputStream sequenceInputStream = new SequenceInputStream(inputStreamEnumeration);
            if (sequenceInputStream.available() > 0){
                sequenceInputStream.readAllBytes();
                byte[] bytes = sequenceInputStream.readAllBytes();
                String message = uploadFileUsingSecureUrl(url, bytes, metaData);
                return message;
            }
        }
        return "failed";
    }

Edited: I came across couple package that called Xuggler and FFMPEG, however most of them are getting the video file from disk (which has a path), but for my case there isn't any video file because I do not download them to local, they only existed in the runtime and will upload to S3 later on after concatenated.

Appreciates any help! Thank you!

Sivvie Lim
  • 784
  • 2
  • 14
  • 43

1 Answers1

0

So in the end I just downloaded the clips, saved it to the disk on runtime, merged them using mp4parser and upload to S3. Afterwards I just deleted those on my disk.

If anyone curious about the code, it is taken from https://github.com/sannies/mp4parser/blob/master/examples/src/main/java/com/googlecode/mp4parser/AppendExample.java

Thank you.

Sivvie Lim
  • 784
  • 2
  • 14
  • 43