Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.segra.tv/llms.txt

Use this file to discover all available pages before exploring further.

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