diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
index 612b769..63ae9a1 100644
--- a/.github/PULL_REQUEST_TEMPLATE.md
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -4,7 +4,7 @@ Describe the change and why it is needed.
## Validation
-- [ ] `dotnet build .\InstantReplay.sln -c Release`
+- [ ] `dotnet build .\Captail.sln -c Release`
- [ ] Real Windows UI checked when applicable
- [ ] Existing replay, hotkey, tray, and recovery behavior preserved
- [ ] New user-facing text added to both EN and RU resources
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index b604b5e..d69b9be 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -29,7 +29,7 @@ jobs:
with:
dotnet-version: 9.0.x
cache: true
- cache-dependency-path: src/InstantReplay/InstantReplay.csproj
+ cache-dependency-path: src/Captail/Captail.csproj
- name: Cache OBS runtime
uses: actions/cache@v6
@@ -43,13 +43,13 @@ jobs:
- name: Build Release
shell: pwsh
- run: dotnet build ./InstantReplay.sln -c Release -p:ContinuousIntegrationBuild=true
+ run: dotnet build ./Captail.sln -c Release -p:ContinuousIntegrationBuild=true
- name: Validate localization dictionaries
shell: pwsh
run: |
- [xml]$en = Get-Content ./src/InstantReplay/Languages/Strings.en.xaml
- [xml]$ru = Get-Content ./src/InstantReplay/Languages/Strings.ru.xaml
+ [xml]$en = Get-Content ./src/Captail/Languages/Strings.en.xaml
+ [xml]$ru = Get-Content ./src/Captail/Languages/Strings.ru.xaml
$enKeys = @($en.ResourceDictionary.String | ForEach-Object { $_.Key })
$ruKeys = @($ru.ResourceDictionary.String | ForEach-Object { $_.Key })
$differences = @(Compare-Object $enKeys $ruKeys)
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index dab6b3e..a265108 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -56,7 +56,7 @@ jobs:
with:
dotnet-version: 9.0.x
cache: true
- cache-dependency-path: src/InstantReplay/InstantReplay.csproj
+ cache-dependency-path: src/Captail/Captail.csproj
- name: Cache OBS runtime
uses: actions/cache@v6
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 0d40e8a..b079505 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,14 @@
All notable user-facing changes are documented here.
+## [Unreleased]
+
+### Changed
+
+- Renamed remaining solution, project, namespace, icon, and native bridge identifiers to Captail.
+- Added a real interface screenshot and an OBS Replay Buffer comparison to the README.
+- Standardized repository comments and diagnostic messages in English.
+
## [0.1.0] - 2026-07-20
First public preview.
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index dbd7173..058815e 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -27,7 +27,7 @@ Requirements:
```powershell
.\tools\AcquireObsRuntime.ps1
-dotnet build .\InstantReplay.sln -c Debug
+dotnet build .\Captail.sln -c Debug
```
## Pull requests
@@ -43,6 +43,8 @@ dotnet build .\InstantReplay.sln -c Debug
## Code style
- Follow existing C# and XAML conventions.
+- Use English for GitHub issues, pull requests, documentation, code comments, and diagnostic messages.
+- Keep Russian text only in the Russian localization dictionary.
- Prefer clear behavior over abstraction.
- Keep user-facing text in EN/RU localization dictionaries.
- Do not present unavailable hardware functionality as enabled.
diff --git a/InstantReplay.sln b/Captail.sln
similarity index 92%
rename from InstantReplay.sln
rename to Captail.sln
index 2f84d49..94217cf 100644
--- a/InstantReplay.sln
+++ b/Captail.sln
@@ -5,7 +5,7 @@ VisualStudioVersion = 17.0.31903.59
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{827E0CD3-B72D-47B6-A68D-7590B98EB39B}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "InstantReplay", "src\InstantReplay\InstantReplay.csproj", "{FB66E8EA-3BE5-4E9C-8533-1C1B10A06151}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Captail", "src\Captail\Captail.csproj", "{FB66E8EA-3BE5-4E9C-8533-1C1B10A06151}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
diff --git a/README.md b/README.md
index 3131c61..281653c 100644
--- a/README.md
+++ b/README.md
@@ -13,6 +13,10 @@
Captail is designed around one rule: **Instant Replay should stay on.** A game crash, game-to-desktop switch, temporary capture failure, protected surface, or recoverable graphics-driver interruption should not silently leave you without a replay. A watchdog monitors the recording pipeline and restarts it when recovery is possible.
+
+
+
+
> [!WARNING]
> Captail `v0.1.x` is an early public preview. Core recording works, but bugs and hardware-specific problems are expected. Please report anything that does not work.
@@ -27,6 +31,16 @@ Captail is designed around one rule: **Instant Replay should stay on.** A game c
- **Flexible audio** — system/game audio and microphone, volume controls, microphone boost, mixed or separate tracks.
- **Local and private** — no account, cloud upload, analytics, or telemetry. Replays stay on your PC.
+## How Captail differs from OBS Replay Buffer
+
+Captail uses libobs for capture and encoding, but it is not an OBS Studio frontend.
+
+- Starts directly in the system tray with Windows.
+- Requires no scenes, sources, or streaming configuration.
+- Monitors capture health and automatically recovers the recording pipeline.
+- Switches between focused game capture and desktop capture.
+- Stays focused on one job: reliable instant replay.
+
## Download
Download the latest version from [GitHub Releases](https://github.com/FaulMit/captail/releases).
@@ -147,7 +161,7 @@ Requirements:
git clone https://github.com/FaulMit/captail.git
cd captail
.\tools\AcquireObsRuntime.ps1
-dotnet build .\InstantReplay.sln -c Release
+dotnet build .\Captail.sln -c Release
```
Create local release packages:
diff --git a/docs/captail-main.jpg b/docs/captail-main.jpg
new file mode 100644
index 0000000..c43d7d8
Binary files /dev/null and b/docs/captail-main.jpg differ
diff --git a/installer/Captail.iss b/installer/Captail.iss
index 4fa631b..14bad31 100644
--- a/installer/Captail.iss
+++ b/installer/Captail.iss
@@ -35,7 +35,7 @@ ArchitecturesInstallIn64BitMode=x64compatible
MinVersion=10.0.19041
OutputDir={#OutputDir}
OutputBaseFilename=Captail-{#MyAppVersion}-Setup-win-x64
-SetupIconFile=..\src\InstantReplay\Assets\Everloop.ico
+SetupIconFile=..\src\Captail\Assets\Captail.ico
UninstallDisplayIcon={app}\{#MyAppExeName}
UninstallDisplayName={#MyAppName}
Uninstallable=yes
diff --git a/native/ObsBridge/CMakeLists.txt b/native/ObsBridge/CMakeLists.txt
index 95c2c4b..3c560f8 100644
--- a/native/ObsBridge/CMakeLists.txt
+++ b/native/ObsBridge/CMakeLists.txt
@@ -1,6 +1,6 @@
cmake_minimum_required(VERSION 3.20)
-project(EverloopObsBridge LANGUAGES CXX)
+project(CaptailObsBridge LANGUAGES CXX)
-add_library(EverloopObsBridge SHARED EverloopObsBridge.cpp)
-target_compile_features(EverloopObsBridge PRIVATE cxx_std_20)
-target_compile_definitions(EverloopObsBridge PRIVATE WIN32_LEAN_AND_MEAN NOMINMAX)
+add_library(CaptailObsBridge SHARED CaptailObsBridge.cpp)
+target_compile_features(CaptailObsBridge PRIVATE cxx_std_20)
+target_compile_definitions(CaptailObsBridge PRIVATE WIN32_LEAN_AND_MEAN NOMINMAX)
diff --git a/native/ObsBridge/EverloopObsBridge.cpp b/native/ObsBridge/CaptailObsBridge.cpp
similarity index 100%
rename from native/ObsBridge/EverloopObsBridge.cpp
rename to native/ObsBridge/CaptailObsBridge.cpp
diff --git a/native/ObsCaptureFixture/ObsCaptureFixture.cpp b/native/ObsCaptureFixture/ObsCaptureFixture.cpp
index f2a5c42..ba00b66 100644
--- a/native/ObsCaptureFixture/ObsCaptureFixture.cpp
+++ b/native/ObsCaptureFixture/ObsCaptureFixture.cpp
@@ -22,7 +22,7 @@ int WINAPI wWinMain(HINSTANCE instance, HINSTANCE, PWSTR, int show)
WNDCLASSW window_class{};
window_class.hInstance = instance;
window_class.lpfnWndProc = window_proc;
- window_class.lpszClassName = L"EverloopObsCaptureFixture";
+ window_class.lpszClassName = L"CaptailObsCaptureFixture";
window_class.hCursor = LoadCursorW(nullptr, MAKEINTRESOURCEW(32512));
if (!RegisterClassW(&window_class))
return 1;
@@ -30,7 +30,7 @@ int WINAPI wWinMain(HINSTANCE instance, HINSTANCE, PWSTR, int show)
HWND window = CreateWindowExW(
0,
window_class.lpszClassName,
- L"Everloop OBS Capture Fixture",
+ L"Captail OBS Capture Fixture",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
diff --git a/src/InstantReplay/App.xaml b/src/Captail/App.xaml
similarity index 93%
rename from src/InstantReplay/App.xaml
rename to src/Captail/App.xaml
index d3e16a4..54408a1 100644
--- a/src/InstantReplay/App.xaml
+++ b/src/Captail/App.xaml
@@ -1,4 +1,4 @@
-
diff --git a/src/InstantReplay/App.xaml.cs b/src/Captail/App.xaml.cs
similarity index 97%
rename from src/InstantReplay/App.xaml.cs
rename to src/Captail/App.xaml.cs
index e16d769..2072ef9 100644
--- a/src/InstantReplay/App.xaml.cs
+++ b/src/Captail/App.xaml.cs
@@ -9,7 +9,7 @@
using System.Windows.Threading;
using H.NotifyIcon;
-namespace InstantReplay;
+namespace Captail;
public partial class App : Application
{
@@ -355,7 +355,7 @@ private async void RunGameCaptureTest(string[] args)
OutputDirectory = root,
};
if (!TryStartPipeline(showError: false))
- throw new InvalidOperationException("OBS Game Capture не запустился.");
+ throw new InvalidOperationException("OBS Game Capture did not start.");
await Task.Delay(TimeSpan.FromSeconds(8));
string path = await _obs!.SaveReplayAsync();
@@ -397,11 +397,11 @@ private async void RunFaultRecoveryTest()
};
StartHealthMonitor();
if (!TryStartPipeline(showError: false))
- throw new InvalidOperationException("Исходный OBS pipeline не запустился.");
+ throw new InvalidOperationException("The initial OBS pipeline did not start.");
DateTime originalStart = _pipelineStartedUtc;
await Task.Delay(TimeSpan.FromSeconds(3));
- RecoverPipeline("QA: искусственный перезапуск OBS.");
+ RecoverPipeline("QA: simulated OBS restart.");
await Task.Delay(TimeSpan.FromSeconds(6));
bool restarted = IsReplayRunning && _pipelineStartedUtc > originalStart;
string path = restarted
@@ -471,8 +471,8 @@ private bool AcquireSingleInstance(bool backgroundLaunch, bool isolatedUiTest)
Environment.UserName;
string suffix = userId.Replace('\\', '.') +
(isolatedUiTest ? ".UiOnly" : "");
- string mutexName = $@"Local\Everloop.SingleInstance.{suffix}";
- _activationPipeName = $"Everloop.Activate.{suffix}";
+ string mutexName = $@"Local\Captail.SingleInstance.{suffix}";
+ _activationPipeName = $"Captail.Activate.{suffix}";
_singleInstanceMutex = new Mutex(
initiallyOwned: true,
mutexName,
@@ -503,11 +503,11 @@ private void SendActivationCommand(string command)
}
catch (TimeoutException)
{
- // Первый экземпляр ещё запускается.
+ // The first instance may still be starting.
}
catch (IOException)
{
- // Pipe между попытками пересоздаётся.
+ // The pipe is recreated between attempts.
}
}
}
@@ -550,7 +550,7 @@ private async Task ActivationServerLoopAsync(CancellationToken cancellationToken
private static void TerminateLegacyInstances()
{
int currentId = Environment.ProcessId;
- foreach (Process process in Process.GetProcessesByName("InstantReplay"))
+ foreach (Process process in Process.GetProcessesByName("Captail"))
{
using (process)
{
@@ -568,7 +568,7 @@ private static void TerminateLegacyInstances()
catch (Exception exception)
{
Log.Write(
- $"Не удалось закрыть старый экземпляр PID {process.Id}: " +
+ $"Failed to close the previous instance PID {process.Id}: " +
exception.Message);
}
}
@@ -588,7 +588,7 @@ private void BindHotkeyAtStartup()
}
catch (Exception exception)
{
- Log.Write($"Глобальный хоткей недоступен: {exception.Message}");
+ Log.Write($"Global hotkey unavailable: {exception.Message}");
_pendingUiError = exception.Message;
ShowOverlayNotification(
"!",
@@ -639,7 +639,7 @@ private bool TryStartPipeline(bool showError)
if (engine is not null)
_capabilities = engine.Capabilities;
StopPipeline();
- Log.Write($"Запуск OBS pipeline не удался: {exception}");
+ Log.Write($"OBS pipeline startup failed: {exception}");
if (showError)
{
ShowOverlayNotification(
@@ -667,7 +667,7 @@ private void StopPipeline()
}
catch (Exception exception)
{
- Log.Write($"Остановка OBS pipeline: {exception}");
+ Log.Write($"OBS pipeline shutdown failed: {exception}");
}
}
@@ -1119,7 +1119,7 @@ private async Task SaveReplayCoreAsync(ObsReplayEngine engine)
}
catch (Exception exception)
{
- Log.Write($"Сохранение повтора упало: {exception}");
+ Log.Write($"Replay save failed: {exception}");
ShowOverlayNotification(
"!",
Localization.Text("L.Notify.SaveError"),
@@ -1161,7 +1161,7 @@ private static string FormatDuration(int seconds) =>
private static Icon CreateIcon()
{
using Stream stream = GetResourceStream(
- new Uri("Assets/Everloop.ico", UriKind.Relative)).Stream;
+ new Uri("Assets/Captail.ico", UriKind.Relative)).Stream;
using var icon = new Icon(stream);
return (Icon)icon.Clone();
}
@@ -1185,7 +1185,7 @@ protected override void OnExit(ExitEventArgs e)
}
catch
{
- // Уже освобождён во время аварийного завершения.
+ // Already released during emergency shutdown.
}
_singleInstanceMutex.Dispose();
}
diff --git a/src/InstantReplay/AssemblyInfo.cs b/src/Captail/AssemblyInfo.cs
similarity index 100%
rename from src/InstantReplay/AssemblyInfo.cs
rename to src/Captail/AssemblyInfo.cs
diff --git a/src/InstantReplay/Assets/Everloop.ico b/src/Captail/Assets/Captail.ico
similarity index 100%
rename from src/InstantReplay/Assets/Everloop.ico
rename to src/Captail/Assets/Captail.ico
diff --git a/src/InstantReplay/AudioDevices.cs b/src/Captail/AudioDevices.cs
similarity index 96%
rename from src/InstantReplay/AudioDevices.cs
rename to src/Captail/AudioDevices.cs
index 6e31134..63b950f 100644
--- a/src/InstantReplay/AudioDevices.cs
+++ b/src/Captail/AudioDevices.cs
@@ -1,6 +1,6 @@
using NAudio.CoreAudioApi;
-namespace InstantReplay;
+namespace Captail;
internal static class AudioDevices
{
diff --git a/src/InstantReplay/Autostart.cs b/src/Captail/Autostart.cs
similarity index 73%
rename from src/InstantReplay/Autostart.cs
rename to src/Captail/Autostart.cs
index 62b0ce1..d9da7b7 100644
--- a/src/InstantReplay/Autostart.cs
+++ b/src/Captail/Autostart.cs
@@ -1,18 +1,17 @@
using Microsoft.Win32;
-namespace InstantReplay;
+namespace Captail;
-/// Автозапуск через HKCU\...\Run — без прав администратора.
+/// Per-user startup through HKCU\...\Run; administrator rights are not required.
public static class Autostart
{
private const string RunKey = @"Software\Microsoft\Windows\CurrentVersion\Run";
private const string ValueName = "Captail";
- private const string LegacyValueName = "InstantReplay";
public static bool IsEnabled()
{
using var key = Registry.CurrentUser.OpenSubKey(RunKey);
- return HasCommand(key, ValueName) || HasCommand(key, LegacyValueName);
+ return HasCommand(key, ValueName);
}
public static void SetEnabled(bool enabled)
@@ -27,12 +26,10 @@ public static void SetEnabled(bool enabled)
ValueName,
$"\"{executablePath}\" --background",
RegistryValueKind.String);
- key.DeleteValue(LegacyValueName, throwOnMissingValue: false);
}
else
{
key.DeleteValue(ValueName, throwOnMissingValue: false);
- key.DeleteValue(LegacyValueName, throwOnMissingValue: false);
}
}
diff --git a/src/InstantReplay/InstantReplay.csproj b/src/Captail/Captail.csproj
similarity index 90%
rename from src/InstantReplay/InstantReplay.csproj
rename to src/Captail/Captail.csproj
index 96a75a7..084a7d9 100644
--- a/src/InstantReplay/InstantReplay.csproj
+++ b/src/Captail/Captail.csproj
@@ -12,7 +12,8 @@
Captail
Captail
Captail
- Assets\Everloop.ico
+ Captail
+ Assets\Captail.ico
0.1.0
@@ -23,7 +24,7 @@
-
+
PreserveNewest
PreserveNewest
@@ -51,13 +52,13 @@
-
-
+
-
@@ -65,7 +66,7 @@
AfterTargets="Publish"
DependsOnTargets="BuildObsBridge"
Condition="'$(PublishDir)' != ''">
-
diff --git a/src/InstantReplay/Config.cs b/src/Captail/Config.cs
similarity index 57%
rename from src/InstantReplay/Config.cs
rename to src/Captail/Config.cs
index 149af7a..28081ff 100644
--- a/src/InstantReplay/Config.cs
+++ b/src/Captail/Config.cs
@@ -2,47 +2,47 @@
using System.Text.Json;
using System.Text.Json.Serialization;
-namespace InstantReplay;
+namespace Captail;
public sealed class Config
{
public string Language { get; set; } = "en";
public int BufferSeconds { get; set; } = 300;
- /// 0 = ограничение только по длительности.
+ /// 0 = duration-only limit.
public int MaxReplaySizeMb { get; set; }
public int FrameRate { get; set; } = 60;
- /// 0 = адаптивный битрейт по кодеку и нагрузке.
+ /// 0 = adaptive bitrate based on codec and load.
public int BitrateMbps { get; set; }
public string Hotkey { get; set; } = "Ctrl+Shift+F10";
public string ToggleReplayHotkey { get; set; } = "Ctrl+Shift+F9";
public bool ReplayEnabled { get; set; } = true;
- /// "av1", "hevc" или "h264". OBS выбирает доступный encoder нужного формата.
+ /// "av1", "hevc", or "h264". OBS selects an available encoder for the requested format.
public string Codec { get; set; } = "h264";
public int MonitorIndex { get; set; }
- /// "source", "720p", "1080p", "1440p" или "2160p".
+ /// "source", "720p", "1080p", "1440p", or "2160p".
public string RecordingResolution { get; set; } = "source";
- /// "desktop" или "game".
+ /// "desktop" or "game".
public string CaptureSource { get; set; } = "desktop";
- /// Полный путь к EXE выбранной игры; PID определяется при запуске pipeline.
+ /// Full path to the selected game executable; PID is resolved when the pipeline starts.
public string GameExecutablePath { get; set; } = "";
public bool CaptureSystemAudio { get; set; } = true;
public int SystemAudioVolume { get; set; } = 100;
- /// ID render-устройства для loopback; пусто — дефолтное устройство Windows.
+ /// Render-device ID used for loopback; empty selects the Windows default device.
public string SystemAudioDeviceId { get; set; } = "";
public bool CaptureMicrophone { get; set; }
public int MicrophoneVolume { get; set; } = 100;
public int MicrophoneBoostDb { get; set; }
- /// ID устройства микрофона; пусто — дефолтный микрофон Windows.
+ /// Microphone device ID; empty selects the Windows default microphone.
public string MicrophoneDeviceId { get; set; } = "";
public int AudioBitrateKbps { get; set; } = 192;
- /// "aac" для fragmented MP4 или "opus" для MKV.
+ /// "aac" for fragmented MP4 or "opus" for MKV.
public string AudioCodec { get; set; } = "aac";
///
- /// true — звук системы и микрофон сохраняются отдельными аудиодорожками;
- /// false — источники сводятся в одну дорожку.
+ /// true stores system audio and microphone on separate tracks;
+ /// false mixes both sources into one track.
///
public bool SeparateAudioTracks { get; set; }
@@ -51,31 +51,22 @@ public sealed class Config
[JsonIgnore]
public static string ConfigPath =>
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Captail", "config.json");
- [JsonIgnore]
- private static string LegacyConfigPath =>
- Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "InstantReplay", "config.json");
-
public static Config Load()
{
- foreach (string path in new[] { ConfigPath, LegacyConfigPath })
+ try
{
- try
+ if (File.Exists(ConfigPath))
{
- if (!File.Exists(path))
- continue;
-
Config config =
- JsonSerializer.Deserialize(File.ReadAllText(path)) ??
+ JsonSerializer.Deserialize(File.ReadAllText(ConfigPath)) ??
new Config();
config.Language = NormalizeLanguage(config.Language);
- if (!string.Equals(path, ConfigPath, StringComparison.OrdinalIgnoreCase))
- config.Save();
return config;
}
- catch
- {
- // Пробуем следующий путь; повреждённый конфиг не роняет запуск.
- }
+ }
+ catch
+ {
+ // A damaged config must not prevent startup.
}
var defaultConfig = new Config();
diff --git a/src/InstantReplay/EncoderCapabilities.cs b/src/Captail/EncoderCapabilities.cs
similarity index 99%
rename from src/InstantReplay/EncoderCapabilities.cs
rename to src/Captail/EncoderCapabilities.cs
index 331305c..8193e1a 100644
--- a/src/InstantReplay/EncoderCapabilities.cs
+++ b/src/Captail/EncoderCapabilities.cs
@@ -1,4 +1,4 @@
-namespace InstantReplay;
+namespace Captail;
public sealed record CodecCapability(
string Codec,
diff --git a/src/InstantReplay/HotkeyManager.cs b/src/Captail/HotkeyManager.cs
similarity index 96%
rename from src/InstantReplay/HotkeyManager.cs
rename to src/Captail/HotkeyManager.cs
index 587b8df..7e1f2ca 100644
--- a/src/InstantReplay/HotkeyManager.cs
+++ b/src/Captail/HotkeyManager.cs
@@ -2,9 +2,9 @@
using System.Windows.Input;
using System.Windows.Interop;
-namespace InstantReplay;
+namespace Captail;
-/// Два глобальных хоткея: сохранение повтора и включение/выключение буфера.
+/// Global hotkeys for saving a replay and toggling the replay buffer.
public sealed class HotkeyManager : IDisposable
{
[DllImport("user32.dll")]
diff --git a/src/InstantReplay/Interop/CaptureInterop.cs b/src/Captail/Interop/CaptureInterop.cs
similarity index 96%
rename from src/InstantReplay/Interop/CaptureInterop.cs
rename to src/Captail/Interop/CaptureInterop.cs
index ec5132c..cc9a37e 100644
--- a/src/InstantReplay/Interop/CaptureInterop.cs
+++ b/src/Captail/Interop/CaptureInterop.cs
@@ -3,7 +3,7 @@
using System.Runtime.InteropServices;
using System.Text;
-namespace InstantReplay.Interop;
+namespace Captail.Interop;
internal static class CaptureInterop
{
@@ -153,7 +153,7 @@ public static bool IsProcessRunning(string executablePath)
}
catch
{
- // Защищённые системные процессы не являются выбранной игрой.
+ // Protected system processes cannot be the selected game.
}
process.Dispose();
diff --git a/src/InstantReplay/Languages/Strings.en.xaml b/src/Captail/Languages/Strings.en.xaml
similarity index 100%
rename from src/InstantReplay/Languages/Strings.en.xaml
rename to src/Captail/Languages/Strings.en.xaml
diff --git a/src/InstantReplay/Languages/Strings.ru.xaml b/src/Captail/Languages/Strings.ru.xaml
similarity index 100%
rename from src/InstantReplay/Languages/Strings.ru.xaml
rename to src/Captail/Languages/Strings.ru.xaml
diff --git a/src/InstantReplay/Localization.cs b/src/Captail/Localization.cs
similarity index 98%
rename from src/InstantReplay/Localization.cs
rename to src/Captail/Localization.cs
index b0c84e4..8ea36ca 100644
--- a/src/InstantReplay/Localization.cs
+++ b/src/Captail/Localization.cs
@@ -1,7 +1,7 @@
using System.Globalization;
using System.Windows;
-namespace InstantReplay;
+namespace Captail;
public static class Localization
{
diff --git a/src/InstantReplay/Log.cs b/src/Captail/Log.cs
similarity index 95%
rename from src/InstantReplay/Log.cs
rename to src/Captail/Log.cs
index 734e8e9..fe477c5 100644
--- a/src/InstantReplay/Log.cs
+++ b/src/Captail/Log.cs
@@ -1,6 +1,6 @@
using System.IO;
-namespace InstantReplay;
+namespace Captail;
public static class Log
{
diff --git a/src/InstantReplay/ObsLogBridge.cs b/src/Captail/ObsLogBridge.cs
similarity index 76%
rename from src/InstantReplay/ObsLogBridge.cs
rename to src/Captail/ObsLogBridge.cs
index 9a34551..5ef1a5d 100644
--- a/src/InstantReplay/ObsLogBridge.cs
+++ b/src/Captail/ObsLogBridge.cs
@@ -1,6 +1,6 @@
using System.Runtime.InteropServices;
-namespace InstantReplay;
+namespace Captail;
internal static class ObsLogBridge
{
@@ -11,18 +11,18 @@ private delegate void LogCallback(
private static readonly LogCallback Callback = Write;
- [DllImport("EverloopObsBridge.dll", CallingConvention = CallingConvention.Cdecl)]
+ [DllImport("CaptailObsBridge.dll", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)]
private static extern bool everloop_install_obs_log_handler(LogCallback callback);
- [DllImport("EverloopObsBridge.dll", CallingConvention = CallingConvention.Cdecl)]
+ [DllImport("CaptailObsBridge.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern void everloop_remove_obs_log_handler();
internal static bool Install()
{
bool installed = everloop_install_obs_log_handler(Callback);
if (!installed)
- Log.Write("OBS log bridge не установился.");
+ Log.Write("OBS log bridge could not be installed.");
return installed;
}
diff --git a/src/InstantReplay/ObsNative.cs b/src/Captail/ObsNative.cs
similarity index 99%
rename from src/InstantReplay/ObsNative.cs
rename to src/Captail/ObsNative.cs
index 172ca30..bef1587 100644
--- a/src/InstantReplay/ObsNative.cs
+++ b/src/Captail/ObsNative.cs
@@ -1,6 +1,6 @@
using System.Runtime.InteropServices;
-namespace InstantReplay;
+namespace Captail;
internal static class ObsNative
{
diff --git a/src/InstantReplay/ObsReplayEngine.cs b/src/Captail/ObsReplayEngine.cs
similarity index 98%
rename from src/InstantReplay/ObsReplayEngine.cs
rename to src/Captail/ObsReplayEngine.cs
index fb2d46c..0baf990 100644
--- a/src/InstantReplay/ObsReplayEngine.cs
+++ b/src/Captail/ObsReplayEngine.cs
@@ -1,8 +1,8 @@
using System.IO;
using System.Runtime.InteropServices;
-using InstantReplay.Interop;
+using Captail.Interop;
-namespace InstantReplay;
+namespace Captail;
public sealed class ObsReplayEngine : IDisposable
{
@@ -163,7 +163,7 @@ public static EncoderCapabilities ProbeCapabilities(Config config)
}
catch (Exception exception)
{
- Log.Write($"Проверка возможностей GPU не удалась: {exception}");
+ Log.Write($"GPU capability detection failed: {exception}");
return EncoderCapabilities.Failed(exception.Message);
}
finally
@@ -479,8 +479,8 @@ private void CreateSources()
}
else
{
- // WGC переживает secure/DRM-поверхности и сбросы DXGI стабильнее;
- // защищённые участки становятся чёрными, сам источник не останавливается.
+ // WGC handles secure/DRM surfaces and DXGI resets more reliably;
+ // protected regions become black without stopping the source.
ObsNative.obs_data_set_int(videoSettings, "method", 2);
ObsNative.obs_data_set_string(
videoSettings,
@@ -628,8 +628,8 @@ private void CreateEncoders()
if (_videoEncoder == 0)
{
Log.Write(
- $"Кодировщик {candidate.EncoderId} отклонил профиль " +
- $"{loadProfile}; пробуем следующий.");
+ $"Encoder {candidate.EncoderId} rejected profile " +
+ $"{loadProfile}; trying the next candidate.");
continue;
}
@@ -922,7 +922,7 @@ private int AudioTrackCount()
int enabled = (_config.CaptureSystemAudio ? 1 : 0) +
(_config.CaptureMicrophone ? 1 : 0);
if (enabled == 0)
- return 1; // Replay Buffer требует аудиокодировщик; дорожка остаётся тихой.
+ return 1; // Replay Buffer requires an audio encoder; this track remains silent.
return _config.SeparateAudioTracks && enabled > 1 ? 2 : 1;
}
diff --git a/src/InstantReplay/OverlayNotificationWindow.xaml b/src/Captail/OverlayNotificationWindow.xaml
similarity index 97%
rename from src/InstantReplay/OverlayNotificationWindow.xaml
rename to src/Captail/OverlayNotificationWindow.xaml
index 457c8d7..7bd6d34 100644
--- a/src/InstantReplay/OverlayNotificationWindow.xaml
+++ b/src/Captail/OverlayNotificationWindow.xaml
@@ -1,4 +1,4 @@
-
+
@@ -155,7 +155,7 @@
-
+
-
+
-
+
-
+
-
+