Web Viewer Filter
The Web Viewer filter is an output filter for OpenFilter that provides a web-based visualization of incoming image streams. It hosts a FastAPI application that serves JPEG-encoded frames via a multipart/x-mixed-replace stream, accessible through a web browser. The filter also provides a /data endpoint for streaming frame metadata, making it ideal for real-time monitoring and debugging of OpenFilter pipelines.
OverviewDirect link to Overview
The Web Viewer filter is designed to handle web-based visualization scenarios where you need to:
- Display real-time image streams in a web browser
- Monitor OpenFilter pipeline output visually
- Debug image processing results
- Provide live visualization for multiple topics
- Stream frame metadata alongside images
- Host a web interface for pipeline monitoring
- Support multiple concurrent viewers
- Integrate with existing web applications
Key FeaturesDirect link to Key Features
- Web-based Visualization: Real-time image display in web browsers
- Multipart Streaming: Efficient JPEG streaming via multipart/x-mixed-replace
- Metadata Streaming: Frame data streaming via
/dataendpoint - Multi-topic Support: Display images from multiple topics
- Concurrent Viewers: Support multiple simultaneous viewers
- FastAPI Integration: Modern web framework with automatic API documentation
- CORS Support: Cross-origin resource sharing for web integration
- Responsive Design: Works on desktop and mobile browsers
ConfigurationDirect link to Configuration
Basic ConfigurationDirect link to Basic Configuration
from openfilter.filter_runtime.filter import Filter
from openfilter.filter_runtime.filters.webvis import Webvis
# Simple web visualization
Filter.run_multi([
# ... other filters above
(Webvis, dict(
sources='tcp://localhost:5550',
outputs='tcp://*:5552',
port=8000,
)),
])
Advanced Configuration with Multiple OptionsDirect link to Advanced Configuration with Multiple Options
# Web visualization with available options
Filter.run_multi([
# ... other filters above
(Webvis, dict(
sources='tcp://localhost:5550',
outputs='tcp://*:5552',
port=8000,
host='0.0.0.0', # Listen on all interfaces
)),
])
Environment VariablesDirect link to Environment Variables
You can configure via environment variables:
export FILTER_SOURCES="tcp://localhost:5550"
export FILTER_OUTPUTS="tcp://*:5552"
export FILTER_PORT="8000"
export FILTER_HOST="0.0.0.0"
Web InterfaceDirect link to Web Interface
Main Visualization PageDirect link to Main Visualization Page
The Web Viewer filter provides a web interface accessible at:
http://localhost:8000/
Page FeaturesDirect link to Page Features
- Real-time Image Display: Shows incoming images as they arrive
- Topic Selection: Dropdown to select different topics
- Metadata Display: Shows frame information and statistics
- Responsive Layout: Adapts to different screen sizes
- Auto-refresh: Automatically updates with new frames
Image Streaming EndpointDirect link to Image Streaming Endpoint
Topic Endpoint (/{topic})Direct link to topic-endpoint-topic
Provides real-time image streaming for specific topics:
GET /
GET /main
GET /camera1
Stream FeaturesDirect link to Stream Features
- Multipart/x-mixed-replace: Standard MJPEG streaming format
- Topic-based URLs: Direct topic access via URL path
- JPEG Encoding: Efficient image compression
- Real-time Updates: Immediate frame updates
- Browser Compatibility: Works with all modern browsers
Stream ExamplesDirect link to Stream Examples
# Stream main topic (default)
curl -N http://localhost:8000/
# Stream main topic explicitly
curl -N http://localhost:8000/main
# Stream camera1 topic
curl -N http://localhost:8000/camera1
Data Streaming EndpointDirect link to Data Streaming Endpoint
Data Endpoint (/{topic}/data)Direct link to data-endpoint-topicdata
Provides frame metadata streaming for specific topics:
GET /main/data
GET /camera1/data
Data FeaturesDirect link to Data Features
- Server-Sent Events: Real-time data streaming via text/event-stream
- JSON Data: Frame data dictionary as JSON string
- Topic-based URLs: Data from specific topics via URL path
- Event Stream: Real-time data updates every second
- API Integration: Easy integration with web applications
Data FormatDirect link to Data Format
The /data endpoint streams Server-Sent Events with the following format:
data: {'meta': {'id': 231, 'ts': 1758745938.571617, 'src': 'file://./data/video-03.mp4', 'src_fps': 25.0, 'detections': [{'class': 'face', 'rois': [421, 133, 503, 236], 'confidence': 0.9186320304870605}, {'class': 'face', 'rois': [754, 8, 826, 132], 'confidence': 0.9028760194778442}]}, 'faces_detected': 2, 'face_coordinates': [{'bbox': [421, 133, 82, 103], 'confidence': 0.9186320304870605}, {'bbox': [754, 8, 72, 124], 'confidence': 0.9028760194778442}], 'face_details': [{'face_id': 0, 'bounding_box': {'x': 421, 'y': 133, 'width': 82, 'height': 103}, 'center': {'x': 462, 'y': 184}, 'confidence': 0.9186320304870605}, {'face_id': 1, 'bounding_box': {'x': 754, 'y': 8, 'width': 72, 'height': 124}, 'center': {'x': 790, 'y': 70}, 'confidence': 0.9028760194778442}]}
Data ExamplesDirect link to Data Examples
# Stream main topic data
curl -N http://localhost:8000/main/data
# Response: Server-Sent Events with JSON frame data
# Stream camera1 topic data
curl -N http://localhost:8000/camera1/data
# Response: Server-Sent Events with JSON frame data
Topic ManagementDirect link to Topic Management
The Web Viewer filter automatically creates endpoints for any topics that receive data. Topics are discovered dynamically from incoming frames - you cannot configure which topics to include or exclude.
Usage ExamplesDirect link to Usage Examples
Example 1: Basic Web VisualizationDirect link to Example 1: Basic Web Visualization
Filter.run_multi([
# ... other filters above
(VideoIn, dict(
sources='file:///input.mp4',
outputs='tcp://*:5550',
)),
(ObjectDetection, dict(
sources='tcp://localhost:5550',
outputs='tcp://*:5552',
)),
(Webvis, dict(
sources='tcp://localhost:5552',
outputs='tcp://*:5554',
port=8000,
)),
])
Behavior: Displays object detection results in web browser at http://localhost:8000.
Example 2: Multi-Camera MonitoringDirect link to Example 2: Multi-Camera Monitoring
Filter.run_multi([
# ... other filters above
(VideoIn, dict(
sources='0', # Camera 1
outputs='tcp://*:5550',
)),
(VideoIn, dict(
sources='1', # Camera 2
outputs='tcp://*:5552',
)),
(Webvis, dict(
sources=[
'tcp://localhost:5550',
# need to remap the topic, cause 1 main topic is accepted
'tcp://localhost:5552;>camera2'],
outputs='tcp://*:5554',
port=8000,
)),
])
Behavior: Monitors multiple cameras with topic selection in web interface.
Example 3: Real-time Processing VisualizationDirect link to Example 3: Real-time Processing Visualization
Filter.run_multi([
# ... other filters above
(VideoIn, dict(
sources='rtsp://camera.local/stream',
outputs='tcp://*:5550',
)),
(FaceDetection, dict(
sources='tcp://localhost:5550',
outputs='tcp://*:5552',
)),
(Webvis, dict(
sources='tcp://localhost:5552',
outputs='tcp://*:5554',
port=8000,
)),
])
Behavior: Shows face detection results with metadata streaming.
Example 4: Debugging and DevelopmentDirect link to Example 4: Debugging and Development
Filter.run_multi([
# ... other filters above
(ImageIn, dict(
sources='file:///images/',
outputs='tcp://*:5550',
)),
(Util, dict(
sources='tcp://localhost:5550',
outputs='tcp://*:5552',
log=True, # Log frame data
)),
(Webvis, dict(
sources='tcp://localhost:5552',
outputs='tcp://*:5554',
port=8000,
)),
])
Behavior: Provides debugging interface with logged data visualization.
Example 5: Production MonitoringDirect link to Example 5: Production Monitoring
Filter.run_multi([
# ... other filters above
(VideoIn, dict(
sources='rtsp://production-camera.local/stream',
outputs='tcp://*:5550',
)),
(ProductionProcessor, dict(
sources='tcp://localhost:5550',
outputs='tcp://*:5552',
)),
(Webvis, dict(
sources='tcp://localhost:5552',
outputs='tcp://*:5554',
port=8000,
host='0.0.0.0', # Listen on all interfaces
)),
])
Behavior: Production monitoring accessible from any network location.
Example 6: API IntegrationDirect link to Example 6: API Integration
Filter.run_multi([
# ... other filters above
(VideoIn, dict(
sources='0', # Webcam
outputs='tcp://*:5550',
)),
(Webvis, dict(
sources='tcp://localhost:5550',
outputs='tcp://*:5552',
port=8000,
)),
])
API EndpointsDirect link to API Endpoints
Available EndpointsDirect link to Available Endpoints
1. Root Endpoint (/)Direct link to 1-root-endpoint-
- Method: GET
- Purpose: Main web interface
- Response: HTML page with visualization
2. Topic Stream Endpoint (/{topic})Direct link to 2-topic-stream-endpoint-topic
- Method: GET
- Purpose: Image streaming for specific topic
- Parameters:
topicin URL path - Response: multipart/x-mixed-replace JPEG stream
3. Topic Data Endpoint (/{topic}/data)Direct link to 3-topic-data-endpoint-topicdata
- Method: GET
- Purpose: Frame metadata streaming for specific topic
- Parameters:
topicin URL path - Response: text/event-stream data
API ExamplesDirect link to API Examples
Stream ImagesDirect link to Stream Images
curl -N http://localhost:8000/main
# Response: multipart/x-mixed-replace JPEG stream
curl -N http://localhost:8000/camera1
# Response: multipart/x-mixed-replace JPEG stream
Stream DataDirect link to Stream Data
curl -N http://localhost:8000/main/data
# Response: text/event-stream data
curl -N http://localhost:8000/camera1/data
# Response: text/event-stream data
CORS ConfigurationDirect link to CORS Configuration
The Web Viewer filter has CORS (Cross-Origin Resource Sharing) hardcoded to allow all origins (*). This cannot be configured - all web requests from any domain are allowed by default.
Performance ConsiderationsDirect link to Performance Considerations
Web Server PerformanceDirect link to Web Server Performance
- Concurrent Connections: FastAPI handles multiple viewers
- Memory Usage: Image buffering for multiple viewers
- CPU Usage: JPEG encoding for each viewer
- Network Bandwidth: Multiple concurrent streams
Image Processing PerformanceDirect link to Image Processing Performance
- JPEG Quality: Balance between quality and size
- Frame Rate: Limit frame rate for web display
- Resolution: Optimize resolution for web viewing
- Compression: Efficient JPEG compression
Optimization StrategiesDirect link to Optimization Strategies
# Optimize for web performance
Filter.run_multi([
# ... other filters above
(VideoIn, dict(
sources='file:///input.mp4',
outputs='tcp://*:5550',
)),
(Util, dict(
sources='tcp://localhost:5550',
outputs='tcp://*:5552',
resize='800x600', # Smaller images for web
maxfps=15, # Lower frame rate
)),
(Webvis, dict(
sources='tcp://localhost:5552',
outputs='tcp://*:5554',
port=8000,
)),
])
Error HandlingDirect link to Error Handling
Common Error ScenariosDirect link to Common Error Scenarios
- Port Conflicts: Port already in use
- Image Processing Errors: Failed image encoding
- Network Issues: Connection failures
- Memory Issues: Insufficient memory for buffering
- Browser Compatibility: Unsupported browser features
Error RecoveryDirect link to Error Recovery
- Automatic Retry: Retries failed operations
- Graceful Degradation: Continues with available functionality
- Error Logging: Logs errors for debugging
- Resource Cleanup: Proper cleanup on failures
Error ExamplesDirect link to Error Examples
# Port already in use
port=8000 # Error: Port 8000 already in use
# Invalid host binding
host='invalid' # Error: Invalid host address
# CORS configuration error
# CORS cannot be configured - it's hardcoded
Debugging and MonitoringDirect link to Debugging and Monitoring
Debug ConfigurationDirect link to Debug Configuration
import logging
logging.basicConfig(level=logging.DEBUG)
# Enable webvis debugging
export DEBUG_WEBVIS=true
export LOG_LEVEL=DEBUG
Debug InformationDirect link to Debug Information
- Web Server Status: Shows server startup and status
- Connection Information: Logs client connections
- Image Processing: Logs image encoding operations
- Error Details: Detailed error information
MonitoringDirect link to Monitoring
- Active Connections: Track number of active viewers
- Frame Rates: Monitor actual vs. target frame rates
- Error Rates: Track connection and processing errors
- Resource Usage: Monitor memory and CPU usage
TroubleshootingDirect link to Troubleshooting
Common IssuesDirect link to Common Issues
Web Server IssuesDirect link to Web Server Issues
- Check port availability
- Verify host binding
- Check firewall settings
- Validate configuration parameters
Image Display IssuesDirect link to Image Display Issues
- Check image format support
- Verify JPEG encoding
- Monitor frame rate
- Check browser compatibility
Network IssuesDirect link to Network Issues
- Check network connectivity
- Verify CORS configuration
- Monitor bandwidth usage
- Test with different browsers
Performance IssuesDirect link to Performance Issues
- Optimize image resolution
- Reduce frame rate
- Monitor resource usage
- Check concurrent connections
Debug ConfigurationDirect link to Debug Configuration
# Enable comprehensive debugging
Filter.run_multi([
# ... other filters above
(Webvis, dict(
sources='tcp://localhost:5550',
outputs='tcp://*:5552',
port=8000,
)),
])
Advanced UsageDirect link to Advanced Usage
Custom Web InterfaceDirect link to Custom Web Interface
# Custom web interface integration
Filter.run_multi([
# ... other filters above
(Webvis, dict(
sources='tcp://localhost:5550',
outputs='tcp://*:5552',
port=8000,
)),
])
Multi-Stream IntegrationDirect link to Multi-Stream Integration
# Multiple web visualization instances
Filter.run_multi([
# ... other filters above
(VideoIn, dict(
sources='0', # Camera 1
outputs='tcp://*:5550',
)),
(VideoIn, dict(
sources='1', # Camera 2
outputs='tcp://*:5552',
)),
(Webvis, dict(
sources='tcp://localhost:5550',
outputs='tcp://*:5554',
port=8000,
)),
(Webvis, dict(
sources='tcp://localhost:5552',
outputs='tcp://*:5556',
port=8081,
)),
])
API IntegrationDirect link to API Integration
# API integration with external systems
Filter.run_multi([
# ... other filters above
(Webvis, dict(
sources='tcp://localhost:5550',
outputs='tcp://*:5552',
port=8000,
)),
])
API ReferenceDirect link to API Reference
WebvisConfigDirect link to WebvisConfig
class WebvisConfig(FilterConfig):
sources: str | list[str] | list[tuple[str, dict[str, Any]]]
outputs: str | list[str] | list[tuple[str, dict[str, Any]]]
port: int | None
host: str | None
WebvisDirect link to Webvis
class Webvis(Filter):
FILTER_TYPE = 'Output'
@classmethod
def normalize_config(cls, config)
def init(self, config)
def setup(self, config)
def shutdown(self)
def process(self, frames)
def create_web_app(self)
def stream_images(self, topic)
def stream_data(self, topic)
def get_available_topics(self)
def encode_image(self, frame)
Environment VariablesDirect link to Environment Variables
FILTER_SOURCES: Input sourcesFILTER_OUTPUTS: Output destinationsFILTER_PORT: Web server port (default: 8000)FILTER_HOST: Web server host (default: '0.0.0.0')