Allows developers to install and customize their connected camera and other devices to securely stream video, audio, and time-encoded data to Kinesis Video Streams
Implements StreamEventMetadata class and StreamEventType enum.
Implement JNI wrapper for PutEventMetadata in NativeKinesisVideoProducerStream.
Add PutEventMetadata calls for every keyframe in ImageFrameSource for the DemoApp to use.
Testing
The following testing and validation was conducted for various STREAM_EVENT_TYPE (StreamEventType in Java end) values using a KVS stream configured for image generation and notifications.
A. IMAGE_GENERATION - Valid Inputs
1. 0 StreamEventMetadata Name/Value Pairs
StreamEventMetadata(null, (byte)0, new String[]{}, new String[]{})
The first S3 object received contains an image of the footage:
✅ This image matches the first frame contained in the set of test .h264 files:
Due to the specific format or packaging of our .h264 test files, it was not readily possible to use an ffmpeg command to display the first frame as an image. An alternative technique was used to view the above first test frame which involved hardcoding the Java sample's image file index to remain at 0, so the first frame was constantly uploaded to KVS. Playing back the KVS stream at any recent point would then show that first frame.
Note: Images will no longer be shown for the remaining test cases below due to redundancy.
✅ The S3 object contains no additional metadata as expected:
2. 1 StreamEventMetadata Name/Value Pair
StreamEventMetadata(null, (byte)1, new String[]{"aTestName"}, new String[]{"aTestValue"})
✅ S3 saved image is valid.
✅ S3 metadata received as expected:
✅ The above successful tests were the case for pair counts from 1-9, but 10 failed as seen below.
❌ No image object in S3.
❌ No metadata.
PutEventMetadata fails with 0x52000074 STATUS_MAX_FRAGMENT_METADATA_COUNT.
NOTE: This uncovered that the true limit to name/value pairs in PIC is 9, or 8 if using an S3 imagePrefix.
⚠️ We see only one name/value pair is saved in the object, so specifying the correct number of numberOfPairs is NOT optional:
C. NONE
String[] testNames = new String[]{"name-one"};
String[] testValues = new String[]{"value-one"};
testMetadata = new StreamEventMetadata(null, (byte)1, testNames, testValues);
mkvDataAvailableCallback.onEventMetadataAvailable(StreamEventType.STREAM_EVENT_TYPE_NONE.getIntType(), testMetadata);
✅ Received the expected error status code:
0x00000002 | STATUS_INVALID_ARG
D. NOTIFICATION
Notification functionality was tested using an SNS topic with an email subscription.
✅ Received the expected notification via email with the expected SNS payload:
String[] testNames = new String[]{"name-one"};
String[] testValues = new String[]{"value-one"};
testMetadata = new StreamEventMetadata(null, (byte)1, testNames, testValues);
mkvDataAvailableCallback.onEventMetadataAvailable(StreamEventType.STREAM_EVENT_TYPE_LAST.getIntType(), testMetadata);
✅ Received the expected error status code:
0x00000002 | STATUS_INVALID_ARG
F. Multiple StreamEventType
Using bitwise OR, IMAGE_GENERATION (1 = 001) was combined with NOTIFICATION (2 = 010) to equal 3 (011):
String[] testNames = new String[]{"name-one"};
String[] testValues = new String[]{"value-one"};
testMetadata = new StreamEventMetadata(null, (byte)1, testNames, testValues);
mkvDataAvailableCallback.onEventMetadataAvailable(3, testMetadata);
✅ Both, the S3 object containing an image with tags, and the SNS email notification were received:
G. Negative StreamEventType
Care must be take here as the Java int passed to the JNI can be negative, while the StreamEventType parameter is an unsigned integer in PIC. Checks were placed in both the JNI and Java layers to error out if StreamEventType is negative.
String[] testNames = new String[]{"name-one"};
String[] testValues = new String[]{"value-one"};
testMetadata = new StreamEventMetadata(null, (byte)1, testNames, testValues);
mkvDataAvailableCallback.onEventMetadataAvailable(-1, testMetadata);
✅ Received the expected Java error due to Precondition check:
java.lang.IllegalArgumentException
After removing the Java Precondition check to validate the JNI check:
✅ Received the expected native exception:
2024-05-10 17:29:48,969 [pool-3-thread-1] ERROR c.a.k.j.c.KinesisVideoJavaClientFactory - [PIC] KinesisVideoClientWrapper - putKinesisVideoEventMetadata(): STREAM_EVENT_TYPE cannot be negative.
By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.
Brings
PutEventMetadata
support for the Java Producer SDK through the following changes:StreamEventMetadata
class andStreamEventType
enum.PutEventMetadata
inNativeKinesisVideoProducerStream
.ImageFrameSource
for the DemoApp to use.Testing
The following testing and validation was conducted for various STREAM_EVENT_TYPE (StreamEventType in Java end) values using a KVS stream configured for image generation and notifications.
A. IMAGE_GENERATION - Valid Inputs
1. 0 StreamEventMetadata Name/Value Pairs
The first S3 object received contains an image of the footage:
✅ This image matches the first frame contained in the set of test .h264 files: Due to the specific format or packaging of our
.h264
test files, it was not readily possible to use an ffmpeg command to display the first frame as an image. An alternative technique was used to view the above first test frame which involved hardcoding the Java sample's image file index to remain at 0, so the first frame was constantly uploaded to KVS. Playing back the KVS stream at any recent point would then show that first frame.Note: Images will no longer be shown for the remaining test cases below due to redundancy.
✅ The S3 object contains no additional metadata as expected:
2. 1 StreamEventMetadata Name/Value Pair
✅ S3 saved image is valid. ✅ S3 metadata received as expected:
✅ The above successful tests were the case for pair counts from 1-9, but 10 failed as seen below.
3. 10 StreamEventMetadata Name/Value Pairs
❌ No image object in S3. ❌ No metadata. PutEventMetadata fails with
0x52000074 STATUS_MAX_FRAGMENT_METADATA_COUNT
. NOTE: This uncovered that the true limit to name/value pairs in PIC is 9, or 8 if using an S3imagePrefix
.4. Long-Running Test: 1 StreamEventMetadata Name/Value Pair
The following test was run for 11 hours:
✅ Images and tags were received in the S3 bucket after 11 hours, with no errors.
5. Null StreamEventMetadata
✅ S3 saved image is valid. ✅ The S3 object contains no additional metadata as expected.
B. IMAGE_GENERATION - Invalid Inputs
1. Invalid
Name
: "AWS"✅ Received the expected error status code:
0x52000077 | STATUS_INVALID_METADATA_NAME
2.
Name
Too LongLimited by MKV_MAX_TAG_NAME_LEN which is 128.
Testing using 128 characters:
✅ No error. The name/value pair is present in the S3 object:
Testing using 129 characters:
✅ Received the expected error status code:
0x5200008e | STATUS_INVALID_IMAGE_METADATA_KEY_LENGTH
3.
Value
Too LongLimited by MKV_MAX_TAG_VALUE_LEN which is 256.
Testing using 256 characters:
✅ No error. The name/value pair is present in the S3 object:
Testing using 257 characters:
✅ Received the expected error status code:
0x5200008f | STATUS_INVALID_IMAGE_METADATA_VALUE_LENGTH
4.
Names
is Empty, butnumberOfPairs
is> 0
✅ Received the expected error status code:
0x00000001 | STATUS_NULL_ARG
5.
Names
is Not Empty, butnumberOfPairs
is< Names.length
Using previously used arrays of 10 name/value pairs, but with numberOfPairs set to 1:
⚠️ We see only one name/value pair is saved in the object, so specifying the correct number of
numberOfPairs
is NOT optional:C. NONE
✅ Received the expected error status code:
0x00000002 | STATUS_INVALID_ARG
D. NOTIFICATION
Notification functionality was tested using an SNS topic with an email subscription. ✅ Received the expected notification via email with the expected SNS payload:
E. LAST
✅ Received the expected error status code:
0x00000002 | STATUS_INVALID_ARG
F. Multiple StreamEventType
Using bitwise OR, IMAGE_GENERATION (1 = 001) was combined with NOTIFICATION (2 = 010) to equal 3 (011):
✅ Both, the S3 object containing an image with tags, and the SNS email notification were received:
G. Negative StreamEventType
Care must be take here as the Java int passed to the JNI can be negative, while the StreamEventType parameter is an unsigned integer in PIC. Checks were placed in both the JNI and Java layers to error out if StreamEventType is negative.
✅ Received the expected Java error due to Precondition check:
java.lang.IllegalArgumentException
After removing the Java Precondition check to validate the JNI check: ✅ Received the expected native exception:
2024-05-10 17:29:48,969 [pool-3-thread-1] ERROR c.a.k.j.c.KinesisVideoJavaClientFactory - [PIC] KinesisVideoClientWrapper - putKinesisVideoEventMetadata(): STREAM_EVENT_TYPE cannot be negative.
By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.