VIF delivers detection results to event listeners which are Java classes that implement IVifEventListener. This reference documents that interface and the DetectionResponse class hierarchy passed to it. For a guided walkthrough with a worked example, see Create a custom VIF event listener.
package com.wowza.wms.plugin.videointelligence.api;
public interface IVifEventListener {
static String getVersion();
default void onInit(IApplicationInstance appInstance, IMediaStream stream,
Set<String> methods, HashMap<String, Object> properties);
default void onShutdown();
default boolean immediate(DetectionResponse response);
default boolean batch(ArrayList<DetectionResponse> responses);
default boolean rollup(DetectionResponse response);
}All five instance methods are default. An implementation only needs to override the ones relevant to it. A listener that only uses immediate delivery, for example, doesn't need to provide batch or rollup overrides at all; the interface's defaults cover the rest.
| Modifier and type | Method | Description |
|---|---|---|
static String | getVersion() | Returns the plugin API version. |
void | onInit(...) | Called once when the listener is attached to a stream. |
void | onShutdown() | Called once when the listener is detached or the stream stops. |
boolean | immediate(DetectionResponse) | Called per detection response, if methods includes immediate. |
boolean | batch(ArrayList<DetectionResponse>) | Called periodically with a batch of accumulated responses, if methods includes batch. |
boolean | rollup(DetectionResponse) | Called on a rollup interval with a response, if methods includes rollup. |
static String getVersion()Returns the version string of the IVifEventListener API your listener was compiled against — useful for logging or diagnostics when multiple listener versions may be in play.
default void onInit(IApplicationInstance appInstance,
IMediaStream stream,
Set<String> methods,
HashMap<String, Object> properties)Called once, when VIF attaches this listener to a stream.
Parameters:
appInstance— the WSE application instance the stream belongs to.stream— the media stream this listener instance is attached to.methods— the delivery modes configured for this listener (any combination of"immediate","batch","rollup"— seeEventMethodType).properties— the listener's configuredpropertiesmap fromvideo-intelligence.json, passed through as a rawHashMap<String, Object>. There's no schema enforcement at this layer — implementations read and type-convert each expected key themselves. Before callingonInit, VIF also writes a set of standard keys into this same map (see below).
Standard properties injected by VIF:
Before onInit is called, VIF adds the following keys to the properties map, on top of whatever you configured. They're written after your configured entries, so these names are reserved — a configured property that reuses one of these names is overwritten by VIF's value.
| Key | Value type in map | Description |
|---|---|---|
stream_name | String | Source stream name (stream.getName()). |
width | String | Source video width in pixels (from the stream's codec config). |
height | String | Source video height in pixels. |
vif_width | String | Width of the frame VIF sends to the detector — the inference resolution, derived from inference_video_height and the source aspect ratio. |
vif_height | String | Height of the frame VIF sends to the detector. |
frame_rate | String | Source frame rate in fps (rounded to a whole number). |
detector_type | String | The detector running on the stream: object, scene, vlm, or synthetic. |
confidence_threshold | Double | This listener's configured confidence_threshold (default 0.0, meaning no filtering) — the per-listener value, not the detector's object_analysis / scene_analysis threshold. |
Every value is inserted as a String except confidence_threshold, which is a Double. Because the map is typed <String, Object>, read the values defensively:
String streamName = (String) properties.get("stream_name");
int srcWidth = Integer.parseInt(properties.get("width").toString());
int srcHeight = Integer.parseInt(properties.get("height").toString());
int vifWidth = Integer.parseInt(properties.get("vif_width").toString());
int vifHeight = Integer.parseInt(properties.get("vif_height").toString());
int frameRate = Integer.parseInt(properties.get("frame_rate").toString());
String detector = (String) properties.get("detector_type");
double confidence = ((Number) properties.get("confidence_threshold")).doubleValue();Typical use: parse properties into typed fields, store appInstance/stream references, and set up any external resources (for example, obtaining a shared singleton like WebhookListener).
default void onShutdown()Called once, when the listener is detached from its stream or the stream stops. Release anything acquired in onInit here — timers, connections, in-progress work tied to this listener instance.
default boolean immediate(DetectionResponse response)Called for each individual detection response, only if "immediate" is in this listener's configured methods. Lowest-latency delivery path.
Returns: true if the response was consumed/acted on; false otherwise.
default boolean batch(ArrayList<DetectionResponse> responses)Called periodically with a group of accumulated responses, only if "batch" is in this listener's configured methods.
Returns: true if the batch was consumed/acted on; false otherwise.
default boolean rollup(DetectionResponse response)Called on a rollup interval with a response, only if "rollup" is in this listener's configured methods. For object detections, the rollup response carries statistical summaries (average, min, max, standard deviation) rather than raw per-frame values — see ObjectDetectionRollupData below.
Returns: true if the rollup was consumed/acted on; false otherwise.
package com.wowza.wms.plugin.videointelligence.event;
public enum EventMethodType {
DISABLED, IMMEDIATE, BATCH, ROLLUP
}The four values a listener's methods configuration maps to.
package com.wowza.wms.plugin.videointelligence.message;
public class DetectionResponse extends Message {
public String createdAt;
public DetectionWindowData detectionWindow;
public Integer preprocessTimeMs;
public Integer inferenceTimeMs;
public Integer postprocessTimeMs;
public Integer totalProcessingTimeMs;
public String detectionsType;
public Long sequenceId;
public <T> ArrayList<T> getDetections();
public void setDetections(ArrayList detections);
public DetectionResponse clone();
}The base class delivered to immediate, batch, and rollup. Fields are public, not getter-accessed — there's no getCreatedAt()/getSequenceId(), you read the fields directly.
At runtime, the object passed to your listener is always one of the concrete subclasses below, never a bare DetectionResponse — check detectionsType or use instanceof to determine which.
| Field | Type | Description |
|---|---|---|
createdAt | String | Timestamp the response was created. |
detectionWindow | DetectionWindowData | The frame/time range this response covers — see below. |
preprocessTimeMs / inferenceTimeMs / postprocessTimeMs / totalProcessingTimeMs | Integer | Per-stage processing time in milliseconds. |
detectionsType | String | Discriminates which concrete subclass this is. |
sequenceId | Long | Monotonically increasing sequence number for ordering responses. |
public class ObjectDetectionResponse extends DetectionResponse {
public ArrayList<ObjectDetectionData> detections;
}public class SceneDetectionResponse extends DetectionResponse {
// detections field is package-private; use getDetections()
public ArrayList<SceneDetectionData> getDetections();
}public class VlmDetectionResponse extends DetectionResponse {
public boolean isStructured;
public String modelName;
public String content;
public Integer tokenCount;
public Boolean truncated;
public static final String FREEFORM_CLASS_NAME;
public void parseContent();
public ArrayList<VlmDetectionData> getDetections();
}isStructured distinguishes Custom mode (a JSON schema response, isStructured = true) from Detect/Describe mode (free-text, isStructured = false). content holds the raw model output before parsing; parseContent() populates detections from it. FREEFORM_CLASS_NAME is the sentinel class name used for Describe mode results, which have no real class name.
package com.wowza.wms.plugin.videointelligence.message;
public class DetectionData {
public String className;
public Double confidence;
public String reasoning;
public String toJsonStr();
}The per-item entries inside getDetections(). reasoning is populated for VLM results (the model's stated justification for the class) and generally null for object/scene detections.
public class ObjectDetectionData extends DetectionData {
public Integer trackId;
public int frameId;
public BoundingBoxData bbox;
}trackId is null for detections without a confirmed tracking ID yet (VIF interleaves these with tracked detections — see the wall-clock-not-response-cadence guidance in the how-to article).
Both currently add no additional public fields beyond the DetectionData base (className, confidence, reasoning).
public class BoundingBoxData {
public int x;
public int y;
public int w;
public int h;
public int getX2(); // x + w
public int getY2(); // y + h
}Pixel coordinates in the analyzed frame. Not present at all for scene or VLM detections, since those aren't spatially localized.
public class DetectionWindowData {
public Long fromFrameId;
public Long toFrameId;
public Long frameCount;
public String fromFrame;
public String toFrame;
public Long fromTimeCode;
public Long toTimeCode;
public Long behindLiveMs;
public Boolean caughtUp;
public Long skippedFrames;
public Long skippedMs;
}behindLiveMs, caughtUp, skippedFrames, and skippedMs relate to VIF's catch-up-to-live behavior (see the catch_up_to_live / catch_up_max_behind_seconds config fields) — useful if your listener needs to know whether a given response reflects real-time analysis or catch-up-skipped frames.
Delivered inside rollup() responses for object detections — statistical summaries instead of raw per-frame values.
public class ObjectDetectionRollupData {
public Integer trackId;
public String className;
public ObjectDetectionRollupValue confidence, x, y, x2, y2, h, w;
public Integer firstFrameId;
public Integer lastFrameId;
public Double duration;
public Long samples;
}
public class ObjectDetectionRollupValue {
public Double avg, stdDev, min, max, first, last, sum;
public Long sampleSize;
}Each spatial/confidence value is summarized (average, min, max, standard deviation, first, last) over the rollup interval rather than delivered as a single point-in-time value.