Skip to main content

Connection

The WebSocket server runs on ws://localhost:5000/ and accepts connections from the frontend.
const socket = new WebSocket('ws://localhost:5000/');
The backend only allows one active WebSocket connection. New connections automatically close previous ones.

Message Structure

Frontend to Backend

Messages sent via window.external.sendMessage() use this JSON structure:
{
  "Method": "string",
  "Parameters": {
    // Method-specific parameters
  }
}

Backend to Frontend

Messages received via WebSocket use this JSON structure:
{
  "method": "string",
  "content": {
    // Event-specific data
  }
}
Note the casing difference: Method (capitalized) for frontend-to-backend, method (lowercase) for backend-to-frontend due to JSON serialization settings.

Frontend to Backend Methods

These commands can be sent from the frontend to control the backend.

Recording Control

StartRecording
method
Starts a manual recording session.Parameters: NoneExample:
sendMessageToBackend('StartRecording');
StopRecording
method
Stops the current recording.Parameters: NoneExample:
sendMessageToBackend('StopRecording');

Authentication

Login
method
Authenticates the user with Supabase tokens.Parameters:
accessToken
string
required
Supabase access token from the session
refreshToken
string
required
Supabase refresh token for token renewal
Example:
sendMessageToBackend('Login', {
  accessToken: session.access_token,
  refreshToken: session.refresh_token,
});
Logout
method
Signs out the current user.Parameters: NoneExample:
sendMessageToBackend('Logout');

Clip Creation

CreateClip
method
Creates clips from selected video segments.Parameters:
Selections
array
required
Array of selection objects defining clip segments
id
number
required
Unique identifier for this selection
startTime
number
required
Start timestamp in seconds
endTime
number
required
End timestamp in seconds
fileName
string
required
Source video file name
filePath
string
Full path to source video
type
string
required
Content type (e.g., “recording”, “replay”)
game
string
required
Game name for organizing clips
title
string
Optional title for the clip
igdbId
number
IGDB game database ID
Example:
sendMessageToBackend('CreateClip', {
  Selections: [{
    id: 1,
    startTime: 30.5,
    endTime: 45.2,
    fileName: "gameplay_2024.mp4",
    filePath: "C:/Videos/gameplay_2024.mp4",
    type: "recording",
    game: "Valorant",
    title: "Epic Ace",
    igdbId: 12345
  }]
});
CancelClip
method
Cancels an in-progress clip operation.Parameters:
id
number
required
The clip operation ID to cancel
Example:
sendMessageToBackend('CancelClip', { id: 123 });
CreateAiClip
method
Creates AI-generated highlights from a video.Parameters:
FileName
string
required
Video file name to process
Example:
sendMessageToBackend('CreateAiClip', {
  FileName: "gameplay_2024.mp4"
});

Content Management

DeleteContent
method
Deletes a single piece of content.Parameters:
FileName
string
required
File name of the content to delete
ContentType
string
required
Type of content (“Recording”, “Clip”, “Replay”)
Example:
sendMessageToBackend('DeleteContent', {
  FileName: "clip_001.mp4",
  ContentType: "Clip"
});
DeleteMultipleContent
method
Deletes multiple content items in a batch operation.Parameters:
Items
array
required
Array of items to delete, each with FileName and ContentType
Example:
sendMessageToBackend('DeleteMultipleContent', {
  Items: [
    { FileName: "clip_001.mp4", ContentType: "Clip" },
    { FileName: "clip_002.mp4", ContentType: "Clip" }
  ]
});
RenameContent
method
Renames a content file.Parameters: Handled by ContentService.HandleRenameContentExample:
sendMessageToBackend('RenameContent', {
  // Parameters defined in ContentService
});
ImportFile
method
Imports an external video file into Segra.Parameters: Handled by ImportService.HandleImportFileExample:
sendMessageToBackend('ImportFile', {
  // Parameters defined in ImportService
});

Upload & Compression

UploadContent
method
Uploads content to a platform (e.g., Segra.tv).Parameters: Handled by UploadService.HandleUploadContentExample:
sendMessageToBackend('UploadContent', {
  // Parameters defined in UploadService
});
CancelUpload
method
Cancels an in-progress upload.Parameters:
fileName
string
required
File name of the upload to cancel
Example:
sendMessageToBackend('CancelUpload', {
  fileName: "clip_001.mp4"
});
CompressVideo
method
Compresses a video to reduce file size.Parameters:
FilePath
string
required
Full path to the video file
Example:
sendMessageToBackend('CompressVideo', {
  FilePath: "C:/Videos/large_file.mp4"
});

Bookmarks

AddBookmark
method
Adds a bookmark during recording or playback.Parameters: Handled by ContentService.HandleAddBookmarkExample:
sendMessageToBackend('AddBookmark', {
  // Parameters defined in ContentService
});
DeleteBookmark
method
Removes a bookmark.Parameters: Handled by ContentService.HandleDeleteBookmarkExample:
sendMessageToBackend('DeleteBookmark', {
  // Parameters defined in ContentService
});

Settings

UpdateSettings
method
Updates application settings.Parameters: Handled by SettingsService.HandleUpdateSettingsExample:
sendMessageToBackend('UpdateSettings', {
  // Settings object with changed values
});
SetVideoLocation
method
Opens a folder picker to change the video storage location.Parameters: NoneExample:
sendMessageToBackend('SetVideoLocation');
SetCacheLocation
method
Opens a folder picker to change the cache storage location.Parameters: NoneExample:
sendMessageToBackend('SetCacheLocation');
ApplyVideoPreset
method
Applies a video quality preset.Parameters:
preset
string
required
Name of the preset (e.g., “1080p60”, “4k60”)
Example:
sendMessageToBackend('ApplyVideoPreset', {
  preset: "1080p60"
});
ApplyClipPreset
method
Applies a clip quality preset.Parameters:
preset
string
required
Name of the preset
Example:
sendMessageToBackend('ApplyClipPreset', {
  preset: "high_quality"
});

Game Management

AddToWhitelist
method
Adds a game to the recording whitelist.Parameters:
game
object
required
Game object with name and paths
Name
string
required
Game name
Paths
array
required
Array of executable paths
Example:
sendMessageToBackend('AddToWhitelist', {
  game: {
    Name: "Valorant",
    Paths: ["C:/Games/Valorant/VALORANT.exe"]
  }
});
RemoveFromWhitelist
method
Removes a game from the whitelist.Parameters:
game
object
required
Game object matching the one to remove
AddToBlacklist
method
Adds a game to the recording blacklist.Parameters:
game
object
required
Game object with name and paths
RemoveFromBlacklist
method
Removes a game from the blacklist.Parameters:
game
object
required
Game object matching the one to remove
MoveGame
method
Moves a game between whitelist and blacklist.Parameters:
game
object
required
Game object to move
targetList
string
required
Target list: “whitelist” or “blacklist”
Example:
sendMessageToBackend('MoveGame', {
  game: { Name: "GameName", Paths: [...] },
  targetList: "blacklist"
});
SelectGameExecutable
method
Opens a file picker to select a game executable.Parameters: NoneResponse: Backend sends SelectedGameExecutable message with the selected fileExample:
sendMessageToBackend('SelectGameExecutable');

System Actions

OpenFileLocation
method
Opens Windows Explorer to the file location.Parameters:
FilePath
string
required
Full path to the file
Example:
sendMessageToBackend('OpenFileLocation', {
  FilePath: "C:/Videos/clip.mp4"
});
OpenInBrowser
method
Opens a URL in the default browser.Parameters:
Url
string
required
URL to open
Example:
sendMessageToBackend('OpenInBrowser', {
  Url: "https://segra.tv"
});
OpenLogsLocation
method
Opens Windows Explorer to the logs folder.Parameters: NoneExample:
sendMessageToBackend('OpenLogsLocation');
ToggleFullscreen
method
Toggles fullscreen mode.Parameters:
enabled
boolean
required
True to enable fullscreen, false to disable
Example:
sendMessageToBackend('ToggleFullscreen', {
  enabled: true
});

Updates

CheckForUpdates
method
Checks for available application updates.Parameters: NoneExample:
sendMessageToBackend('CheckForUpdates');
ApplyUpdate
method
Applies a downloaded update and restarts the application.Parameters: NoneExample:
sendMessageToBackend('ApplyUpdate');

Connection

NewConnection
method
Signals that a new WebSocket connection has been established. The backend responds with initial state.Parameters: NoneResponse: Backend sends:
  • Settings with current application state
  • GameList with available games
  • AppVersion with backend version
Example:
sendMessageToBackend('NewConnection');

Storage & Recovery

StorageWarningConfirm
method
Confirms or cancels a storage warning action.Parameters: Handled by StorageWarningService.HandleStorageWarningConfirm
RecoveryConfirm
method
Confirms recovery of temporary files after a crash.Parameters: Handled by RecoveryService.HandleRecoveryConfirm

Backend to Frontend Events

These messages are sent from the backend to update the frontend state.

State Updates

Settings
event
Sends the complete application state to the frontend.Content:
settings
object
Complete Settings.Instance object containing all application state
Example:
{
  "method": "Settings",
  "content": {
    "contentFolder": "C:/Videos",
    "cacheFolder": "C:/AppData/Segra",
    "state": {
      "recording": null,
      "content": [...],
      // ... full state object
    }
  }
}
GameList
event
Sends the list of detected games.Content:
games
array
Array of game objects with names and executable paths
Example:
{
  "method": "GameList",
  "content": [
    {
      "name": "Valorant",
      "paths": ["C:/Games/Valorant/VALORANT.exe"],
      "igdbId": 12345
    }
  ]
}
AppVersion
event
Sends the backend application version for version mismatch detection.Content:
version
string
Semantic version string (e.g., “1.2.3”)
Example:
{
  "method": "AppVersion",
  "content": {
    "version": "1.2.3"
  }
}
Frontend automatically reloads if this doesn’t match __APP_VERSION__

Progress Events

ClipProgress
event
Reports progress of clip creation operations.Content:
id
number
required
Clip operation ID
progress
number
required
Progress percentage (0-100), or -1 for error
selections
array
required
Array of selections being processed
error
string
Error message if progress is -1
Example:
{
  "method": "ClipProgress",
  "content": {
    "id": 123456,
    "progress": 45,
    "selections": [...]
  }
}
UploadProgress
event
Reports progress of upload operations.Content:
fileName
string
required
File being uploaded
progress
number
required
Progress percentage (0-100), or -1 for error
status
string
required
Upload status: “uploading”, “processing”, “done”, or “error”
message
string
Status message or error description
Example:
{
  "method": "UploadProgress",
  "content": {
    "fileName": "clip_001.mp4",
    "progress": 75,
    "status": "uploading",
    "message": "Uploading to server..."
  }
}
ImportProgress
event
Reports progress of file import operations.Content:
id
string
required
Import operation ID
fileName
string
required
Current file being imported
progress
number
required
Progress percentage for current file
status
string
required
Import status: “importing”, “done”, or “error”
totalFiles
number
required
Total number of files to import
currentFileIndex
number
required
Index of current file (0-based)
message
string
Status message
CompressionProgress
event
Reports progress of video compression.Content:
filePath
string
required
File being compressed
progress
number
required
Progress percentage (0-100), or -1 for error
status
string
required
Status: “compressing”, “done”, “skipped”, or “error”
message
string
Status message
Example:
{
  "method": "CompressionProgress",
  "content": {
    "filePath": "C:/Videos/large.mp4",
    "progress": 50,
    "status": "compressing"
  }
}
UpdateProgress
event
Reports progress of application updates.Content:
version
string
required
Version being downloaded
progress
number
required
Download progress (0-100)
status
string
required
Status: “downloading”, “downloaded”, “ready”, or “error”
message
string
required
Human-readable status message
AiProgress
event
Reports progress of AI highlight generation.Content: Handled by AiService
MigrationStatus
event
Reports status of data migration operations.Content:
isRunning
boolean
required
Whether migration is currently running
currentMigration
string
Description of current migration

User Notifications

ShowModal
event
Displays a modal dialog to the user.Content:
title
string
required
Modal title
subtitle
string
Optional subtitle
description
string
required
Modal body text
type
string
required
Modal type: “info”, “warning”, or “error”
Example:
{
  "method": "ShowModal",
  "content": {
    "title": "Error",
    "description": "Failed to start recording",
    "type": "error"
  }
}
StorageWarning
event
Warns user about storage space issues and requests confirmation.Content:
warningId
string
required
Unique ID for this warning
title
string
required
Warning title
description
string
required
Warning description
confirmText
string
required
Text for confirm button
cancelText
string
required
Text for cancel button
action
string
required
Action to perform if confirmed
actionData
any
required
Data needed to perform the action
RecoveryPrompt
event
Prompts user to recover files after a crash.Content:
files
array
required
Array of recoverable file objects
totalCount
number
required
Total number of files that can be recovered
BookmarkCreated
event
Notifies that a bookmark was created (typically from a keybind).Content: Empty objectExample:
{
  "method": "BookmarkCreated",
  "content": {}
}

UI Events

SelectedGameExecutable
event
Returns the game executable selected by the user.Content:
name
string
required
Game name (derived from executable name)
paths
array
required
Array containing the selected executable path
Example:
{
  "method": "SelectedGameExecutable",
  "content": {
    "name": "MyGame",
    "paths": ["C:/Games/MyGame/game.exe"]
  }
}
ReleaseNotes
event
Sends release notes for available versions.Content:
releaseNotesList
array
required
Array of release note objects
version
string
required
Version number
base64Markdown
string
required
Release notes in base64-encoded markdown
releaseDate
string
required
ISO 8601 date string
ShowReleaseNotes
event
Triggers the frontend to display release notes.Content: Version string to show notes for
ObsDownloadProgress
event
Reports OBS download progress during first-time setup.Content:
progress
number
required
Download progress (0-100)
status
string
required
Download status: “downloading”

Heartbeat

pong
event
Response to ping heartbeat message.Content: Empty objectExample:
{
  "method": "pong",
  "content": {}
}

Error Handling

Frontend Validation

Always check if the backend connection is available before sending messages:
if ((window as any).external && typeof (window as any).external.sendMessage === 'function') {
  sendMessageToBackend('StartRecording');
} else {
  console.error('Backend connection not available');
}

Backend Error Responses

When operations fail, the backend typically:
  1. Logs the error with Serilog
  2. Sends a progress event with progress: -1 and an error field
  3. Optionally shows a ShowModal message to the user
Example error response:
{
  "method": "ClipProgress",
  "content": {
    "id": 123456,
    "progress": -1,
    "selections": [...],
    "error": "FFmpeg not found. Please reinstall Segra."
  }
}

Connection Failures

The WebSocket automatically reconnects if the connection drops:
  • Reconnect attempts: Infinite
  • Reconnect interval: 3 seconds
  • Heartbeat timeout: 30 seconds
When reconnected, the backend re-sends the full state:
onOpen: () => {
  console.log('WebSocket reconnected - resyncing state');
  sendMessageToBackend('NewConnection');
}

Best Practices

Use TypeScript Types

Import message type definitions from Models/WebSocketMessages.ts for type safety.

Handle All States

Progress events can be: in-progress (0-100), complete (100), or error (-1). Handle all cases.

Listen to Events

Use window.addEventListener('websocket-message') to react to backend events globally.

Graceful Degradation

Always check if window.external.sendMessage exists before calling it.
Never assume the WebSocket is connected. Use the isConnected state from useWebSocketContext() to check connection status.

Example: Complete Clip Workflow

Here’s a complete example showing the clip creation workflow:
import { sendMessageToBackend } from '../Utils/MessageUtils';
import { useEffect, useState } from 'react';

function ClipCreator() {
  const [progress, setProgress] = useState(0);
  const [clipId, setClipId] = useState<number | null>(null);

  // Listen for progress updates
  useEffect(() => {
    const handleMessage = (event: CustomEvent) => {
      const { method, content } = event.detail;
      
      if (method === 'ClipProgress') {
        if (content.id === clipId) {
          if (content.progress === -1) {
            console.error('Clip failed:', content.error);
          } else if (content.progress === 100) {
            console.log('Clip complete!');
          } else {
            setProgress(content.progress);
          }
        }
      }
    };

    window.addEventListener('websocket-message', handleMessage as EventListener);
    return () => window.removeEventListener('websocket-message', handleMessage as EventListener);
  }, [clipId]);

  const createClip = () => {
    const id = Math.floor(Math.random() * 1000000);
    setClipId(id);
    
    sendMessageToBackend('CreateClip', {
      Selections: [{
        id: id,
        startTime: 10,
        endTime: 20,
        fileName: 'gameplay.mp4',
        type: 'recording',
        game: 'Valorant',
        title: 'Epic Play'
      }]
    });
  };

  const cancelClip = () => {
    if (clipId) {
      sendMessageToBackend('CancelClip', { id: clipId });
    }
  };

  return (
    <div>
      <button onClick={createClip}>Create Clip</button>
      <button onClick={cancelClip}>Cancel</button>
      <progress value={progress} max={100} />
    </div>
  );
}

Next Steps