Overview
Video functions enable playback of video files and static images within QLC+. Videos can be displayed on screens, projectors, or LED walls, synchronized with lighting effects for complete multimedia shows.
Video functions are primarily used in the QML UI and support both video playback and static image display.
When to Use Video
Multimedia Shows Combine lighting with video content for immersive experiences
Visual Backdrops Display static or animated backgrounds
Projection Mapping Control projector content in sync with lights
LED Wall Content Play videos on LED video walls
The Video class (video.h:36) supports various formats:
static const QStringList m_defaultVideoCaps =
QStringList () << "*.avi" << "*.wmv" << "*.mkv"
<< "*.mp4" << "*.mov" << "*.mpg"
<< "*.mpeg" << "*.flv" << "*.webm" ;
static const QStringList m_defaultPictureCaps =
QStringList () << "*.png" << "*.bmp" << "*.jpg"
<< "*.jpeg" << "*.gif" ;
Actual supported formats depend on the platform’s media framework. Use getVideoCapabilities() to query available formats.
Key Properties
The Video class provides extensive control:
Source Configuration
Path to video/image file or URL. Can be local file or network stream.
Automatically detected. True if source is a static image.
Display Properties
Video resolution (width × height). Read from video metadata.
Custom position and size: QRect(x, y, width, height). Leave null for default.
3D rotation angles in degrees: QVector3D(xRot, yRot, zRot)
Layer order for multiple videos. Higher values appear on top.
Playback Configuration
Screen index for multi-monitor setups (0 = primary screen)
If true, video fills the entire screen
Class Methods
Source Management
// Set video source
bool setSourceUrl ( QString filename );
QString sourceUrl ();
// Check if source is a picture
bool isPicture () const ;
Duration Control
// Get/set video duration
void setTotalDuration ( quint32 duration );
quint32 totalDuration ();
For pictures, duration determines how long the image displays.
Display Configuration
// Resolution
QSize resolution ();
void setResolution ( QSize size );
// Custom geometry
QRect customGeometry ();
void setCustomGeometry ( QRect rect );
// Rotation (3D transform)
QVector3D rotation () const ;
void setRotation ( QVector3D rotation );
// Layer order
int zIndex () const ;
void setZIndex ( int idx );
// Screen selection
int screen ();
void setScreen ( int index );
// Fullscreen mode
bool fullscreen ();
void setFullscreen ( bool enable );
// Get codec information
QString audioCodec ();
void setAudioCodec ( QString codec );
QString videoCodec ();
void setVideoCodec ( QString codec );
Attributes
Video supports real-time adjustable attributes:
enum VideoAttr {
Intensity = Function ::Intensity, // Brightness (0.0-1.0)
Volume , // Audio volume (0-100)
XRotation , // X-axis rotation (-360 to 360)
YRotation , // Y-axis rotation (-360 to 360)
ZRotation , // Z-axis rotation (-360 to 360)
XPosition , // X position offset (-100 to 100)
YPosition , // Y position offset (-100 to 100)
WidthScale , // Width scale (0-1000%)
HeightScale // Height scale (0-1000%)
};
// Adjust attribute
int adjustAttribute ( qreal fraction , int attributeId );
// Get current intensity
qreal intensity ();
Intensity Control
Intensity affects both brightness and volume:
int adjustAttribute ( qreal fraction , int attributeId ) {
switch (attributeId) {
case Intensity:
emit requestBrightnessVolumeAdjust ( fraction );
emit intensityChanged ();
break ;
}
}
Playback Control
Signals for Playback
signals:
void requestPlayback (); // Start playing
void requestPause ( bool enable ); // Pause/resume
void requestStop (); // Stop playback
void requestBrightnessVolumeAdjust ( qreal ); // Adjust brightness/volume
These signals are connected to the video player backend.
Lifecycle Methods
// Start video
void preRun ( MasterTimer * timer ) {
emit requestPlayback ();
Function :: preRun (timer);
}
// Pause control
void setPause ( bool enable ) {
emit requestPause (enable);
Function :: setPause (enable);
}
// Stop video
void postRun ( MasterTimer * timer , QList < Universe * > universes ) {
emit requestStop ();
Function :: postRun (timer, universes);
}
// Stop from UI (triggered by EndOfMedia)
Q_INVOKABLE void stopFromUI () {
if ( isRunning ())
stop ( FunctionParent :: master ());
}
XML Structure
< Function Type = "Video" ID = "60" Name = "Intro Video" >
< Speed FadeIn = "0" FadeOut = "0" Duration = "0" />
< RunOrder > SingleShot </ RunOrder >
< Source Screen = "0"
Fullscreen = "1"
Geometry = "100,100,800,600"
Rotation = "0,0,0"
ZIndex = "1" >
videos/intro.mp4
</ Source >
</ Function >
Geometry="x,y,width,height"
Rotation="xDeg,yDeg,zDeg"
Multi-Screen Setup
For multiple displays:
// Primary screen (default)
video -> setScreen ( 0 );
// Secondary screen
video -> setScreen ( 1 );
// Third screen
video -> setScreen ( 2 );
Screen indices correspond to the system’s display configuration. Use fullscreen for best results on secondary screens.
Custom Geometry
Precise positioning and sizing:
// Windowed mode with custom size/position
QRect geometry ( 100 , 100 , 800 , 600 ); // x, y, width, height
video -> setCustomGeometry (geometry);
video -> setFullscreen ( false );
3D Rotation
Apply 3D transformations:
// Rotate around Y-axis (spin)
QVector3D rotation ( 0 , 45 , 0 ); // 45° Y-rotation
video -> setRotation (rotation);
// Combine rotations
QVector3D rotation ( 15 , 30 , 0 ); // Tilt and spin
video -> setRotation (rotation);
Rotation is applied in X-Y-Z order.
Layer Ordering
Control video stacking:
// Background video
backgroundVideo -> setZIndex ( 1 );
// Overlay video
overlayVideo -> setZIndex ( 10 );
// Top layer
topVideo -> setZIndex ( 100 );
Higher z-index values appear on top.
Image Display
Static images are handled identically:
Video * image = new Video (doc);
image -> setSourceUrl ( "images/backdrop.png" );
image -> setTotalDuration ( 30000 ); // Show for 30 seconds
image -> setFullscreen ( true );
For images, totalDuration() determines how long the image displays. For videos, it’s read from the file.
signals:
void sourceChanged ( QString url ); // Source changed
void intensityChanged (); // Intensity adjusted
void customGeometryChanged ( QRect rect ); // Geometry changed
void rotationChanged ( QVector3D rotation ); // Rotation changed
void zIndexChanged ( int index ); // Z-index changed
void totalTimeChanged ( qint64 ); // Duration changed
void metaDataChanged ( QString key , QVariant data ); // Metadata updated
Connect to these for UI updates:
connect (video, & Video ::totalTimeChanged,
this , & UI ::updateDuration);
connect (video, & Video ::metaDataChanged,
this , & UI ::updateMetadata);
Best Practices
Use Appropriate Formats
Prefer MP4 with H.264 for best compatibility
Test on Target Hardware
Video playback performance varies by system
Optimize File Size
Large videos can cause playback issues; compress appropriately
Set Correct Screen Index
Verify screen indices match your display configuration
Use Fullscreen for Projectors
Always use fullscreen mode for projector output
Common Use Cases
Projection Mapping
Video * projection = new Video (doc);
projection -> setSourceUrl ( "mapping.mp4" );
projection -> setScreen ( 1 ); // Projector screen
projection -> setFullscreen ( true );
LED Wall Content
Video * ledWall = new Video (doc);
ledWall -> setSourceUrl ( "content.mp4" );
ledWall -> setCustomGeometry ( QRect ( 0 , 0 , 1920 , 1080 ));
ledWall -> setZIndex ( 1 );
Multi-Layer Video
// Background
Video * bg = new Video (doc);
bg -> setSourceUrl ( "background.mp4" );
bg -> setZIndex ( 1 );
// Foreground overlay
Video * fg = new Video (doc);
fg -> setSourceUrl ( "overlay.png" );
fg -> setZIndex ( 10 );
fg -> adjustAttribute ( 0.5 , Video ::Intensity); // 50% opacity
High-resolution videos (4K+) require powerful GPU
Multiple simultaneous videos multiply resource usage
Rotation and scaling add rendering overhead
Network streams may have latency issues
Playing multiple 1080p videos simultaneously requires significant system resources. Test on production hardware before show day.
Windows
Uses DirectShow or Media Foundation
Good codec support
Hardware acceleration available
macOS
Uses AVFoundation
Excellent codec support
Native hardware acceleration
Linux
Uses GStreamer
Codec support depends on installed plugins
Hardware acceleration varies by driver
Troubleshooting
Video Not Playing
Verify file format is supported: Video::getVideoCapabilities()
Check file path is correct (use absolute paths)
Test file in standalone player
Ensure required codecs are installed
Check system has sufficient resources
Disable unnecessary features (rotation, scaling)
Close other resource-intensive applications
Use hardware-accelerated codec (H.264)
Reduce number of simultaneous videos
Limitations
Video functions have these limitations:
UI-Only : Video playback only works in QML UI, not headless mode
Platform-Dependent : Codec support varies by operating system
Resource-Intensive : Multiple videos require powerful hardware
No Streaming : Limited support for network streams
No Effects : No built-in video effects or filters
See Also
Audio - Audio playback integration
Shows - Synchronize video with lighting
RGB Matrix - LED wall pixel control