-
Notifications
You must be signed in to change notification settings - Fork 4
gwp developer guide
The Genetec Web Player (GWP) is a JavaScript/TypeScript library designed to embed live and playback video streams from Genetec Security Center™ into custom web applications. It offers advanced video streaming capabilities using WebSockets and Media Source Extensions, providing an easy-to-use API while abstracting the complexities of managing streams, codecs, and security.
This guide provides detailed instructions for integrating the GWP into your application, including setup, authentication, and usage examples for advanced features like PTZ control, timeline management, and diagnostics.
Additional Documentation:
- GWP API Reference - Complete technical API reference with all interfaces, methods, properties, events, and enumerations
- Sample Application - Comprehensive working example demonstrating all GWP features, perfect for testing and debugging
-
Client:
- GWP runs in the browser, using WebSockets and Media Source Extensions for streaming.
- All video/audio decoding is handled by the browser, leveraging hardware acceleration when available.
-
Server:
- The Media Gateway role in Security Center streams video/audio and handles transcoding if needed.
- The web server hosting your application must be able to reach the Media Gateway.
-
Authentication:
- Uses Security Center users for secure token retrieval.
- All user privileges are enforced by the Media Gateway.
-
Data Flow:
- Browser (GWP) establishes a secure WebSocket (WSS) to the Media Gateway.
- Token retrieval is handled via a callback function.
- Video/audio streams are delivered directly to the browser.
- Live and Playback Video Streaming: Access real-time and recorded video feeds.
- Audio Support: Stream AAC audio where supported.
- PTZ Camera Control: Low-latency Pan-Tilt-Zoom control.
- Dynamic Stream Selection: Adaptive resolution and bitrate adjustment based on player size.
- Digital Zoom: Enhance video regions for detailed views.
- Fisheye Dewarping: Correct fisheye distortions for a traditional PTZ-like experience.
- Timeline API: Access bookmarks and motion detection events.
- Diagnostics: Tools for debugging and monitoring.
-
Media Gateway Role:
- The Media Gateway Role must be configured in Security Center. See the Media Gateway Developer Guide for setup instructions.
- Open ports 80 and 443 for public access.
- Ensure the Media Gateway and GWP library versions are compatible.
-
Authentication:
- Security Center user credentials.
-
Environment Requirements:
- Supported Browsers: Chrome, Firefox, Edge, Safari, Internet Explorer 11.
-
Camera GUIDs: Unique identifiers for the cameras you wish to stream.
To use the Genetec Web Player, users must have the appropriate Security Center privileges configured.
Important
A local user account with the necessary privileges listed below will work. The user must also have access rights to the partition where the camera is located.
These privileges are required for all GWP applications:
- Log on using the SDK: Allows the user to run SDK applications and authenticate with the Media Gateway.
- View camera properties: Allows the user to view camera configurations.
- Live hit monitoring: Allows the user to open the Live hit monitoring task in the Web App.
These privileges are only required if your application uses the corresponding features:
-
View live video: Required to view live video streams from cameras (when using
playLive()). -
View playback: Required to view recorded/playback video from cameras (when using
seek()or playback features).
For PTZ camera control functionality, the following table maps GWP PTZ methods to their required Security Center privileges:
| GWP PTZ Method(s) | Required Privilege | Description |
|---|---|---|
startPanTilt(), stopPanTilt(), startZoom(), stopZoom(), stop(), goHome()
|
Perform basic operations | Allows basic PTZ operations (pan, tilt, zoom, and stop movements) |
goToPreset(preset) |
Use presets | Allows the user to move the camera to preset positions |
runPattern(pattern) |
Use patterns | Allows the user to run camera movement patterns |
lock(), unlock()
|
Lock PTZ | Allows the user to lock and unlock PTZ controls |
startFocus(), stopFocus(), startIris(), stopIris()
|
Change focus and iris settings | Allows the user to adjust camera focus and iris settings |
Note
PTZ privileges are hierarchical. The parent privilege "View live video" must be granted before any PTZ motor privileges can take effect.
Configuration Note: All privileges can be configured in Security Center Config Tool under User Management. Ensure that users or user groups are granted the necessary privileges and have access rights to the partitions containing the cameras they need to access.
This section provides a minimal working example to get you started quickly. For detailed explanations, see the subsequent sections.
<!DOCTYPE html>
<html>
<head>
<title>GWP Quick Start</title>
</head>
<body>
<div id="playerContainer" style="width: 640px; height: 480px;"></div>
<script src="https://<YourMediaGatewayAddress>/media/v2/files/gwp.js"></script>
<script src="app.js"></script>
</body>
</html>// Configuration
const mediaGatewayEndpoint = 'https://<YourMediaGatewayAddress>/media';
const cameraGuid = '00000000-0000-0000-0000-000000000000'; // Replace with your camera GUID
const username = 'admin';
const sdkCertificate = 'YourSDKCertificate'; // From Security Center license
const password = 'yourPassword';
// Token retrieval function
const getTokenFct = async (cameraId) => {
const response = await fetch(`${mediaGatewayEndpoint}/v2/token/${cameraId}`, {
credentials: 'include',
headers: {
'Authorization': `Basic ${btoa(username + ";" + sdkCertificate + ":" + password)}`
}
});
if (!response.ok) {
throw new Error(`Failed to fetch token: ${response.statusText}`);
}
return await response.text();
};
// Initialize player
async function startPlayer() {
try {
// Create player instance
const divContainer = document.getElementById('playerContainer');
const webPlayer = gwp.buildPlayer(divContainer);
// Register error handler
webPlayer.onErrorStateRaised.register((error) => {
console.error(`Error ${error.errorCode}: ${error.value}`);
});
// Start and connect to camera
await webPlayer.start(cameraGuid, mediaGatewayEndpoint, getTokenFct);
// Play live video
webPlayer.playLive();
console.log('Player started successfully!');
} catch (error) {
console.error('Failed to start player:', error);
}
}
// Start when page loads
startPlayer();If you see CORS errors, configure the Media Gateway to allow your origin. See the Troubleshooting section.
Next Steps: Continue reading for detailed information on authentication, privileges, PTZ control, playback, and advanced features.
The GWP library can be included in two ways:
<script src="https://<MediaGatewayAddress>/media/v2/files/gwp.js"></script>const gwp = require('<MediaGatewayAddress>/media/v2/files/gwp');Important
It is strongly recommended to load the GWP library directly from your Media Gateway server using the URLs shown above. Each Security Center version includes a specific gwp.js file designed for that version. While you can download and cache the gwp.js file separately, this approach is not recommended as using a mismatched GWP version (e.g., an older gwp.js with a newer Security Center version) may result in compatibility issues, broken functionality, or unexpected behavior. Always ensure the GWP library version matches your Media Gateway version.
Ensure the GWP library version matches the Media Gateway version. To retrieve the version:
console.log(gwp.version);The version displayed should match your Security Center/Media Gateway version to ensure full compatibility.
In Security Center, a Role represents a specific task with its configuration, while Agents are servers assigned to perform that role's work. When you create a Media Gateway role in Security Center, every agent assigned to this role shares the same configuration.
The Genetec Web Player connects to a specific Media Gateway agent. You must provide the public address of this agent in the start() method.
If you have multiple Media Gateway agents, you are responsible for implementing load balancing logic in your application. The GWP does not automatically load balance between agents.
Simple Approach: Alternate between agents in a round-robin fashion.
Advanced Load Balancing should consider:
- Current Server Load - Distribute connections evenly across all agents
- Resource Sharing - Streaming the same camera twice from the same agent is more efficient than using two different agents
- Network Topology - Avoid long-distance redirection; prefer geographically closer agents
- Agent Health - Monitor agent availability and route away from unhealthy agents
Example:
const mediaGatewayAgents = [
'https://gateway1.example.com/media',
'https://gateway2.example.com/media',
'https://gateway3.example.com/media'
];
let currentAgentIndex = 0;
function getNextMediaGatewayAgent() {
const agent = mediaGatewayAgents[currentAgentIndex];
currentAgentIndex = (currentAgentIndex + 1) % mediaGatewayAgents.length;
return agent;
}
// Use when starting player
const mediaGatewayEndpoint = getNextMediaGatewayAgent();
await webPlayer.start(cameraGuid, mediaGatewayEndpoint, getTokenFct);To connect to the Media Gateway and stream video, the GWP requires a security token. This token is obtained by authenticating with Security Center user credentials (username, password, and SDK certificate). The token contains all Security Center user privileges, which are enforced by the Media Gateway. Only users with the correct Security Center permissions (such as "Log on using the SDK" and "View live video") can retrieve tokens and access video streams.
Tokens can be obtained via the Media Gateway's /v2/token/{cameraId} endpoint.
API Endpoint:
GET /v2/token/{cameraId}
Headers:
Authorization: Basic <Base64(username;sdkCertificate:password)>
Example:
const getTokenFct = async (cameraId) => {
const response = await fetch(`${mediaGatewayEndpoint}/v2/token/${cameraId}`, {
credentials: 'include',
headers: {
'Authorization': `Basic ${btoa(username + ";" + sdkCertificate + ":" + password)}`
}
});
if (!response.ok) {
throw new Error(`Failed to fetch token: ${response.statusText}`);
}
return await response.text();
};- Do Not Hardcode Credentials: Use server-side logic to fetch tokens securely. The recommended approach is for your backend to handle token requests using Security Center user credentials, then pass the token to the browser.
Summary:
- GWP relies on Security Center users for authentication and token retrieval.
- The token is what authorizes and scopes access to video streams.
- All user privileges are enforced by the Media Gateway based on the Security Center user account used for token generation.
A player (or IWebPlayer) represents a single video stream displayed in your web page. The player goes through distinct states during its lifetime:
Players are anchored in an existing empty HTML div element on your web page.
const divContainer = document.getElementById('playerContainer');
const webPlayer = gwp.buildPlayer(divContainer);At this stage:
- The player displays a black background
- No connection to Media Gateway has been established
- The player tries to use as much space as possible in the div element
- Now is the time to register event handlers before starting the player
Next steps: Either start the player or dispose of it.
The start() method initializes the connection with a Media Gateway for a specific camera (but doesn't play anything until you call playLive() or seek()).
await webPlayer.start(cameraGuid, mediaGatewayEndpoint, getTokenFct);Parameters:
-
cameraGuid: The unique identifier of the camera in 8-4-4-4-12 format (e.g.,"00000001-0000-babe-0000-080023e940c6") -
mediaGatewayEndpoint: The Media Gateway's public address (e.g.,"https://hostname.com/media") -
getTokenFct: A callback function returning a token (see Authentication)
This call returns a Promise:
- Succeeds once initialization and connection to Media Gateway is complete
- Fails if connection cannot be established (invalid parameters, network issues, or token problems)
- You cannot use the player until the promise completes
Alternative: Use startWithService() for WebSocket multiplexing (see Advanced: Multiplexing Multiple Players)
Once started, all player commands can be called. Commands are immediate but are queued internally and handled asynchronously.
Playing a Live Stream:
webPlayer.playLive();Playback Controls:
// Seek to a specific time
webPlayer.seek(new Date('2023-12-24T10:00:00Z'));
// Pause and Resume
webPlayer.pause();
webPlayer.resume();
// Adjust playback speed (0.01 to 100, or -100 to -0.01 for reverse)
webPlayer.setPlaySpeed(2); // Fast-forward at 2x speed
webPlayer.setPlaySpeed(-6); // Reverse playback at 6x speedOther Controls:
// Enable audio
webPlayer.setAudioEnabled(true);
// Enable PTZ low-latency mode
webPlayer.setPtzMode(true);
// Toggle privacy protection
webPlayer.togglePrivacy();
// Show diagnostic overlay
webPlayer.showDebugOverlay(true);Next steps: Either stop the player or dispose of it when done.
Calling stop() on a started player will stop and clear any stream currently being displayed.
webPlayer.stop();After stopping:
- No video will be displayed (black background)
- You can
start()again with a different camera or Media Gateway - It's generally better to reuse a player for performance and to avoid changing the web page layout
Disposing will free all resources and remove everything from the HTML div element.
webPlayer.dispose();Important
- The player instance becomes completely unusable after disposal
- Unregister all event handlers before disposing
- The DOM container is cleared
The GWP provides error events to help you handle issues such as network problems, invalid tokens, permission errors, or server outages. Proper error handling improves user experience and aids in troubleshooting.
The player provides the onErrorStateRaised event that fires when an error occurs. Always register an error handler:
webPlayer.onErrorStateRaised.register((error) => {
console.error(`Error ${error.errorCode}: ${error.value}`);
if (error.isFatal) {
// Fatal errors stop the player
handleFatalError(error);
} else {
// Non-fatal errors may allow continued operation
handleNonFatalError(error);
}
});The ErrorStatusEvent object contains:
-
errorCode (number): The error code from the
ErrorCodeenum - value (string): Textual description of the error (not localized)
- isFatal (boolean): Indicates whether the error stops the player
The GWP uses the following error codes (from the ErrorCode enum):
| Error Code | Value | Description | Suggested Action |
|---|---|---|---|
Unknown |
0 | Unknown error | Display generic error message and retry |
ConnectionLost |
2 | Connection lost | Attempt to reconnect or notify user |
InsufficientDiskSpace |
3 | Server has disk space issues | Notify user, contact administrator |
ConnectionFailed |
4 | Connection failed | Check network connectivity, retry |
StreamNotFound |
6 | Stream not found | Verify camera GUID, check camera availability |
RequestTimedOut |
9 | Request timed out | Retry operation |
UnitPlaybackUnavailable |
11 | Video unit can't do playback | Notify user that playback is unavailable |
LiveCapacityExceeded |
12 | Live stream limit reached | Notify user, try again later |
PlaybackCapacityExceeded |
13 | Playback stream limit reached | Notify user, try again later |
UnsupportedEncoding |
14 | Unsupported codec | Check camera configuration |
DatabaseUpgradeRequired |
15 | Media Router database needs upgrade | Contact administrator |
InsufficientPrivilege |
16 | User lacks required privileges | Check Security Center privileges, contact administrator |
InsufficientCapability |
17 | Video unit cannot process command | Check camera/server capabilities |
MissingCertificate |
18 | Cannot decrypt encrypted stream | Check encryption certificates |
NotSupported |
20 | Command not supported | Check feature availability |
CantUsePrivateKey |
21 | Certificate missing private key | Check certificate configuration |
DeniedByServer |
23 | Server rejected the request | Check permissions and configuration |
NoTranscodingAllowed |
24 | Transcoding is prevented | Check Media Gateway configuration |
ForbiddenTransformation |
32 | Stream transformation requires transcoding | Adjust stream settings or enable transcoding |
CloudPlaybackFailure |
33 | Unable to play from cloud | Check cloud configuration |
UnsupportedOmnicastFederationRole |
34 | Omnicast Federation Role not supported | Check federation configuration |
UpdateSessionError |
1000 | Invalid stream state | Restart player session |
webPlayer.onErrorStateRaised.register((error) => {
switch (error.errorCode) {
case 16: // InsufficientPrivilege
displayError('Access denied. You do not have permission to view this camera. Please contact your administrator.');
break;
case 2: // ConnectionLost
case 4: // ConnectionFailed
displayError('Network connection lost. Attempting to reconnect...');
// Optionally implement retry logic
break;
case 6: // StreamNotFound
displayError('Camera not found. Please verify the camera is online and try again.');
break;
case 9: // RequestTimedOut
displayError('Request timed out. Please check your network connection and try again.');
break;
case 12: // LiveCapacityExceeded
case 13: // PlaybackCapacityExceeded
displayError('Server capacity limit reached. Please try again later.');
break;
default:
displayError(`An error occurred: ${error.value}`);
console.error('Error details:', error);
}
});
function displayError(message) {
const errorDiv = document.getElementById('errorDiv');
errorDiv.textContent = message;
errorDiv.style.display = 'block';
}In addition to error events, you can monitor the streaming connection status:
webPlayer.onStreamStatusChanged.register((status) => {
console.log(`Connection status: ${status.state} - ${status.value}`);
// Handle specific connection states
if (status.state === 5) { // Streaming
console.log('Successfully streaming');
} else if (status.state === 31) { // UnauthorizedToken
console.error('Token was denied - check user privileges');
}
});Refer to the StreamingConnectionStatus enum in the TypeScript definitions for a complete list of connection status codes.
The player must be connected to the Media Gateway to stream video. Various situations can prevent or interrupt streaming, and the GWP handles connection issues differently depending on whether they are recoverable.
When you call start(), the player establishes a connection to the Media Gateway. This method returns a Promise:
try {
await webPlayer.start(cameraGuid, mediaGatewayEndpoint, getTokenFct);
console.log('Player started successfully');
} catch (error) {
console.error('Failed to start player:', error);
// Possible causes: invalid parameters, network issues, invalid token
// You can periodically retry if connectivity might be restored
}Once the player is successfully started, if any streaming problem occurs later, the player will automatically attempt to reconnect and recover to its previous state (e.g., playing live video).
The onStreamStatusChanged event will fire with the value ConnectingToMediaGateway (status code -1) once a connection timeout occurs:
webPlayer.onStreamStatusChanged.register((status) => {
if (status.state === -1) {
console.log('Connection lost, attempting to reconnect...');
} else if (status.state === 5) {
console.log('Successfully streaming');
}
});Recoverable Errors: Most streaming problems are considered recoverable, and the player will automatically go back to a valid state when the issue is resolved:
- Connection timeouts
- Network interruptions
- Temporary server issues
- Camera temporarily offline
Non-Recoverable Errors:
Some errors require you to manually restart the player (call stop(), then start() again):
| Status | Code | Description | Required Action |
|---|---|---|---|
NotEnoughBandwidth |
19 | Bandwidth limit reached | Stop and restart player when bandwidth is available |
MediaRouterStreamNotFound |
22 | Media Router couldn't find stream | Verify camera configuration, restart player |
StreamUnreachable |
25 | No route found for stream | Check network topology, restart player |
UnauthorizedToken |
31 | Token was denied | Verify user privileges and token, restart player |
Example: Handling Non-Recoverable Errors
webPlayer.onStreamStatusChanged.register((status) => {
const nonRecoverableStates = [19, 22, 25, 31];
if (nonRecoverableStates.includes(status.state)) {
console.error('Non-recoverable error:', status.value);
// Display error to user
displayError(`Cannot stream: ${status.value}. Please try again.`);
// Cleanup and prepare for restart
webPlayer.stop();
// Optionally: implement retry logic with delay
setTimeout(() => {
retryPlayerStart();
}, 5000);
}
});-
Handle Initial Connection Failures: Always wrap
start()in a try-catch block -
Monitor Connection Status: Register to
onStreamStatusChangedto track connection health - Provide User Feedback: Display meaningful messages during reconnection attempts
- Implement Retry Logic: For non-recoverable errors, consider implementing exponential backoff retry
- Avoid Automatic Retries on User Errors: Don't auto-retry if the error is due to insufficient privileges or invalid configuration
Consider a large retail store using PTZ cameras to monitor different sections. A user can program the PTZ to focus on high-traffic areas during peak hours and adjust manually when suspicious activity is detected:
// Move the camera to monitor entrance
const ptz = webPlayer.ptzControl;
ptz.goToPreset(1); // Preset 1 is configured for the main entrance
// Follow a suspicious individual
ptz.startPanTilt(0.3, -0.2); // Pan right and tilt down
setTimeout(() => ptz.stopPanTilt(), 5000); // Stop after 5 seconds
// Zoom in for a closer look
ptz.startZoom(0.5); // Slowly zoom in
setTimeout(() => ptz.stopZoom(), 3000); // Stop after 3 secondsA security operator in a corporate setting may want to review past events, such as motion detection in restricted areas:
// Set a timeline range to view activity during the night shift
webPlayer.timelineProvider.setTimelineRange(new Date('2023-12-23T22:00:00Z'), new Date('2023-12-24T06:00:00Z'));
// Display bookmarks and motion detection events
webPlayer.timelineProvider.onTimelineContentUpdated.register(({ events }) => {
events.forEach(event => {
if (event.kind === 1) { // Bookmark
console.log(`Bookmark: ${event.details} at ${event.time}`);
} else if (event.kind === 0) { // Recording sequence
console.log(`Motion detected: starts at ${event.time} for ${event.duration}s`);
}
});
});The GWP supports Pan-Tilt-Zoom (PTZ) control for compatible cameras.
const ptz = webPlayer.ptzControl;
ptz.startPanTilt(0.5, 0.3); // Start panning and tilting
ptz.stopPanTilt(); // Stop movement
ptz.startZoom(1); // Zoom in
ptz.stopZoom(); // Stop zooming
ptz.goToPreset(1); // Move to a preset positionThe Timeline API allows you to query and display playback metadata, including recorded video sequences and user bookmarks. The API is designed for graphical timeline representations and focuses on a "range of interest" (the visible portion of the timeline).
Important Limitations:
- Maximum range: 72 hours between start and end time
- Recommended range: 24 hours or less for optimal performance
- The API does not provide user actions (like adding bookmarks) - use the Web SDK or REST SDK for those operations
Setting Timeline Range:
You must set a range of interest before receiving timeline updates. The range can include future times for live updates:
// Set a 24-hour range
const startTime = new Date('2023-12-24T00:00:00Z');
const endTime = new Date('2023-12-25T00:00:00Z');
webPlayer.timelineProvider.setTimelineRange(startTime, endTime);Important
Register your event handler BEFORE calling setTimelineRange() to avoid missing initial data.
Handling Timeline Updates:
The onTimelineContentUpdated event fires whenever the timeline content changes within your range of interest:
webPlayer.timelineProvider.onTimelineContentUpdated.register((event) => {
console.log('Coverage:', event.coverageStart, 'to', event.coverageEnd);
console.log('Events:', event.events);
event.events.forEach((timelineEvent) => {
if (timelineEvent.kind === 0) {
// RecordingSequence
console.log('Recording from', timelineEvent.time,
'duration:', timelineEvent.duration, 'seconds');
} else if (timelineEvent.kind === 1) {
// Bookmark
console.log('Bookmark at', timelineEvent.time,
'details:', timelineEvent.details);
}
});
});Timeline Event Structure:
interface TimelineContentEvent {
coverageStart: Date; // Start of updated range
coverageEnd: Date; // End of updated range
events: TimelineEvent[]; // All events in coverage range
}
interface TimelineEvent {
time: Date; // Event time or start time
duration?: number; // Duration in seconds (for sequences)
details?: string; // User-provided details (for bookmarks)
kind: 0 | 1; // 0 = RecordingSequence, 1 = Bookmark
}Understanding Coverage:
The coverageStart and coverageEnd define which part of the timeline was updated. This can be smaller than your range of interest - areas outside the coverage are considered untouched:
// Your range: 00:00 to 24:00
// Coverage received: 10:00 to 14:00
// Interpretation: Only data between 10:00-14:00 changed;
// data before 10:00 and after 14:00 remains unchangedHandling Overlapping Sequences:
Sequences may overlap between updates. You must merge overlapping sequences to build the complete timeline:
function mergeSequences(existingSequences, newSequences) {
// Merge logic: combine overlapping sequences
// This is left as an exercise - implement based on your UI needs
return mergedSequences;
}Live Updates:
If the endTime is in the future, you'll periodically receive updates for new live recordings:
// Set range including future time for live updates
const now = new Date();
const future = new Date(now.getTime() + (60 * 60 * 1000)); // +1 hour
webPlayer.timelineProvider.setTimelineRange(now, future);
// You'll receive updates as new recordings become availableTimeline Dynamics:
Timeline content can change in real-time:
- Sequences may get shorter, longer, or disappear
- Archivers going offline/online affects sequence availability
- Retention policies may delete old archives
- Multiple sources (camera, auxiliary archivers) create overlapping sequences
The "Near-Live" Gap:
There's typically a small gap (a few seconds) between the last recorded sequence and "live" time. This is the time it takes for live frames to be written to the archiver and become available for playback. This gap is called the "near-live" period.
The GWP supports digital zoom when available (check if webPlayer.digitalZoomControl is non-null). Digital zoom allows users to magnify specific regions of the video for detailed viewing.
Key Features:
- Zoom factor from 1x (no zoom) to 20x maximum
- Navigate around the zoomed image
- Optional preview canvas showing the zoomed region
- Can zoom into black bars when video aspect ratio doesn't match container
Basic Usage:
const zoom = webPlayer.digitalZoomControl;
if (zoom) {
// Zoom to a specific point
zoom.goTo(0.5, 0.5, 2); // x, y (normalized 0-1), zoom factor
// Zoom into the center of current view
zoom.zoom(3); // Zoom factor 3x
// Move around at current zoom level
zoom.move(0.2, -0.1); // Move right and up (normalized -1 to 1)
// Zoom with focus point (keeps point at same location)
zoom.zoomWithFocus(0.3, 0.3, 5); // x, y, zoom factor
// Reset to full image
zoom.stop();
// Get current position
console.log(`Position: (${zoom.X}, ${zoom.Y}), Zoom: ${zoom.Zoom}x`);
}Digital Zoom Preview:
The optional preview canvas shows an overview of the full image with the zoomed region highlighted:
const preview = zoom.Preview;
// Enable/disable the preview
preview.Enabled = true;
// Access the preview canvas for customization
const canvas = preview.Canvas;
canvas.style.position = 'absolute';
canvas.style.top = '10px';
canvas.style.left = '10px';
canvas.style.border = '2px solid white';Default User Interactions:
The GWP provides built-in mouse/touch interactions for convenience:
On Player Canvas:
- Click and drag: Moves the zoomed view - the center follows the cursor position
- Mouse wheel: Not implemented by default (you must implement this yourself if needed)
On Preview Canvas:
- Click: Centers the zoomed view on the clicked point
- Drag: Continuously updates the center as you drag
Customizing or Disabling Interactions:
You can override default interactions by intercepting JavaScript events during the capture phase:
// Example: Disable default drag behavior
divContainer.addEventListener('mousedown', (event) => {
event.stopPropagation(); // Prevents GWP's default handler
// Implement your custom behavior here
}, true); // true = capture phaseImplementing Mouse Wheel Zoom:
The GWP doesn't handle mouse wheel by default. Here's a complete implementation:
const zoom = webPlayer.digitalZoomControl;
divContainer.addEventListener('wheel', (event) => {
event.preventDefault();
if (!zoom) return;
const delta = event.deltaY > 0 ? -0.5 : 0.5; // Scroll direction
const newZoom = Math.max(1, Math.min(20, zoom.Zoom + delta));
zoom.zoom(newZoom);
}, { passive: false });Taking Snapshots of Zoomed View:
// Snapshot of the zoomed portion only
const imageData = zoom.snapshot();
if (imageData) {
// Convert to downloadable image
const canvas = document.createElement('canvas');
canvas.width = imageData.width;
canvas.height = imageData.height;
const ctx = canvas.getContext('2d');
ctx.putImageData(imageData, 0, 0);
const link = document.createElement('a');
link.download = 'zoomed-snapshot.png';
link.href = canvas.toDataURL();
link.click();
}When a fisheye lens is configured for a camera in Security Center, the GWP can dewarp the image to simulate a PTZ camera experience. This feature is available when webPlayer.dewarperControl is non-null (requires Media Gateway 5.10.2+).
Important Notes:
- Dewarping is performed in the browser and can be resource-intensive
- Frame rate is limited to 10 fps when dewarping is enabled
- Supports common circular fisheye lenses (Acti and Euklis oval lenses may show slight distortion)
- Replaces digital zoom when available
Basic Usage:
const dewarper = webPlayer.dewarperControl;
if (dewarper) {
// Check if currently dewarping
console.log('Is dewarping:', dewarper.isDewarping);
// Navigate using pan/tilt (in degrees)
dewarper.gotoPanTilt(45, -20); // Pan 45° right, tilt 20° down
// Navigate using X/Y coordinates (normalized -1 to 1)
dewarper.gotoXY(0.3, 0.3); // Move to upper-right quadrant
// Zoom (1x to 20x)
dewarper.gotoZoom(3); // 3x zoom
// Get current position
console.log(`Pan: ${dewarper.PanDegrees}°, Tilt: ${dewarper.TiltDegrees}°`);
console.log(`Position: (${dewarper.X}, ${dewarper.Y}), Zoom: ${dewarper.ZoomFactor}x`);
// Stop dewarping and return to original warped image
dewarper.stopDewarping();
}Dewarping Preview:
The preview shows the full fisheye image with the dewarped region highlighted. By default, it appears in the upper-left corner:
const preview = dewarper.Preview;
// Enable/disable preview
preview.Enabled = true;
// Access and customize the preview canvas
const canvas = preview.Canvas;
// Position and style the preview
canvas.style.position = 'absolute';
canvas.style.top = '10px';
canvas.style.left = '10px';
canvas.style.width = '200px';
canvas.style.height = '200px';
// Customize colors using CSS properties
canvas.style.color = 'rgba(255, 255, 0, 0.3)'; // Yellow tint inside visible zone
canvas.style.borderColor = 'red'; // Red border around visible zoneCSS Customization Table:
| CSS Property | Effect |
|---|---|
color (on preview canvas) |
Color/tint inside the visible dewarped zone |
border-color (on preview canvas) |
Color of the border outlining the visible zone |
color (on main dewarper canvas) |
Background color outside the fisheye circle |
Default User Interactions:
The dewarper provides built-in mouse interactions for both preview and main canvas:
On Preview Canvas:
- Mouse wheel up: Increases zoom by 0.5x (up to maximum of 20x)
-
Mouse wheel down: Decreases zoom by 0.5x (down to minimum of 1x)
-
Note: Reducing zoom to 1.0x automatically calls
stopDewarping()and returns to the original warped stream
-
Note: Reducing zoom to 1.0x automatically calls
-
Left-click: Calls
gotoXY()to center the dewarped view at the clicked point - Click and drag: Continuously updates center position - the dewarped view follows the cursor
On Main Dewarped Video Canvas:
- Mouse wheel: Zoom in/out (same behavior as preview)
-
Click and drag: Simulates
gotoPanTilt()- horizontal movement sets pan degrees, vertical movement sets tilt degrees
Overriding Default Behaviors:
All default interactions can be overridden by intercepting events during the capture phase:
// Example: Disable zoom on mouse wheel
divContainer.addEventListener('wheel', (event) => {
event.stopPropagation(); // Prevents GWP's default zoom behavior
// Implement custom behavior or do nothing
}, true); // true = capture phaseCapture still images from the video stream using the getSnapshot() method. This returns an ImageData object containing the last displayed frame, or null if no frame is available.
Basic Snapshot:
// Get snapshot from main player (includes watermarking, no zoom/dewarping)
const imageData = webPlayer.getSnapshot();
if (imageData) {
// Convert ImageData to downloadable image
const canvas = document.createElement('canvas');
canvas.width = imageData.width;
canvas.height = imageData.height;
const ctx = canvas.getContext('2d');
ctx.putImageData(imageData, 0, 0);
// Download as PNG
const link = document.createElement('a');
link.download = `snapshot-${new Date().toISOString()}.png`;
link.href = canvas.toDataURL('image/png');
link.click();
}Snapshot Comparison:
Different snapshot sources include different elements:
| Source | Includes Watermark | Includes Zoom/Dewarping |
|---|---|---|
webPlayer.getSnapshot() |
✅ Yes | ❌ No |
digitalZoomControl.snapshot() |
❌ No | ✅ Yes (zoomed view only) |
dewarperControl.snapshot() |
❌ No | ✅ Yes (dewarped view only) |
Display Snapshot in Page:
function displaySnapshot(imageData) {
const canvas = document.createElement('canvas');
canvas.width = imageData.width;
canvas.height = imageData.height;
const ctx = canvas.getContext('2d');
ctx.putImageData(imageData, 0, 0);
const img = new Image();
img.src = canvas.toDataURL();
img.style.maxWidth = '300px';
document.getElementById('snapshotContainer').appendChild(img);
}
// Take and display snapshot
const snapshot = webPlayer.getSnapshot();
if (snapshot) {
displaySnapshot(snapshot);
}Toggle privacy protection on the video stream to mask sensitive content. When enabled, video will be obscured based on Security Center privacy settings.
// Toggle privacy protection on/off
webPlayer.togglePrivacy();
// Check current privacy protection state
console.log('Privacy protected:', webPlayer.isPrivacyProtected);
// Monitor privacy protection changes
webPlayer.onPrivacyProtectionChanged.register(() => {
console.log('Privacy protection changed to:', webPlayer.isPrivacyProtected);
// Update UI to reflect state
if (webPlayer.isPrivacyProtected) {
console.log('Video is now privacy protected');
} else {
console.log('Video is now unprotected');
}
});Note
Privacy protection availability depends on camera configuration and user privileges in Security Center.
The GWP supports audio streaming when the camera provides an AAC audio codec stream.
Requirements:
- Codec: Only AAC audio is currently supported
- Live Audio: Camera must have a microphone
- Playback Audio: "Audio recording" must be enabled in the camera configuration (disabled by default in Security Center)
- User Privileges: User must have appropriate audio viewing privileges
Checking Audio Availability:
// Check if audio is available for this camera
console.log('Audio available:', webPlayer.isAudioAvailable);
// Monitor audio availability changes
webPlayer.onAudioAvailabilityChanged.register((event) => {
console.log('Audio availability changed:', event.isAudioAvailable);
if (event.isAudioAvailable) {
console.log('Audio is now available - you can enable it');
} else {
console.log('Audio is not available at this time');
}
});Note
isAudioAvailable checks camera capabilities and user privileges, but it doesn't guarantee audio is present at the current moment.
Enabling Audio Playback:
// Enable audio playback
webPlayer.setAudioEnabled(true);
// Disable audio
webPlayer.setAudioEnabled(false);
// Check if audio is currently enabled
console.log('Audio enabled:', webPlayer.isAudioEnabled);
// Monitor audio state changes
webPlayer.onAudioStateChanged.register((event) => {
console.log('Audio state changed:', event.isAudioEnabled);
// Update UI (e.g., toggle mute button)
updateMuteButton(event.isAudioEnabled);
});Important: Browser Autoplay Policy
Modern browsers prevent audio from playing automatically without user interaction. If you try to enable audio on page load or without a user action, the browser will likely block it.
Best Practices:
- Only enable audio in response to user actions (button click, touch event, etc.)
- Never auto-enable audio on page load or player start
- Provide UI controls for users to explicitly enable/disable audio
Example: Audio Toggle Button
// HTML: <button id="toggleAudioBtn">Unmute</button>
const audioBtn = document.getElementById('toggleAudioBtn');
audioBtn.addEventListener('click', () => {
// User action triggers audio - browser allows this
const currentState = webPlayer.isAudioEnabled;
webPlayer.setAudioEnabled(!currentState);
// Update button text
audioBtn.textContent = !currentState ? 'Mute' : 'Unmute';
});
// Keep button in sync with audio state
webPlayer.onAudioStateChanged.register((event) => {
audioBtn.textContent = event.isAudioEnabled ? 'Mute' : 'Unmute';
});Browser Autoplay Consequences:
If you attempt to enable audio without user interaction:
- The browser may blacklist your page from playing audio
- Future audio enable attempts may also be blocked
- Users may need to manually adjust browser permissions to restore audio
Handling Autoplay Failures:
There's no direct event for autoplay blocking. If audio doesn't play after enabling it, assume the browser blocked it and prompt the user to click an audio button.
In Security Center, cameras can provide multiple stream configurations labeled by "stream usage":
- Live - Default live viewing stream
- Recording - Stream being recorded to archiver
- Remote - Optimized for remote/WAN viewing
- Low Resolution - Lower quality for bandwidth savings
- High Resolution - Highest quality available
Automatic Stream Selection:
By default, GWP uses automatic stream selection in live mode, choosing the appropriate stream based on player size:
// Automatic mode (default)
// - Player size < 640x480: Uses Low Resolution stream
// - Player size 640x480 to 1280x720: Uses Live stream
// - Player size > 1280x720: Uses High Resolution stream
// The stream automatically switches when the player is resizedConfiguration:
Stream selection is configured in the Media Gateway configuration page in Config Tool. You can choose:
- Specific stream usage (e.g., always use High Resolution)
- Automatic mode with custom thresholds
Transcoding:
If the browser doesn't support the camera's codec, the Media Gateway can transcode the stream. Transcoding configuration in Media Gateway settings:
- Never - No transcoding (some streams may be unplayable)
- For PTZ Only - Transcode only when PTZ mode is enabled
- Always - Allow transcoding for unsupported codecs
PTZ Low-Latency Mode:
Enable PTZ mode to prioritize low latency over stream quality (may trigger transcoding):
// Enable PTZ mode for low-latency control
webPlayer.setPtzMode(true);
// Perform PTZ operations with reduced latency
const ptz = webPlayer.ptzControl;
ptz.startPanTilt(0.5, 0);
// Disable when done to reduce server load
webPlayer.setPtzMode(false);Note
Transcoding is computationally expensive for the Media Gateway server. Configure maximum output resolution and frame rate limits in Media Gateway settings to control resource usage.
The GWP includes a built-in diagnostic overlay for troubleshooting stream issues. The overlay displays real-time information about the stream, including codec, resolution, frame rate, latency, and connection state.
Enable/Disable the Overlay:
// Show the diagnostic overlay
webPlayer.showDebugOverlay(true);
// Hide the diagnostic overlay
webPlayer.showDebugOverlay(false);
// Toggle with keyboard shortcut: Ctrl+Shift+A (when player canvas has focus)Overlay Information Includes:
- Tile ID and camera information
- Video codec and resolution
- Frame rate (current and average)
- Player state and streaming state
- Network latency (global and local)
- Media time and timestamps
- Bitrate and key frame interval
Important
The diagnostic overlay's appearance and content may change in future versions. It is intended for troubleshooting only, not for production use.
Enable GWP Console Logs:
For detailed debugging information in the browser console:
// Enable standard GWP logs (Info level)
gwp.enableLogs();
// Enable verbose/intense logging (Debug level - very detailed)
gwp.enableLogs(true);
// Disable logs (warnings and errors still shown)
gwp.disableLogs();Log Filtering: All GWP logs are prefixed with the 🐹 emoji for easy filtering in the browser console.
Browser-Specific Behavior:
- Chrome: GWP logs appear as "Info" level
- Firefox: GWP logs appear as "Logs" and "Info" levels
Warning
Intense logging (gwp.enableLogs(true)) generates a large volume of output and can impact performance. Use it only when necessary for troubleshooting, and disable it when done.
By default, each player creates its own WebSocket connection to the Media Gateway. If you need to display many players simultaneously, you can multiplex them over a single WebSocket connection for better performance and resource efficiency.
Note
This is an advanced feature. A communication failure of the shared socket will impact all players using it.
First, create a shared Media Gateway service:
const mediaGatewayService = await gwp.buildMediaGatewayService(
mediaGatewayEndpoint,
getTokenFct
);Use startWithService() instead of start() for each player:
// Create multiple players
const player1 = gwp.buildPlayer(document.getElementById('player1'));
const player2 = gwp.buildPlayer(document.getElementById('player2'));
const player3 = gwp.buildPlayer(document.getElementById('player3'));
// Start all players with the same service
await player1.startWithService(camera1Guid, mediaGatewayService);
await player2.startWithService(camera2Guid, mediaGatewayService);
await player3.startWithService(camera3Guid, mediaGatewayService);
// Control each player independently
player1.playLive();
player2.playLive();
player3.seek(new Date('2023-12-24T10:00:00Z'));async function setupMultiplePlayers() {
try {
// Create shared service
const mediaGatewayService = await gwp.buildMediaGatewayService(
'https://gateway.example.com/media',
getTokenFct
);
// Define cameras to display
const cameras = [
{ id: 'camera-guid-1', container: 'player1' },
{ id: 'camera-guid-2', container: 'player2' },
{ id: 'camera-guid-3', container: 'player3' },
{ id: 'camera-guid-4', container: 'player4' }
];
// Create and start all players
const players = [];
for (const cam of cameras) {
const player = gwp.buildPlayer(document.getElementById(cam.container));
// Register error handler
player.onErrorStateRaised.register((error) => {
console.error(`Player ${cam.container} error:`, error.value);
});
await player.startWithService(cam.id, mediaGatewayService);
player.playLive();
players.push(player);
}
console.log(`Started ${players.length} players over single WebSocket`);
return players;
} catch (error) {
console.error('Failed to setup multiplexed players:', error);
throw error;
}
}Benefits:
- Reduced number of WebSocket connections
- Lower network overhead
- Better resource utilization
- Improved performance with many simultaneous players
Considerations:
- Single point of failure: if the shared WebSocket connection fails, all players are affected
- More complex error handling
- Players must connect to the same Media Gateway agent
- Audio: Only AAC audio codec is supported. For playback, "audio recording" must be enabled in the camera configuration (disabled by default in Security Center).
- Reverse Playback: Smooth reverse playback is only supported for MJPEG streams. Other codecs will play keyframes only during reverse playback (recommended minimum speed: -6x).
- Browser Codec Support: Some codecs may require transcoding on the Media Gateway server. Currently, most browsers support H.264 and MJPEG decoding natively.
- Dewarping Frame Rate: When dewarping is enabled, frame rate is limited to 10 fps due to browser processing requirements.
- Dewarping Lens Support: Dewarping currently supports common circular fisheye lenses. Oval lenses (such as Acti and Euklis) may show slight distortion. Special viewing modes (e.g., Panorama effect) are not yet supported.
- CORS Configuration: The Media Gateway must be configured to accept requests from your web application's origin. See the CORS Configuration section.
Cross-Origin Resource Sharing (CORS) is a security mechanism enforced by web browsers that restricts how resources on a web server can be requested from a different origin. For Genetec Web Player (GWP), proper CORS configuration ensures that web applications can securely communicate with the Media Gateway while preventing unauthorized access.
To enforce CORS restrictions, administrators must modify the MediaGateway.gconfig file. This file is located in the ConfigurationFiles directory on the Media Gateway server. If the file does not exist, it must be created manually in this directory.
Typically, the ConfigurationFiles directory is found in:
C:\Program Files (x86)\Genetec Security Center X.X\
where X.X represents the version of Security Center installed on the server.
To limit CORS access exclusively to specific domains, create or modify the MediaGateway.gconfig file and include the following XML structure:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
<MediaGateway EnforceStrictCrossOrigin="true"/>
</Configuration>This setting prevents other web applications from making requests to the Media Gateway, allowing only official Security Center clients to access it.
For custom web applications that integrate GWP, administrators can specify allowed origins explicitly. To define specific origins, update the MediaGateway.gconfig file as follows:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
<MediaGateway EnforceStrictCrossOrigin="true">
<AllowedOrigin Origin="https://example1.com" />
<AllowedOrigin Origin="https://example2.com" />
<AllowedOrigin Origin="https://web.example3.com" />
</MediaGateway>
</Configuration>In this configuration, only the domains example1.com, example2.com, and web.example3.com can request video streams from the Media Gateway.
This section covers common issues and their solutions when working with the Genetec Web Player.
The following are the most frequently encountered issues by developers:
Symptoms:
- Browser shows security warning or blocks connection
- "Your connection is not private" or "NET::ERR_CERT_AUTHORITY_INVALID" error
- Unable to load
gwp.jsor connect to Media Gateway - Console shows certificate errors
Cause: The Media Gateway is using a self-signed SSL certificate that the browser doesn't trust.
Solutions:
-
Accept the Certificate in Browser (Development/Testing Only)
- Navigate directly to the Media Gateway URL in your browser:
https://<MediaGatewayAddress> - Browser will show security warning
- Click "Advanced" and "Proceed to [site]" (or similar option depending on browser)
- This adds a temporary exception for the certificate
- Note: This only works for testing and must be done in each browser/device
- Navigate directly to the Media Gateway URL in your browser:
-
Install Valid SSL Certificate (Recommended for Production)
- Obtain an SSL certificate from a trusted Certificate Authority (CA)
- Install the certificate on the Media Gateway server
- Configure Media Gateway to use the valid certificate
- This is the recommended approach for production environments
-
Install Self-Signed Certificate in Operating System (Development)
- Export the self-signed certificate from the Media Gateway
- Install it in the operating system's trusted root certificate store
- Restart browser after installation
- More permanent than browser exceptions but still not recommended for production
Important
Self-signed certificates should only be used in development/testing environments. Production environments should always use certificates from trusted Certificate Authorities.
Symptoms:
- HTTP 401 Unauthorized error when retrieving token
- Error code 16 (InsufficientPrivilege)
- Video player fails to start or shows permission error
- "Access denied" messages
Cause: Authentication failure due to incorrect credentials, missing privileges, or lack of partition access.
Solutions:
A. Check Credentials
- Verify username and password are correct
- Verify SDK certificate string is correct
- Check Authorization header format:
Basic <Base64(username;sdkCertificate:password)> - Ensure no extra spaces or special characters in credentials
- Test login in Security Center Config Tool to confirm credentials work
B. Check Security Center Privileges
Required privileges for all GWP applications:
- "Log on using the SDK" (Application privileges)
- "View camera properties" (Administrative privileges - Physical entities)
- "Live hit monitoring" (Web App privileges)
Additional privileges depending on features used: 4. For live video: "View live video" (Action privileges - Cameras) 5. For playback: "View playback" (Action privileges - Cameras) 6. For PTZ: Check PTZ motor privileges (requires "View live video" first)
See the complete Security Center Privileges section for details
C. Check Partition Access Rights
- Verify the user has access rights to the partition containing the camera
- In Security Center Config Tool:
- Go to User Management
- Select the user
- Check "Access rights" tab
- Ensure the user has access to the camera's partition
- Common mistake: User has all privileges but no partition access
D. Check Camera Configuration
- Verify the camera GUID is correct
- Ensure the camera exists and is online in Security Center
- Check that the camera is assigned to a partition the user can access
Testing Steps:
// Test token retrieval
const testToken = async () => {
try {
const response = await fetch(`${mediaGatewayEndpoint}/v2/token/${cameraId}`, {
credentials: 'include',
headers: {
'Authorization': `Basic ${btoa(username + ";" + sdkCertificate + ":" + password)}`
}
});
console.log('Status:', response.status);
if (response.ok) {
console.log('Token retrieved successfully');
} else {
console.error('Failed:', response.status, response.statusText);
}
} catch (error) {
console.error('Error:', error);
}
};Symptoms:
- Browser console shows CORS errors
- "Access to fetch/XMLHttpRequest blocked by CORS policy" error
- "No 'Access-Control-Allow-Origin' header is present"
- Token retrieval or WebSocket connection fails
Cause: The Media Gateway is not configured to allow requests from your web application's origin.
Solutions:
-
Configure Media Gateway CORS Settings
Modify the
MediaGateway.gconfigfile located in the ConfigurationFiles directory:C:\Program Files (x86)\Genetec Security Center X.X\ConfigurationFiles\MediaGateway.gconfigOption A: Allow specific origins (Recommended)
<?xml version="1.0" encoding="UTF-8"?> <Configuration> <MediaGateway EnforceStrictCrossOrigin="true"> <AllowedOrigin Origin="https://yourapp.example.com" /> <AllowedOrigin Origin="http://localhost:3000" /> </MediaGateway> </Configuration>
Option B: Allow all origins (Development only - NOT recommended for production)
<?xml version="1.0" encoding="UTF-8"?> <Configuration> <MediaGateway EnforceStrictCrossOrigin="false"/> </Configuration>
-
Restart the Media Gateway Role after modifying the configuration file
-
Verify Your Application's Origin
- Origin includes protocol, domain, and port
- Examples:
https://app.example.com,http://localhost:3000,https://192.168.1.100:8080 - Make sure the exact origin is listed in the configuration
-
Check for Multiple Origins
- If testing from multiple locations (localhost, staging, production), add all origins
Common CORS Mistakes:
- Forgetting to restart Media Gateway after config change
- Origin mismatch (e.g.,
httpvshttps, different port numbers) - Trailing slashes in origin URLs
- Using IP address in code but domain name in CORS config (or vice versa)
See the complete CORS Configuration section for more details.
Symptoms:
- Unexpected errors or exceptions
- Missing methods or properties
- Features not working as documented
- "undefined is not a function" errors
- Inconsistent behavior
Cause: The gwp.js file version doesn't match the Media Gateway/Security Center version.
Solutions:
-
Always Load from Media Gateway
Correct approach:
<script src="https://<MediaGatewayAddress>/media/v2/files/gwp.js"></script>
Incorrect approaches:
- ❌ Using a downloaded/cached copy from a different Security Center version
- ❌ Hosting
gwp.json your own server - ❌ Loading from a different Media Gateway than you're connecting to
-
Verify Version Match
// Check GWP version console.log('GWP Version:', gwp.version()); // This should match your Security Center/Media Gateway version
-
Clear Browser Cache
- Browser may be caching an old version of
gwp.js - Hard refresh: Ctrl+F5 (Windows) or Cmd+Shift+R (Mac)
- Clear browser cache completely
- Try in incognito/private browsing mode
- Browser may be caching an old version of
-
Check for Multiple Script Tags
- Ensure you're not loading
gwp.jsmultiple times - Check that no other libraries are loading an older version
- Ensure you're not loading
-
After Security Center Upgrade
- If Security Center was upgraded, the
gwp.jsfile changes automatically - Users with cached versions will have mismatches
- Consider cache-busting strategies:
<script src="https://<MediaGatewayAddress>/media/v2/files/gwp.js?v=5.12"></script>
- If Security Center was upgraded, the
Prevention:
- Always reference
gwp.jsfrom the Media Gateway server - Don't download and host
gwp.jsseparately - Document the Security Center version your application is tested with
- Test thoroughly after Security Center upgrades
See the Installation section for more details.
Enable GWP logs and use browser developer tools to diagnose issues:
// Enable detailed GWP logging
gwp.enableLogs(true);Check the Browser Console:
- Open Developer Tools (F12)
- Go to Console tab
- Look for error messages, warnings, or GWP logs
- Note error codes and descriptions
Check Network Tab:
- Open Developer Tools (F12)
- Go to Network tab
- Filter for WebSocket connections (WS/WSS)
- Check for failed requests or CORS errors
- Verify token retrieval requests succeed
Check the Debug Overlay:
// Show diagnostic overlay on the player
webPlayer.showDebugOverlay(true);The debug overlay displays real-time information about:
- Connection status
- Stream statistics
- Frame rate and codec information
- Buffering status
If issues persist after trying the solutions above:
-
Enable verbose logging:
gwp.enableLogs(true); // Enable intense logging
-
Gather diagnostic information:
- GWP version:
gwp.version() - Security Center version
- Browser and OS version
- Error codes from console
- Network tab screenshots showing failed requests
- GWP version:
-
Contact Genetec Support with the diagnostic information
-
Use Logs: Enable GWP logs to gather detailed information:
gwp.enableLogs();
-
Check Network Accessibility: Ensure the Media Gateway is reachable from your network.
-
Validate Configuration: Confirm the Media Gateway role and permissions are properly configured in Security Center.
-
Security Center SDK Developer Guide Overview of the SDK framework and how to build integrations with Security Center.
-
Platform SDK
- Overview Introduction to the Platform SDK and core concepts.
- Connecting to Security Center Step-by-step guide for connecting and authenticating with the SDK.
- SDK Certificates Details certificates, licensing, and connection validation.
- Referencing SDK Assemblies Best practices for referencing assemblies and resolving them at runtime.
- SDK Compatibility Guide Understanding backward compatibility and versioning in the SDK.
- Entity Guide Explains the core entity model, inheritance, and how to work with entities.
- Entity Cache Guide Describes the engine's local entity cache and synchronization.
- Transactions Covers batching operations for performance and consistency.
- Events Subscribing to real-time system events.
- Actions Sending actions to Security Center.
- Security Desk Displaying content on monitors, reading tiles, sending tasks, and messaging operators.
- Custom Events Defining, raising, and subscribing to custom events.
- ReportManager Querying entities and activity data from Security Center.
- ReportManager Query Reference Complete reference of query types, parameters, and response formats.
- Privileges Checking, querying, and setting user privileges.
- Partitions Entity organization and access control through partitions.
- Logging How to configure logging, diagnostics, and debug methods.
-
Plugin SDK
- Overview Introduction to plugin architecture and capabilities.
- Certificates SDK certificate requirements for plugin roles.
- Lifecycle Initialization and disposal patterns.
- Threading Threading model, QueueUpdate, and async patterns.
- State Management Reporting plugin health and diagnostics.
- Configuration Configuration storage and monitoring.
- Restricted Configuration Secure credential storage and admin-only configuration.
- Events Event subscription and handling.
- Queries Query processing and response handling.
- Request Manager Request/response communication with clients.
- Database Database integration and schema management.
- Entity Ownership Understanding plugin-owned entities, running state management, and ownership release.
- Entity Mappings Using EntityMappings for plugin-specific configuration and external system integration.
- Server Management High availability and server failover.
- Custom Privileges Defining and enforcing custom privileges.
- Custom Entity Types Defining and managing plugin-specific entity types.
- Resolving Non-SDK Assemblies Handling third-party dependencies in plugins and workspace modules.
- Deploying Plugins Registering and deploying plugins and workspace modules.
- .NET 8 Support Building plugins with .NET 8 and .NET Standard compatibility.
-
Workspace SDK
- Overview Introduction to client-side UI extensions for Security Desk and Config Tool.
- Certificates SDK certificate requirements for workspace modules.
- Creating Modules Module lifecycle, registration patterns, and assembly resolution.
- Tasks Executable actions, home page entries, and programmatic invocation.
- Pages Page content, lifecycle, descriptors, and navigation.
- Components Dashboard widgets, tiles, maps, credentials, and content builders.
- Tile Extensions Custom tile widgets, views, and properties panels.
- Services Built-in services for dialogs, maps, alarms, badges, and more.
- Contextual Actions Right-click context menu extensions.
- Options Extensions Custom settings pages in application preferences.
- Configuration Pages Entity configuration pages for Config Tool.
- Monitors Multi-monitor support and shared components.
- Shared Components Using monitor and workspace shared UI components.
- Commands Command execution, evaluation, and interception.
- Extending Events Adding custom fields to Security Center events.
- Map Extensions Custom map objects, layers, and providers.
- Timeline Providers Custom timeline event sources for video playback.
- Image Extractors Custom image sources for cardholder photos and custom fields.
- Credential Encoders Encoding credentials with custom encoder components.
- Cardholder Fields Extractors Importing cardholder data from external sources.
- Content Builders Building and customizing tile content in Security Desk.
-
Macro SDK
- Overview How macros work, creating and configuring macro entities, automation, and monitoring.
- Developer Guide Developing macro code with the UserMacro class and Security Center SDK.
-
- Getting Started Setup, authentication, and basic configuration for the Web SDK.
- Referencing Entities Entity discovery, search capabilities, and parameter formats.
- Entity Operations CRUD operations, multi-value fields, and method execution.
- Partitions Managing partitions, entity membership, and user access control.
- Custom Fields Creating, reading, writing, and filtering custom entity fields.
- Custom Card Formats Managing custom credential card format definitions.
- Actions Control operations for doors, cameras, macros, and notifications.
- Events and Alarms Real-time event monitoring, alarm monitoring, and custom events.
- Incidents Incident management, creation, and attachment handling.
- Reports Activity reports, entity queries, and historical data retrieval.
- Tasks Listing and executing saved report tasks.
- Macros Monitoring currently running macros.
- Custom Entity Types Listing, retrieving, and deleting custom entity type descriptors.
- System Endpoints License usage, web tokens, and exception handling.
- Performance Guide Optimization tips and best practices for efficient API usage.
- Reference Entity GUIDs, EntityType enumeration, and EventType enumeration.
- Under the Hood Technical architecture, query reflection, and SDK internals.
- Troubleshooting Common error resolution and debugging techniques.
- Media Gateway Guide Setup and configuration of the Media Gateway role for video streaming.
- Developer Guide Complete guide to integrating GWP for live and playback video streaming.
- API Reference Full API documentation with interfaces, methods, properties, and events.
- Sample Application Comprehensive demo showcasing all GWP features with timeline and PTZ controls.
- Multiplexing Sample Multi-camera grid demo using a shared WebSocket connection.