Menu

Video Recording and Upload

Relevant source files

This document describes the video recording and upload system in docker-selenium, which captures browser test sessions as video files and optionally uploads them to cloud storage. The system consists of a video recorder container running FFmpeg to capture X11 display output, orchestrated by shell scripts that monitor session lifecycle via the Selenium Grid API.

For information about general Kubernetes deployment and configuration, see 3. For distributed tracing and observability features, see 6.3.

System Architecture

The video recording system can be deployed in two configurations:

  1. Standalone Mode: Video recorder in a separate container monitoring a standalone Selenium node
  2. Sidecar Mode: Video recorder as a sidecar container attached to browser node pods (Kubernetes)

Sources: Video/video.sh1-298 Video/Dockerfile1-56 charts/selenium-grid/values.yaml224-240

Video Container Components

The selenium/video image contains the following key components:

ComponentPurposeConfiguration
video.shMain orchestration script, monitors sessions and controls FFmpegSE_RECORD_VIDEO, SE_VIDEO_POLL_INTERVAL
video_graphQLQuery.shQueries Grid GraphQL for session capabilitiesSE_NODE_GRID_GRAPHQL_URL
video_nodeQuery.pyParses session metadata to determine recording settingsVIDEO_CAP_NAME, TEST_NAME_CAP
ffmpegVideo encoder capturing X11 displaySE_FRAME_RATE, SE_CODEC, SE_PRESET
rcloneCloud storage transfer utilityRCLONE_CONFIG
upload.shUpload orchestration scriptSE_VIDEO_UPLOAD_ENABLED

Sources: Video/Dockerfile15-33 Video/video.sh1-25

Session-Driven Recording Flow

Sources: Video/video.sh254-293 Video/video_graphQLQuery.sh1-86

Video Recording Control

Capability-Based Recording

Recording is controlled by session capabilities sent in the WebDriver request:

CapabilityTypeDefaultDescription
se:recordVideobooleantrueEnable/disable recording for this session
se:namestringsession_idTest name used in video filename
se:videoNamestring-Override filename (takes precedence over se:name)

Example WebDriver Session Request:

The video recorder queries these capabilities via GraphQL after detecting a new session:

Sources: Video/video_graphQLQuery.sh32-54 Video/video.sh257-266

Environment Variable Configuration

The video recorder is configured through environment variables defined in the Dockerfile:

Environment VariableDefaultDescription
SE_RECORD_VIDEOtrueGlobal toggle for video recording
SE_FRAME_RATE15Video frame rate (fps)
SE_CODEClibx264FFmpeg video codec
SE_PRESETultrafastFFmpeg encoding preset
SE_VIDEO_FILE_NAMEvideo.mp4Default filename (overridden by capabilities)
SE_VIDEO_FILE_NAME_SUFFIXtrueAppend session ID to filename
SE_VIDEO_FILE_NAME_TRIM_REGEX[^a-zA-Z0-9-_]Characters to remove from filename
SE_VIDEO_POLL_INTERVAL2Seconds between /status polls
SE_VIDEO_WAIT_ATTEMPTS50Max attempts to wait for API
DISPLAY_CONTAINER_NAMEseleniumHostname of browser container
DISPLAY_NUM99X11 display number
VIDEO_FOLDER/videosOutput directory for video files

Sources: Video/Dockerfile35-53 Video/video.sh3-22

Video File Naming Strategy

The filename generation follows this precedence:

Implementation:

Sources: Video/video_graphQLQuery.sh63-80 Video/video.sh262

FFmpeg Encoding Process

The video recorder uses FFmpeg to capture the X11 display:

FFmpeg Command Example:

Process Management:

  • FFmpeg runs as a background process (&)
  • Process ID tracked in FFMPEG_PID variable
  • Stopped via SIGTERM signal when session ends
  • Script waits for file integrity before upload

Sources: Video/video.sh232-273 Video/Dockerfile35-44

Upload System Integration

RCLONE Configuration

When upload is enabled (SE_VIDEO_UPLOAD_ENABLED=true), the system uses RCLONE to transfer videos to cloud storage:

Upload Signal Flow

The video recorder signals the uploader via a named pipe:

Upload Pipe File Location:

  • Internal upload: /tmp/uploadpipe (within same container)
  • External upload: ${VIDEO_FOLDER}/uploadpipe (shared volume)

Sources: Video/video.sh66-76 Video/video.sh162-168

RCLONE Environment Variables

RCLONE is configured via environment variables following the pattern RCLONE_CONFIG_<REMOTE>_<OPTION>:

S3 Example:

GCS Example:

These are typically stored as Kubernetes Secrets when deployed via Helm.

Sources: tests/charts/templates/render/dummy.yaml232-240 charts/selenium-grid/values.yaml386-388

Kubernetes Deployment Configuration

Helm Chart Values Structure

The Helm chart provides configuration for video recording at multiple levels:

Video Recorder as Sidecar Container

The video recorder is deployed as a sidecar container in browser node pods:

Key Helm Values:

Pod Structure:

Sources: charts/selenium-grid/values.yaml224-240 charts/selenium-grid/templates/_helpers.tpl374-383

Volume Sharing

Video files are shared between browser and recorder containers via a shared volume:

For persistent storage, configure a PersistentVolumeClaim:

Sources: charts/selenium-grid/templates/_helpers.tpl464-483 tests/charts/templates/render/dummy.yaml262-271

ConfigMap Customization

Recorder ConfigMap

The recorderConfigMap allows overriding the default video.sh script:

Template Reference: The Helm chart mounts this ConfigMap in the recorder container at /opt/bin by default.

Sources: charts/selenium-grid/values.yaml354-372 charts/selenium-grid/CONFIGURATION.md159-166

Uploader ConfigMap

The uploaderConfigMap configures RCLONE credentials and custom upload scripts:

These secrets are mounted as environment variables with the RCLONE_CONFIG_ prefix.

Sources: charts/selenium-grid/values.yaml374-394 charts/selenium-grid/CONFIGURATION.md167-175

Environment Variable Reference

Video Recording Control

VariableDefaultDescription
SE_RECORD_VIDEOtrueMaster toggle for video recording
SE_VIDEO_RECORD_STANDALONEfalseRecord in standalone mode (vs hub-node)
SE_VIDEO_FILE_NAMEvideo.mp4Default filename when not auto-generated
SE_VIDEO_FILE_NAME_TRIM_REGEX[^a-zA-Z0-9-_]Characters to remove from filenames
SE_VIDEO_FILE_NAME_SUFFIXtrueAppend session ID to filename

FFmpeg Encoding Settings

VariableDefaultDescription
SE_FRAME_RATE15Video frame rate (fps)
SE_CODEClibx264Video codec
SE_PRESETultrafastEncoding preset (quality vs speed)
SE_VIDEO_CRF28Constant Rate Factor (quality: 0-51, lower=better)
SE_VIDEO_MAXRATE1000kMaximum bitrate
SE_VIDEO_BUFSIZE2000kRate control buffer size
SE_FFMPEG_THREADS1FFmpeg thread count

Audio Recording (Optional)

VariableDefaultDescription
SE_RECORD_AUDIOfalseEnable audio recording
SE_AUDIO_SOURCE-f pulse -ac 2 -i defaultAudio input source for FFmpeg

Upload Configuration

VariableDefaultDescription
SE_VIDEO_UPLOAD_ENABLEDfalseEnable cloud upload
SE_VIDEO_INTERNAL_UPLOADtrueUse internal RCLONE (vs external container)
SE_UPLOAD_DESTINATION_PREFIX""RCLONE destination (e.g., s3://bucket/path)
SE_UPLOAD_PIPE_FILE_NAMEuploadpipeNamed pipe filename
RCLONE_CONFIG/opt/selenium/upload.confRCLONE config file path

Polling and Timeouts

VariableDefaultDescription
SE_VIDEO_POLL_INTERVAL2Seconds between /status API polls
SE_VIDEO_WAIT_ATTEMPTS50Max attempts to wait for Node API
SE_VIDEO_FILE_READY_WAIT_ATTEMPTS5Max attempts to verify file integrity
SE_VIDEO_WAIT_UPLOADER_SHUTDOWN_ATTEMPTS5Max attempts to wait for uploader shutdown

Sources: Video/Dockerfile35-53 Video/video.sh3-21

Session Lifecycle and Drain Behavior

When a node is configured to drain after a certain session count (SE_DRAIN_AFTER_SESSION_COUNT), the video recorder handles graceful shutdown:

Implementation:

Sources: Video/video.sh136-141 Video/video.sh283-286

Video Manager (File Browser)

The chart includes an optional video manager deployment for browsing recorded videos via HTTP:

This deploys a file browser UI that mounts the same shared volume as the video recorder, allowing users to view and download recorded videos.

Sources: charts/selenium-grid/values.yaml262-271 charts/selenium-grid/README.md40

Authentication and Security

Basic Authentication

When the Grid uses basic authentication, the video recorder includes credentials in API requests:

Sources: Video/video.sh36-39 Video/video_graphQLQuery.sh17-20

Node Registration Secret

If node registration secret is enabled, it's included in API headers:

Sources: Video/video.sh42-46

Troubleshooting and Logging

Log Format

All video recorder logs follow a standardized timestamp format:

Example Output:

2025-01-15 14:23:45,123 [video.recorder] - Session: abc123 is created 2025-01-15 14:23:45,456 [video.recorder] - Start recording: true, video file name: MyTest_abc123.mp4 2025-01-15 14:23:45,789 [video.recorder] - Starting to record video 2025-01-15 14:23:45,901 [video.recorder] - Video recording started 

Common Issues

IssueCauseSolution
Video file emptyDisplay not ready when FFmpeg startedCheck wait_for_display() function logs
Recording not triggeredCapability se:recordVideo not setVerify WebDriver capabilities include se:recordVideo: true
Upload failsInvalid RCLONE configurationCheck RCLONE_CONFIG_* environment variables
File not uploadedNamed pipe not createdVerify mkfifo ${UPLOAD_PIPE_FILE} succeeded
Permission deniedVolume mount permissionsEnsure /videos directory is writable by seluser (UID 1200)

Sources: Video/video.sh21-22 Video/video.sh78-89


Primary Sources: Video/video.sh1-298 Video/Dockerfile1-56 Video/video_graphQLQuery.sh1-86 charts/selenium-grid/values.yaml224-240 charts/selenium-grid/CONFIGURATION.md159-175 charts/selenium-grid/templates/_helpers.tpl374-483