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);
}
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());
}
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());
}
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());
}
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());
}
Aggregations