Skip to content

Commit ef275ac

Browse files
authored
Merge 27d593b into 4f1e798
2 parents 4f1e798 + 27d593b commit ef275ac

File tree

2 files changed

+44
-13
lines changed

2 files changed

+44
-13
lines changed

README.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,17 @@ For audio only, run `./kvsAudioOnlyStreamingSample <stream-name> <streaming_dura
133133

134134
This will stream the audio files from the `samples/aacSampleFrames` or `samples/alawSampleFrames` (as per the choice of audio codec in the last argument) respectively.
135135

136+
### Fragment metadata
137+
138+
`./kvsVideoOnlyRealtimeStreamingSample` is the only sample that has the [fragment metadata](https://docs.aws.amazon.com/kinesisvideostreams/latest/dg/how-meta.html) implemented out of the box.
139+
140+
In addition to the required arguments above, this sample has an additional argument:
141+
```shell
142+
./kvsVideoOnlyRealtimeStreamingSample <stream-name> <video-codec> <streaming-duration-in-seconds> <sample-location> <num-metadata>
143+
```
144+
145+
`num-metadata` -- the number of sample fragment metadata key-value pairs that are added to each fragment. Min: 0, Max: 10. Default: 10.
146+
136147
### Setting log levels
137148

138149

samples/KvsVideoOnlyRealtimeStreamingSample.c

Lines changed: 33 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@
1111
#define VIDEO_CODEC_NAME_H264 "h264"
1212
#define VIDEO_CODEC_NAME_H265 "h265"
1313
#define VIDEO_CODEC_NAME_MAX_LENGTH 5
14+
#define METADATA_MAX_KEY_LENGTH 128
15+
#define METADATA_MAX_VALUE_LENGTH 256
16+
#define MAX_METADATA_PER_FRAGMENT 10
1417

1518
#define NUMBER_OF_FRAME_FILES 403
1619

@@ -57,10 +60,10 @@ INT32 main(INT32 argc, CHAR* argv[])
5760
STREAM_HANDLE streamHandle = INVALID_STREAM_HANDLE_VALUE;
5861
STATUS retStatus = STATUS_SUCCESS;
5962
PCHAR accessKey = NULL, secretKey = NULL, sessionToken = NULL, streamName = NULL, region = NULL, cacertPath = NULL;
60-
CHAR frameFilePath[MAX_PATH_LEN + 1];
63+
CHAR frameFilePath[MAX_PATH_LEN + 1], metadataKey[METADATA_MAX_KEY_LENGTH + 1], metadataValue[METADATA_MAX_VALUE_LENGTH + 1];
6164
Frame frame;
6265
BYTE frameBuffer[200000]; // Assuming this is enough
63-
UINT32 frameSize = SIZEOF(frameBuffer), frameIndex = 0, fileIndex = 0;
66+
UINT32 frameSize = SIZEOF(frameBuffer), frameIndex = 0, fileIndex = 0, n = 0, numMetadata = 10;
6467
UINT64 streamStopTime, streamingDuration = DEFAULT_STREAM_DURATION;
6568
DOUBLE startUpLatency;
6669
BOOL firstFrame = TRUE;
@@ -70,8 +73,8 @@ INT32 main(INT32 argc, CHAR* argv[])
7073
VIDEO_CODEC_ID videoCodecID = VIDEO_CODEC_ID_H264;
7174

7275
if (argc < 2) {
73-
DLOGE("Usage: AWS_ACCESS_KEY_ID=SAMPLEKEY AWS_SECRET_ACCESS_KEY=SAMPLESECRET %s <stream_name> <codec> <duration_in_seconds> "
74-
"<frame_files_path>\n",
76+
DLOGE("Usage: AWS_ACCESS_KEY_ID=SAMPLEKEY AWS_SECRET_ACCESS_KEY=SAMPLESECRET %s <stream_name>"
77+
"<codec> <duration_in_seconds> <frame_files_path> [num_metadata = 10]\n",
7578
argv[0]);
7679
CHK(FALSE, STATUS_INVALID_ARG);
7780
}
@@ -81,33 +84,39 @@ INT32 main(INT32 argc, CHAR* argv[])
8184
CHK(FALSE, STATUS_INVALID_ARG);
8285
}
8386

84-
MEMSET(frameFilePath, 0x00, MAX_PATH_LEN + 1);
85-
if (argc < 5) {
86-
STRCPY(frameFilePath, (PCHAR) "../samples/");
87-
} else {
88-
STRNCPY(frameFilePath, argv[4], MAX_PATH_LEN);
89-
}
90-
9187
cacertPath = getenv(CACERT_PATH_ENV_VAR);
9288
sessionToken = getenv(SESSION_TOKEN_ENV_VAR);
9389
streamName = argv[1];
9490
if ((region = getenv(DEFAULT_REGION_ENV_VAR)) == NULL) {
9591
region = (PCHAR) DEFAULT_AWS_REGION;
9692
}
9793

98-
if (argc >= 3) {
94+
if (argc >= 3 && !IS_EMPTY_STRING(argv[2])) {
9995
if (!STRCMP(argv[2], VIDEO_CODEC_NAME_H265)) {
10096
STRNCPY(videoCodec, VIDEO_CODEC_NAME_H265, STRLEN(VIDEO_CODEC_NAME_H265));
10197
videoCodecID = VIDEO_CODEC_ID_H265;
10298
}
10399
}
104100

105-
if (argc >= 4) {
101+
if (argc >= 4 && !IS_EMPTY_STRING(argv[3])) {
106102
// Get the duration and convert to an integer
107103
CHK_STATUS(STRTOUI64(argv[3], NULL, 10, &streamingDuration));
108104
streamingDuration *= HUNDREDS_OF_NANOS_IN_A_SECOND;
109105
}
110106

107+
MEMSET(frameFilePath, 0x00, MAX_PATH_LEN + 1);
108+
if (argc >= 5 && !IS_EMPTY_STRING(argv[4])) {
109+
STRNCPY(frameFilePath, argv[4], MAX_PATH_LEN);
110+
} else {
111+
STRCPY(frameFilePath, (PCHAR) "../samples/");
112+
}
113+
114+
if (argc >= 6 && !IS_EMPTY_STRING(argv[5])) {
115+
numMetadata = STRTOUL(argv[5], NULL, 10);
116+
DLOGD("numMetadata: %d\n", numMetadata);
117+
CHK(numMetadata <= MAX_METADATA_PER_FRAGMENT, STATUS_INVALID_ARG);
118+
}
119+
111120
streamStopTime = GETTIME() + streamingDuration;
112121

113122
// default storage size is 128MB. Use setDeviceInfoStorageSize after create to change storage size.
@@ -154,6 +163,17 @@ INT32 main(INT32 argc, CHAR* argv[])
154163

155164
CHK_STATUS(readFrameData(&frame, frameFilePath, videoCodec));
156165

166+
// Add the fragment metadata key-value pairs
167+
// For limits, refer to https://docs.aws.amazon.com/kinesisvideostreams/latest/dg/limits.html#limits-streaming-metadata
168+
if (numMetadata > 0 && frame.flags == FRAME_FLAG_KEY_FRAME) {
169+
DLOGD("Adding metadata! frameIndex: %d", frame.index);
170+
for (n = 1; n <= numMetadata; n++) {
171+
SNPRINTF(metadataKey, METADATA_MAX_KEY_LENGTH, "TEST_KEY_%d", n);
172+
SNPRINTF(metadataValue, METADATA_MAX_VALUE_LENGTH, "TEST_VALUE_%d", frame.index + n);
173+
CHK_STATUS(putKinesisVideoFragmentMetadata(streamHandle, metadataKey, metadataValue, TRUE));
174+
}
175+
}
176+
157177
CHK_STATUS(putKinesisVideoFrame(streamHandle, &frame));
158178
if (firstFrame) {
159179
startUpLatency = (DOUBLE) (GETTIME() - startTime) / (DOUBLE) HUNDREDS_OF_NANOS_IN_A_MILLISECOND;

0 commit comments

Comments
 (0)