Search in sources :

Example 1 with UploadCallBack

use of com.aws.iot.edgeconnectorforkvs.videouploader.callback.UploadCallBack in project aws-iot-greengrass-edge-connector-for-kinesis-video-stream by awslabs.

the class EdgeConnectorForKVSService method startLiveVideoStreaming.

private void startLiveVideoStreaming(EdgeConnectorForKVSConfiguration edgeConnectorForKVSConfiguration) throws IOException, InterruptedException {
    ReentrantLock processLock = edgeConnectorForKVSConfiguration.getProcessLock();
    try {
        if (processLock.tryLock(INIT_LOCK_TIMEOUT_IN_SECONDS, TimeUnit.SECONDS)) {
            log.info("Start Live Video Streaming Called for " + edgeConnectorForKVSConfiguration.getKinesisVideoStreamName());
            log.info("Calling function " + Constants.getCallingFunctionName(2));
            edgeConnectorForKVSConfiguration.setLiveStreamingRequestsCount(edgeConnectorForKVSConfiguration.getLiveStreamingRequestsCount() + 1);
            if (edgeConnectorForKVSConfiguration.getLiveStreamingRequestsCount() > 1) {
                log.info("Live Streaming already running. Requests Count: " + edgeConnectorForKVSConfiguration.getLiveStreamingRequestsCount());
                return;
            }
        } else {
            log.error("Start uploading for " + edgeConnectorForKVSConfiguration.getKinesisVideoStreamName() + " timeout, re-init camera to restart the process.");
            edgeConnectorForKVSConfiguration.getFatalStatus().set(true);
        }
    } catch (InterruptedException e) {
        log.error("Start uploading for " + edgeConnectorForKVSConfiguration.getKinesisVideoStreamName() + " has been interrupted, re-init camera to restart the process.");
        edgeConnectorForKVSConfiguration.getFatalStatus().set(true);
    } finally {
        if (processLock.isHeldByCurrentThread())
            processLock.unlock();
    }
    // kick-off recording if it wasn't already started
    Future<?> future = recorderService.submit(() -> {
        startRecordingJob(edgeConnectorForKVSConfiguration);
    });
    try {
        // startRecordingJob is a blocking call, so we wait
        // upto 5 seconds for the recording to start before
        // we start live streaming below
        future.get(RECORDING_JOB_WAIT_TIME_IN_SECS, TimeUnit.SECONDS);
    } catch (InterruptedException ex) {
        log.error("Start Live Streaming Interrupted Exception: " + ex.getMessage());
    } catch (ExecutionException ex) {
        log.error("Start Live Streaming Execution Exception: " + ex.getMessage());
    } catch (TimeoutException ex) {
    // Ignore this exception, it is expected since
    // startRecordingJob is a blocking call
    }
    VideoRecorder videoRecorder = edgeConnectorForKVSConfiguration.getVideoRecorder();
    VideoUploader videoUploader = edgeConnectorForKVSConfiguration.getVideoUploader();
    do {
        PipedOutputStream outputStream = new PipedOutputStream();
        PipedInputStream inputStream = new PipedInputStream();
        // Toggle to false before switching outputStream (may not be required)
        videoRecorder.toggleAppDataOutputStream(false);
        edgeConnectorForKVSConfiguration.setOutputStream(outputStream);
        edgeConnectorForKVSConfiguration.setInputStream(inputStream);
        outputStream.connect(inputStream);
        videoRecorder.setAppDataOutputStream(outputStream);
        log.info("Connected streams for KVS Stream: " + edgeConnectorForKVSConfiguration.getKinesisVideoStreamName());
        videoRecorder.toggleAppDataOutputStream(true);
        log.info("Turned on outputStream in recorder and start uploading!");
        Date dateNow = new Date();
        try {
            videoUploader.uploadStream(inputStream, dateNow, new StatusChangedCallBack(), new UploadCallBack(dateNow, edgeConnectorForKVSConfiguration));
        } catch (Exception exception) {
            if (processLock.tryLock(INIT_LOCK_TIMEOUT_IN_SECONDS, TimeUnit.SECONDS)) {
                log.error("Failed to upload stream: {}", exception.getMessage());
                AtomicBoolean isRecorderToggleOff = new AtomicBoolean();
                Thread toggleRecorderOffThreaed = new Thread(() -> {
                    log.info("Waiting for toggling recorder off");
                    videoRecorder.toggleAppDataOutputStream(false);
                    try {
                        TimeUnit.MILLISECONDS.sleep(2000);
                    } catch (InterruptedException e) {
                        log.error("toggleRecorderOffThread exception: " + e.getMessage());
                    }
                    isRecorderToggleOff.set(true);
                    log.info("Toggling recorder off");
                });
                toggleRecorderOffThreaed.start();
                log.info("InputStream is flushing");
                try {
                    int bytesAvailable = inputStream.available();
                    while (!isRecorderToggleOff.get() || bytesAvailable > 0) {
                        byte[] b = new byte[bytesAvailable];
                        inputStream.read(b);
                        bytesAvailable = inputStream.available();
                    }
                } catch (IOException e) {
                    log.error("Exception flush inputStream: " + e.getMessage());
                } finally {
                    if (processLock.isHeldByCurrentThread())
                        processLock.unlock();
                }
                log.info("InputStream is flushed");
                outputStream.close();
                inputStream.close();
            } else {
                log.error("Restart uploading for " + edgeConnectorForKVSConfiguration.getKinesisVideoStreamName() + " timeout, re-init camera to restart the process.");
                edgeConnectorForKVSConfiguration.getFatalStatus().set(true);
                if (processLock.isHeldByCurrentThread())
                    processLock.unlock();
                break;
            }
        }
    } while (retryOnFail && edgeConnectorForKVSConfiguration.getLiveStreamingRequestsCount() > 0);
}
Also used : ReentrantLock(java.util.concurrent.locks.ReentrantLock) VideoUploader(com.aws.iot.edgeconnectorforkvs.videouploader.VideoUploader) StatusChangedCallBack(com.aws.iot.edgeconnectorforkvs.videouploader.callback.StatusChangedCallBack) VideoRecorder(com.aws.iot.edgeconnectorforkvs.videorecorder.VideoRecorder) PipedOutputStream(java.io.PipedOutputStream) PipedInputStream(java.io.PipedInputStream) IOException(java.io.IOException) Date(java.util.Date) TimeoutException(java.util.concurrent.TimeoutException) EdgeConnectorForKVSException(com.aws.iot.edgeconnectorforkvs.model.exceptions.EdgeConnectorForKVSException) EdgeConnectorForKVSUnrecoverableException(com.aws.iot.edgeconnectorforkvs.model.exceptions.EdgeConnectorForKVSUnrecoverableException) IOException(java.io.IOException) ExecutionException(java.util.concurrent.ExecutionException) UploadCallBack(com.aws.iot.edgeconnectorforkvs.videouploader.callback.UploadCallBack) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) ExecutionException(java.util.concurrent.ExecutionException) TimeoutException(java.util.concurrent.TimeoutException)

Example 2 with UploadCallBack

use of com.aws.iot.edgeconnectorforkvs.videouploader.callback.UploadCallBack in project aws-iot-greengrass-edge-connector-for-kinesis-video-stream by awslabs.

the class VideoUploaderClientTest method uploadStream_mockAckResponseCompleteWithUploadCallback_taskClosed.

@Test
public void uploadStream_mockAckResponseCompleteWithUploadCallback_taskClosed() throws InterruptedException {
    Assumptions.assumeTrue(setPrivateMember(videoUploaderClient, "kvsFrontendClient", mockKvsFrontendClient));
    Assumptions.assumeTrue(setPrivateMember(videoUploaderClient, "kvsDataClient", mockKvsDataClient));
    ArgumentCaptor<PutMediaAckResponseHandler> putMediaAckResponseArgumentCaptor = ArgumentCaptor.forClass(PutMediaAckResponseHandler.class);
    ArgumentCaptor<PutMediaRequest> putMediaRequestArgumentCaptor = ArgumentCaptor.forClass(PutMediaRequest.class);
    when(mockKvsFrontendClient.getDataEndpoint(any(GetDataEndpointRequest.class))).thenReturn(new GetDataEndpointResult().withDataEndpoint(DATA_ENDPOINT));
    doNothing().when(mockKvsDataClient).putMedia(any(PutMediaRequest.class), any(PutMediaAckResponseHandler.class));
    // Since we make putMedia do nothing, so it won't end until we close it.
    Date dateNow = Date.from(Instant.now());
    final UploadCallBack uploadCallBack = new UploadCallBack(dateNow, edgeConnectorForKVSConfiguration);
    new Thread(() -> {
        videoUploaderClient.uploadStream(inputStream, dateNow, null, uploadCallBack);
    }).start();
    // wait until task start
    while (!videoUploaderClient.isOpen()) {
        System.out.println("task is not running");
        Thread.sleep(STATUS_CHANGED_TIME);
    }
    verify(mockKvsDataClient).putMedia(putMediaRequestArgumentCaptor.capture(), putMediaAckResponseArgumentCaptor.capture());
    AckEvent event = new AckEvent().withAckEventType(AckEventType.Values.PERSISTED).withFragmentTimecode(dateNow.getTime());
    putMediaAckResponseArgumentCaptor.getValue().onAckEvent(event);
    putMediaAckResponseArgumentCaptor.getValue().onComplete();
    // wait until task end
    while (videoUploaderClient.isOpen()) {
        System.out.println("task is running");
        Thread.sleep(STATUS_CHANGED_TIME);
    }
    Assertions.assertFalse(videoUploaderClient.isOpen());
}
Also used : GetDataEndpointRequest(com.amazonaws.services.kinesisvideo.model.GetDataEndpointRequest) GetDataEndpointResult(com.amazonaws.services.kinesisvideo.model.GetDataEndpointResult) PutMediaAckResponseHandler(com.amazonaws.services.kinesisvideo.PutMediaAckResponseHandler) PutMediaRequest(com.amazonaws.services.kinesisvideo.model.PutMediaRequest) Date(java.util.Date) AckEvent(com.amazonaws.services.kinesisvideo.model.AckEvent) UploadCallBack(com.aws.iot.edgeconnectorforkvs.videouploader.callback.UploadCallBack) Test(org.junit.jupiter.api.Test)

Example 3 with UploadCallBack

use of com.aws.iot.edgeconnectorforkvs.videouploader.callback.UploadCallBack in project aws-iot-greengrass-edge-connector-for-kinesis-video-stream by awslabs.

the class VideoUploaderClientTest method uploadHistoricalVideo_filesInTimePeriod_runCallbacks.

@Test
public void uploadHistoricalVideo_filesInTimePeriod_runCallbacks() throws InterruptedException {
    Assumptions.assumeTrue(setPrivateMember(videoUploaderClient, "kvsFrontendClient", mockKvsFrontendClient));
    Assumptions.assumeTrue(setPrivateMember(videoUploaderClient, "kvsDataClient", mockKvsDataClient));
    Assumptions.assumeTrue(tempVideoFilesPresent());
    final boolean[] isStatusChanged = { false };
    final Runnable statusChangedCallBack = () -> isStatusChanged[0] = true;
    UploadCallBack uploadCallBack = new UploadCallBack(Date.from(instantNow.minusSeconds(600)), edgeConnectorForKVSConfiguration);
    when(mockKvsFrontendClient.getDataEndpoint(any(GetDataEndpointRequest.class))).thenReturn(new GetDataEndpointResult().withDataEndpoint(DATA_ENDPOINT));
    doNothing().when(mockKvsDataClient).putMedia(any(PutMediaRequest.class), any(PutMediaAckResponseHandler.class));
    // Since we make putMedia do nothing, so it won't end until we close it.
    new Thread(() -> {
        videoUploaderClient.uploadHistoricalVideo(Date.from(instantNow.minusSeconds(600)), Date.from(instantNow.minusSeconds(200)), statusChangedCallBack, uploadCallBack);
    }).start();
    // wait until task start
    if (!videoUploaderClient.isOpen()) {
        System.out.println("task is not running");
        Thread.sleep(STATUS_CHANGED_TIME);
    }
    videoUploaderClient.close();
    // wait until task end
    while (videoUploaderClient.isOpen()) {
        System.out.println("task is running");
        Thread.sleep(STATUS_CHANGED_TIME);
    }
    Assertions.assertFalse(isStatusChanged[0]);
    Assertions.assertNull(uploadCallBack.getUploadingFile());
}
Also used : GetDataEndpointRequest(com.amazonaws.services.kinesisvideo.model.GetDataEndpointRequest) GetDataEndpointResult(com.amazonaws.services.kinesisvideo.model.GetDataEndpointResult) PutMediaAckResponseHandler(com.amazonaws.services.kinesisvideo.PutMediaAckResponseHandler) PutMediaRequest(com.amazonaws.services.kinesisvideo.model.PutMediaRequest) UploadCallBack(com.aws.iot.edgeconnectorforkvs.videouploader.callback.UploadCallBack) Test(org.junit.jupiter.api.Test)

Example 4 with UploadCallBack

use of com.aws.iot.edgeconnectorforkvs.videouploader.callback.UploadCallBack in project aws-iot-greengrass-edge-connector-for-kinesis-video-stream by awslabs.

the class VideoUploaderClientTest method uploadStream_mockAckResponseComplete_runCallbacks.

@Test
public void uploadStream_mockAckResponseComplete_runCallbacks() throws InterruptedException {
    Assumptions.assumeTrue(setPrivateMember(videoUploaderClient, "kvsFrontendClient", mockKvsFrontendClient));
    Assumptions.assumeTrue(setPrivateMember(videoUploaderClient, "kvsDataClient", mockKvsDataClient));
    final boolean[] isStatusChanged = { false };
    final Runnable statusChangedCallBack = () -> isStatusChanged[0] = true;
    final UploadCallBack uploadCallBack = new UploadCallBack(Date.from(Instant.now()), edgeConnectorForKVSConfiguration);
    ArgumentCaptor<PutMediaAckResponseHandler> putMediaAckResponseArgumentCaptor = ArgumentCaptor.forClass(PutMediaAckResponseHandler.class);
    ArgumentCaptor<PutMediaRequest> putMediaRequestArgumentCaptor = ArgumentCaptor.forClass(PutMediaRequest.class);
    when(mockKvsFrontendClient.getDataEndpoint(any(GetDataEndpointRequest.class))).thenReturn(new GetDataEndpointResult().withDataEndpoint(DATA_ENDPOINT));
    doNothing().when(mockKvsDataClient).putMedia(any(PutMediaRequest.class), any(PutMediaAckResponseHandler.class));
    when(this.edgeConnectorForKVSConfiguration.getStreamManager()).thenReturn(streamManager);
    when(streamManager.pushData(any(), any(), any(), any())).thenReturn(0L);
    // Since we make putMedia do nothing, so it won't end until we close it.
    new Thread(() -> {
        videoUploaderClient.uploadStream(inputStream, Date.from(Instant.now()), statusChangedCallBack, uploadCallBack);
    }).start();
    Thread.sleep(STATUS_CHANGED_TIME);
    // wait until task start
    while (!videoUploaderClient.isOpen()) {
        System.out.println("task is not running");
        Thread.sleep(STATUS_CHANGED_TIME);
    }
    verify(mockKvsDataClient).putMedia(putMediaRequestArgumentCaptor.capture(), putMediaAckResponseArgumentCaptor.capture());
    AckEvent event = new AckEvent().withAckEventType(AckEventType.Values.PERSISTED);
    event.setFragmentTimecode(1L);
    putMediaAckResponseArgumentCaptor.getValue().onAckEvent(event);
    // Wait stream manager update values
    Thread.sleep(STATUS_CHANGED_TIME);
    putMediaAckResponseArgumentCaptor.getValue().onComplete();
    // wait until task end
    while (videoUploaderClient.isOpen()) {
        System.out.println("task is running");
        Thread.sleep(STATUS_CHANGED_TIME);
    }
    Assertions.assertFalse(isStatusChanged[0]);
    verify(streamManager, times(1)).pushData(any(), any(), any(), any());
}
Also used : GetDataEndpointRequest(com.amazonaws.services.kinesisvideo.model.GetDataEndpointRequest) GetDataEndpointResult(com.amazonaws.services.kinesisvideo.model.GetDataEndpointResult) PutMediaAckResponseHandler(com.amazonaws.services.kinesisvideo.PutMediaAckResponseHandler) PutMediaRequest(com.amazonaws.services.kinesisvideo.model.PutMediaRequest) AckEvent(com.amazonaws.services.kinesisvideo.model.AckEvent) UploadCallBack(com.aws.iot.edgeconnectorforkvs.videouploader.callback.UploadCallBack) Test(org.junit.jupiter.api.Test)

Example 5 with UploadCallBack

use of com.aws.iot.edgeconnectorforkvs.videouploader.callback.UploadCallBack in project aws-iot-greengrass-edge-connector-for-kinesis-video-stream by awslabs.

the class VideoUploaderClientTest method uploadHistoricalVideo_filesInTimePeriodWithEndpointAlreadySet_runCallbacks.

@Test
public void uploadHistoricalVideo_filesInTimePeriodWithEndpointAlreadySet_runCallbacks() throws InterruptedException {
    Assumptions.assumeTrue(setPrivateMember(videoUploaderClient, "kvsFrontendClient", mockKvsFrontendClient));
    Assumptions.assumeTrue(setPrivateMember(videoUploaderClient, "kvsDataClient", mockKvsDataClient));
    Assumptions.assumeTrue(setPrivateMember(videoUploaderClient, "dataEndpoint", DATA_ENDPOINT));
    Assumptions.assumeTrue(tempVideoFilesPresent());
    final boolean[] isStatusChanged = { false };
    final Runnable statusChangedCallBack = () -> isStatusChanged[0] = true;
    final UploadCallBack uploadCallBack = new UploadCallBack(Date.from(instantNow.minusSeconds(600)), edgeConnectorForKVSConfiguration);
    new Thread(() -> {
        videoUploaderClient.uploadHistoricalVideo(Date.from(instantNow.minusSeconds(600)), Date.from(instantNow.minusSeconds(599)), statusChangedCallBack, uploadCallBack);
    }).start();
    // wait until task start
    if (!videoUploaderClient.isOpen()) {
        System.out.println("task is not running");
        Thread.sleep(STATUS_CHANGED_TIME);
    }
    videoUploaderClient.close();
    // wait until task end
    while (videoUploaderClient.isOpen()) {
        System.out.println("task is running");
        Thread.sleep(STATUS_CHANGED_TIME);
    }
    Assertions.assertFalse(isStatusChanged[0]);
    verify(streamManager, times(0)).pushData(any(), any(), any(), any());
}
Also used : UploadCallBack(com.aws.iot.edgeconnectorforkvs.videouploader.callback.UploadCallBack) Test(org.junit.jupiter.api.Test)

Aggregations

UploadCallBack (com.aws.iot.edgeconnectorforkvs.videouploader.callback.UploadCallBack)9 Test (org.junit.jupiter.api.Test)7 PutMediaAckResponseHandler (com.amazonaws.services.kinesisvideo.PutMediaAckResponseHandler)6 GetDataEndpointRequest (com.amazonaws.services.kinesisvideo.model.GetDataEndpointRequest)6 GetDataEndpointResult (com.amazonaws.services.kinesisvideo.model.GetDataEndpointResult)6 PutMediaRequest (com.amazonaws.services.kinesisvideo.model.PutMediaRequest)6 AckEvent (com.amazonaws.services.kinesisvideo.model.AckEvent)3 Date (java.util.Date)3 EdgeConnectorForKVSException (com.aws.iot.edgeconnectorforkvs.model.exceptions.EdgeConnectorForKVSException)2 EdgeConnectorForKVSUnrecoverableException (com.aws.iot.edgeconnectorforkvs.model.exceptions.EdgeConnectorForKVSUnrecoverableException)2 VideoUploader (com.aws.iot.edgeconnectorforkvs.videouploader.VideoUploader)2 StatusChangedCallBack (com.aws.iot.edgeconnectorforkvs.videouploader.callback.StatusChangedCallBack)2 IOException (java.io.IOException)2 ExecutionException (java.util.concurrent.ExecutionException)2 TimeoutException (java.util.concurrent.TimeoutException)2 VideoRecorder (com.aws.iot.edgeconnectorforkvs.videorecorder.VideoRecorder)1 KvsStreamingException (com.aws.iot.edgeconnectorforkvs.videouploader.model.exceptions.KvsStreamingException)1 PipedInputStream (java.io.PipedInputStream)1 PipedOutputStream (java.io.PipedOutputStream)1 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)1