Skip to main content
The ClipService handles creating clips from recorded sessions and replay buffers. It uses FFmpeg to extract segments, apply encoding settings, and concatenate multiple selections into a single output file.

Overview

Implemented in Backend/Media/ClipService.cs, the service provides:
  • Extract multiple segments from different source videos
  • Concatenate segments into a single clip
  • Re-encode with configurable quality settings
  • Hardware and software encoding support
  • Progress tracking and cancellation
  • Automatic metadata generation

Core Methods

CreateClips

Creates a clip from one or more video selections.
public static async Task CreateClips(List<Selection> selections)
selections
List<Selection>
List of video segments to include in the clip. Each selection contains:
  • Game: Game name
  • FileName: Source video filename
  • FilePath: Full path to source video (optional, auto-resolved if missing)
  • Type: Content type (Session, Buffer, or Clip)
  • StartTime: Start time in seconds
  • EndTime: End time in seconds
  • Title: Optional clip title
  • IgdbId: Optional IGDB game ID
Process Flow:
  1. Validates selections and calculates total duration
  2. Extracts each segment to a temporary file
  3. Concatenates temporary files (if multiple selections)
  4. Generates metadata, thumbnail, and waveform
  5. Adds clip to content library
  6. Cleans up temporary files
Progress Events: Sends ClipProgress messages to the frontend with:
  • id: Unique clip operation ID
  • progress: Progress percentage (0-100, or -1 for error)
  • selections: The original selections list
  • error: Error message (only when progress = -1)
var selections = new List<Selection>
{
    new Selection
    {
        Game = "Valorant",
        FileName = "2026-03-03_14-30-00",
        Type = "Session",
        StartTime = 45.5,
        EndTime = 78.2,
        Title = "Ace Round"
    }
};

await ClipService.CreateClips(selections);

CancelClip

Cancels an in-progress clip operation.
public static async void CancelClip(int clipId)
clipId
int
The unique ID of the clip operation to cancel (provided in ClipProgress messages)
Behavior:
  • Kills all active FFmpeg processes associated with the clip ID
  • Removes processes from tracking
  • Sends completion message to frontend
  • Cleanup of temporary files is handled by the original CreateClips task
Example Usage
// From frontend message handler
int clipId = 123456789;
ClipService.CancelClip(clipId);
Cancellation is immediate and forces FFmpeg process termination. Partial output files are automatically cleaned up.

Encoding Configuration

The service uses settings from Settings.Instance to configure encoding:

Encoder Selection

ClipEncoder
string
  • "gpu": Use hardware acceleration
  • "cpu": Use software encoding

Codec Selection

ClipCodec
string
  • "h264": H.264/AVC
  • "h265": H.265/HEVC
  • "av1": AV1

Hardware Encoder Settings

NVIDIA (NVENC):
ClipQualityGpu
int
CQ level for NVENC (lower = higher quality, typical range: 15-35)
ClipPreset
string
NVENC preset: p1 (fastest) to p7 (slowest), or Quality, Performance
FFmpeg arguments: -cq {quality} -preset {preset} AMD (AMF):
ClipQualityGpu
int
QP level for AMF (lower = higher quality, typical range: 15-35)
ClipPreset
string
AMF usage mode: quality, transcoding, lowlatency, ultralowlatency
FFmpeg arguments: -rc cqp -qp_i {quality} -qp_p {quality} -usage {preset} Intel (QuickSync):
ClipQualityGpu
int
Global quality for QSV ICQ mode (lower = higher quality, typical range: 15-35)
ClipPreset
string
QSV preset: veryfast, faster, fast, medium, slow, slower, veryslow
FFmpeg arguments: -global_quality {quality} -preset {preset}

Software Encoder Settings

ClipQualityCpu
int
CRF value for libx264/libx265 (lower = higher quality, typical range: 18-28)
ClipPreset
string
x264/x265 preset: ultrafast, superfast, veryfast, faster, fast, medium, slow, slower, veryslow
FFmpeg arguments: -crf {quality} -preset {preset}

Additional Settings

ClipFps
int
Target frame rate (0 = keep source frame rate)
ClipAudioQuality
string
AAC audio bitrate (e.g., "128k", "192k", "256k", "320k")

Codec Matrix

The service automatically selects the appropriate codec based on encoder and codec settings:
GPU VendorClipCodecFFmpeg Encoder
NVIDIAh264h264_nvenc
NVIDIAh265hevc_nvenc
NVIDIAav1av1_nvenc
AMDh264h264_amf
AMDh265hevc_amf
AMDav1av1_amf
Intelh264h264_qsv
Intelh265hevc_qsv
Intelav1av1_qsv
CPUh264libx264
CPUh265libx265
CPUav1Not supported (falls back to libx264)
If GPU vendor detection fails, the service automatically falls back to CPU encoding with a warning log message.

FFmpeg Command Examples

Single Clip Extraction

ffmpeg -y -ss 45.5 -t 32.7 \
  -i "input.mp4" \
  -c:v h264_nvenc -preset p4 -cq 20 -r 60 \
  -c:a aac -b:a 192k \
  -movflags +faststart \
  "output.mp4"

Multi-Clip Concatenation

ffmpeg -y -f concat -safe 0 \
  -i "concat_list.txt" \
  -c copy \
  -movflags +faststart \
  "output.mp4"
Where concat_list.txt contains:
file 'C:\\Temp\\clip123.mp4'
file 'C:\\Temp\\clip456.mp4'

File Organization

Clips are saved to:
ContentFolder/clips/{GameName}/{Timestamp}.mp4
Example:
C:/Users/User/Videos/Segra/clips/Valorant/2026-03-03_14-45-30.mp4
Each clip includes:
  • Video file: {timestamp}.mp4
  • Metadata: {timestamp}.json (game, title, timestamps, IGDB ID)
  • Thumbnail: {timestamp}.jpg
  • Waveform: {timestamp}_waveform.png

Progress Tracking

The service tracks progress at multiple stages:
Progress %Stage
0-95%Extracting and encoding segments
96%Concatenating segments
97%Verifying output file
98%Generating metadata
99%Creating thumbnail and waveform
100%Complete - loading into library
-1Error occurred
Progress is weighted by clip duration:
double currentProgress = (processedDuration + (progress * clipDuration)) / totalDuration * 95;

Error Handling

The service includes comprehensive error handling:

Validation Errors

  • Empty selections list
  • Zero or negative total duration
  • FFmpeg not found
  • Missing source files

Extraction Errors

  • Failed to create temp clip file
  • FFmpeg process errors
  • Cancellation during extraction

Concatenation Errors

  • Failed to create output file
  • File not ready for metadata generation

Cleanup

All temporary files are cleaned up in the finally block:
  • Individual clip segments
  • Concat list file
  • Partial output files (on error)
Errors are logged with full stack traces and reported to the frontend via ClipProgress messages with progress: -1 and an error description.

Thread Safety

The service uses a ProcessLock object to ensure thread-safe access to the active FFmpeg process dictionary:
lock (ProcessLock)
{
    ActiveFFmpegProcesses[clipId] = process;
}
This prevents race conditions when:
  • Adding processes during extraction
  • Removing processes after completion
  • Cancelling clips from frontend

Integration Points

  • FFmpegService: Executes FFmpeg with progress callbacks
  • ContentService: Generates thumbnails, metadata, and waveforms
  • SettingsService: Loads clips into content library
  • StorageService: Sanitizes game names for folder organization
  • MessageService: Sends progress updates to frontend