简体   繁体   中英

How to concatenate clips getting from Kinesis Video Stream in Java

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!

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM