Amazon Kinesis Video Streams Producer SDK Java 1.14.0 API

What is this SDK?

This SDK makes it easy to stream video from your Java application to AWS. It is a bridge that takes your video frames and safely delivers them to Amazon Kinesis Video Streams in the cloud, where you can then analyze, store, or stream them to viewers.

What it does for you:

  • Handles the complexity - You just provide video frames, it handles packaging, streaming, and error recovery
  • Secure by default - Automatic authentication and encrypted transmission
  • Reliable streaming - Built-in retry logic and connection management
  • Cross-platform - Works on Windows, macOS, and Linux

SDK Quick Start (3 steps)

// 1. Create a client
KinesisVideoClient client = KinesisVideoJavaClientFactory.createKinesisVideoClient(...);

// 2. Create a media source (sending video frames in a loop)
//    A media source represents a Kinesis Video Stream
MediaSource mediaSource = new YourMediaSource();

// 3. Start streaming (start the putFrame loop)
client.registerMediaSource(mediaSource);
mediaSource.start();

That's it! Your video is now streaming to AWS. See the demo apps for complete examples.

Demo Applications

  • DemoAppMain - Streams sample H.264 video files using com.amazonaws.kinesisvideo.java.mediasource.file.ImageFileMediaSource

Prerequisites

  • Java: Version 11, 17, or 21
  • Maven: For building the project
  • AWS Credentials: Access key and secret key
  • Native Library: Platform-specific JNI library (provided)

Pre-built Libraries Available

We provide pre-built native libraries for:

  • macOS (Intel & Apple Silicon)
  • Ubuntu Linux (x64)
  • Windows 10+
  • Raspberry Pi

Set the java.library.path JVM property to the directory containing the JNI library.

// Pre-built libraries are located in:
src/main/resources/lib/
├── mac/
├── ubuntu/
├── windows/
└── raspberry-pi/
Important: If your platform isn't listed, you'll need to build the JNI library yourself. See the building guide.

Running the Demo

# Build the project
mvn clean compile assembly:single

# Run the demo (replace with your values)
java -classpath target/*jar-with-dependencies.jar \
  -Daws.accessKeyId=YOUR_ACCESS_KEY \
  -Daws.secretKey=YOUR_SECRET_KEY \
  -Dkvs-stream=YOUR_STREAM_NAME \
  -Djava.library.path=src/main/resources/lib/mac \
  -Dlog4j.configurationFile=log4j2.xml \
  com.amazonaws.kinesisvideo.demoapp.DemoAppMain

Learn More

Click on any section below to dive deeper into the topics that interest you:

What is PIC?

Amazon Kinesis Video Streams PIC is a library containing Platform Independent Code for the Producer SDK written in C language.

Since PIC only contains platform independent logic, PIC is missing the platform-specific behavior, such as HTTP requests. The PIC client has a set of callbacks which an SDK can implement. PIC will invoke these callbacks at the appropriate time.

What is JNI?

The Java Native Interface (JNI) is a way for Java code to interact with the C (native) code. The JNI is written in C++ language.

For the official documentation and overview of JNI, see here.

The JNI layer creates the PIC client directly. The JNI implements the PIC callbacks to call the methods in Java, basically forwarding the call with its parameters.

  • When the Java side goes to call one of the methods in the JNI, the Java side uses the native keyword.
  • When the JNI side goes to call a Java method, it will use the built-in JNI methods to interact with the JVM. This process is similar to reflection.

How does Java know where the JNI library is located?

You will need to tell the JVM where the library is located. You can set the java.library.path JVM argument to point to the directory containing the JNI library for your system.

Result Handling & State Transitions (How PIC Decides Next Steps)

The Critical Pattern: Results Drive State Transitions

Summary: Every KVS API call result (HTTP status codes, success/failure) determines what PIC does next.

How it Works:
  1. PIC calls JNI, which calls Java for API calls (e.g., describeStream)
  2. Java makes HTTP call to AWS and gets an HTTP result
  3. Java forwards HTTP result back to PIC via xxxResult() methods
  4. PIC examines the result and decides the next state
  5. State machine steps to next state based on result

Example: DescribeStream Result Handling

// In PIC's fromDescribeStreamState() function:
switch (pKinesisVideoStream->base.result) {
    case SERVICE_CALL_RESULT_OK:
        if (streamStatus == ACTIVE) {
            // Stream exists and is active
            nextState = STREAM_STATE_GET_ENDPOINT;
        }
        break;
        
    case SERVICE_CALL_RESOURCE_NOT_FOUND:
        if (allowStreamCreation) {
            // Stream doesn't exist, create it
            nextState = STREAM_STATE_CREATE;
        } else {
            // Not allowed to create, stop
            nextState = STREAM_STATE_STOPPED;
        }
        break;
        
    default:
        // Error occurred, retry current state
        nextState = STREAM_STATE_DESCRIBE;
}

Finding the State Transition Logic

Want to understand exactly how PIC handles specific scenarios? Look at these files in the PIC source:

# Main state transition logic:
dependency/libkvspic/kvspic-src/src/client/src/StreamState.c

# Key functions to examine:
- fromDescribeStreamState()    // Handles describeStream results
- fromCreateStreamState()      // Handles createStream results
- fromGetEndpointStreamState() // Handles getStreamingEndpoint results
- fromGetTokenStreamState()    // Handles getStreamingToken results

# State machine execution:
dependency/libkvspic/kvspic-src/src/state/src/State.c
- stepStateMachine()           // Main state machine step function

PIC State Machine Execution Flow

Event Triggered stepStateMachine() executeCurrentState() Callback (JNI) Java Callback API Call xxxResult() callback fromCurrentState() Determine Next State
Advanced: State Machine Diagram

PIC Internal Stream States

The native PIC library manages these internal states. This is the expected "normal" state transition path for the Stream.

NEW DESCRIBE CREATE GET_ENDPOINT GET_TOKEN READY PUT_STREAM STREAMING
Advanced: JNI flow & Deep Dive

Key JNI Components

  • NativeKinesisVideoProducerJni: Main JNI interface class
  • NativeLibraryLoader: Handles loading platform-specific libraries
  • Callback Implementations: Java implementations for PIC callbacks
  • ProducerStreamSink: Bridges MediaSource to native producer stream

registerMediaSource() Complete Flow (Stream Setup)

Important Blocking Behavior:
  • registerMediaSource() blocks until the stream reaches READY state
  • The stream reaches READY state once all the AWS API calls (describeStream, createStream (if applicable), getStreamingEndpoint, getStreamingToken) successfully complete.
  • Only after streamReady() callback is fired does registerMediaSource() return
  • If any step fails, registerMediaSource() will throw an exception
client.registerMediaSource() JNI: createKinesisVideoStream() PIC: Stream Created (NEW state) State Machine Runs (NEW→READY) streamReady() callback registerMediaSource() returns

What Happens During State Machine Execution (NEW → READY)

NEW DESCRIBE CREATE (if needed) GET_ENDPOINT GET_TOKEN READY

putFrame() Complete Flow (Frame Ingestion)

After READY: Once registerMediaSource() returns, you can start calling putFrame() to send video data.

Your Application MediaSource.onFrame() ProducerStreamSink.onFrame() JNI: putKinesisVideoFrame() PIC: putFrame() MKV Assembly & Content Store

First putFrame() Triggers READY → STREAMING Transition

READY (waiting for frames) PUT_STREAM (first frame triggers) STREAMING (data flowing to KVS)

Content Store → getStreamData() → putMedia Threading Model

Summary:
  • Your MediaSource.start() calls putFrame() in a loop - putFrame() stores frames in PIC's content store (non-blocking)
  • Content store acts as a buffer between frame production and network transmission
  • getStreamData() runs on a separate thread created by ParallelSimpleHttpClient.sendPayloadInBackground() - it retrieves MKV-packaged data from the content store and sends it to KVS using HTTP chunked-transfer encoding.

getStreamData() Function Flow (PIC's Stream.c):

NativeDataInputStream.read() JNI: getStreamData() Check Upload Handle State Read Content View Fill Buffer with MKV Data Return to Java HTTP Chunked Upload

Java Classes Involved:

  • NativeDataInputStream: Java InputStream that calls getStreamData() to read data from PIC
  • NativeKinesisVideoProducerJni: JNI interface that bridges Java to native PIC functions
  • ParallelSimpleHttpClient: Creates background thread and manages HTTP connection to putMedia
  • PutMediaClient: High-level client that orchestrates the streaming process
Note

putMedia is a long-running HTTP connection that uploads many fragments continuously in a single connection. It is NOT a traditional RESTful API where you would upload one fragment at a time with separate HTTP requests.

What happens in PIC's getStreamData():

// Inside PIC's getStreamData() function:
1. Validate upload handle state (READY/STREAMING/TERMINATED)
2. Handle connection state (rollback on reconnect if needed)
3. Read from content view using contentViewGetNext()
4. Copy MKV fragments to caller buffer
5. Update view current position
6. Handle end-of-stream conditions
7. Return bytes filled in buffer
Stream Callbacks

What do Stream Callbacks do?

Stream callbacks notify the user of events happening during streaming, following the standard observability pattern. These callbacks enable client applications to customize the processing of streaming events asynchronously.

Examples include: streamErrorReport and fragmentAckReceived.

Note:

See AWS Documentation for more information.

Configuration

Summary: Configure the media source with the callbacks for each stream.

During media source registration with the client, the client will ask the media source for Stream Callbacks. If none are provided, it will use the default (no-op) callbacks.

Flow

  1. PIC calls JNI
  2. JNI calls NativeKinesisVideoProducerJni (Java)
  3. NativeKinesisVideoProducerJni forwards the call to NativeKinesisVideoProducerStream
  4. NativeKinesisVideoProducerStream forwards the call to the configured callbacks in the media source

See also:

All Packages Client API Producer API Common API Other Packages 
Package Description
com.amazonaws.kinesisvideo.ack  
com.amazonaws.kinesisvideo.auth  
com.amazonaws.kinesisvideo.client  
com.amazonaws.kinesisvideo.client.mediasource  
com.amazonaws.kinesisvideo.client.signing  
com.amazonaws.kinesisvideo.client.stream  
com.amazonaws.kinesisvideo.common.exception  
com.amazonaws.kinesisvideo.common.function  
com.amazonaws.kinesisvideo.common.preconditions  
com.amazonaws.kinesisvideo.config  
com.amazonaws.kinesisvideo.demoapp  
com.amazonaws.kinesisvideo.demoapp.auth  
com.amazonaws.kinesisvideo.demoapp.contants  
com.amazonaws.kinesisvideo.demoapp.debug  
com.amazonaws.kinesisvideo.encoding  
com.amazonaws.kinesisvideo.http  
com.amazonaws.kinesisvideo.internal.client  
com.amazonaws.kinesisvideo.internal.client.mediasource  
com.amazonaws.kinesisvideo.internal.mediasource  
com.amazonaws.kinesisvideo.internal.mediasource.bytes  
com.amazonaws.kinesisvideo.internal.mediasource.multitrack  
com.amazonaws.kinesisvideo.internal.producer  
com.amazonaws.kinesisvideo.internal.producer.client  
com.amazonaws.kinesisvideo.internal.producer.jni  
com.amazonaws.kinesisvideo.internal.service  
com.amazonaws.kinesisvideo.internal.service.exception  
com.amazonaws.kinesisvideo.java.auth  
com.amazonaws.kinesisvideo.java.client  
com.amazonaws.kinesisvideo.java.mediasource.file  
com.amazonaws.kinesisvideo.java.service  
com.amazonaws.kinesisvideo.model  
com.amazonaws.kinesisvideo.producer  
com.amazonaws.kinesisvideo.signing  
com.amazonaws.kinesisvideo.socket  
com.amazonaws.kinesisvideo.storage
Concrete implementations of StorageCallbacks.
com.amazonaws.kinesisvideo.stream.throttling  
com.amazonaws.kinesisvideo.streaming
Concrete implementations of StreamCallbacks.
com.amazonaws.kinesisvideo.util