Skip to main content

Recording

Resolution & Bitrate Guidelines

QualityResolutionBitrateTarget FPSUse Case
SD1280 x 7202-4 Mbps30Mobile VR, performance mode
HD1920 x 10804-8 Mbps30Standard recording
2K2560 x 14408-12 Mbps30High quality
4K3840 x 216012-20 Mbps30Maximum quality (PC)
For Meta Quest devices, start with HD (1080p) at 30 FPS. Higher resolutions may impact game performance.

Event-Driven Operations

Subscribe to recording events for responsive feedback:
// Subscribe to events
Service->OnRecordingSaveFinished.AddDynamic(this, &AMyActor::HandleSaveFinished);
Service->OnRecordingError.AddDynamic(this, &AMyActor::HandleRecordingError);
Service->OnRecordingSaveProgress.AddDynamic(this, &AMyActor::HandleSaveProgress);

// Start recording
Service->StartRecording();
ShowRecordingIndicator();

void AMyActor::HandleSaveFinished(bool bSuccess)
{
    if (bSuccess)
        ShowSuccessMessage();
    else
        ShowErrorMessage();
}

void AMyActor::HandleRecordingError(FString ErrorMessage, int32 ErrorCode)
{
    UE_LOG(LogLCK, Error, TEXT("Error %d: %s"), ErrorCode, *ErrorMessage);
    ShowErrorNotification(ErrorMessage);
}
For advanced async control, use ULCKRecorderSubsystem directly:
ULCKRecorderSubsystem* Recorder = GetWorld()->GetSubsystem<ULCKRecorderSubsystem>();
Recorder->StartRecordingAsync(FOnLCKRecorderBoolResult::CreateLambda([this](bool bSuccess) {
    if (bSuccess)
        ShowRecordingIndicator();
    else
        ShowErrorMessage();
}));

Audio

Source Priority

When multiple sources are available:
SourceBest ForLatency
LCKUnrealAudioGeneral use, cross-platformLow
LCKFMODFMOD projectsVery Low
LCKWwiseWwise projectsVery Low
LCKOboeAndroid microphoneVery Low
LCKVivoxVoice chat captureLow

Sample Rate Matching

// Get Unreal Audio sample rate
int32 SampleRate = ULCKUnrealAudioBPL::GetUnrealAudioSamplerate();

// Configure encoder with matching rate
FLCKRecorderParams Params;
Params.Samplerate = SampleRate;

Audio Callbacks

Audio callbacks may come from different threads. Use thread-safe patterns:
// Note: BindLambda (single delegate, not AddLambda)
AudioSource->OnAudioDataDelegate.BindLambda([this](
    TArrayView<const float> PCM,
    int32 Channels,
    ELCKAudioChannel Source)
{
    // Queue for game thread if needed
    AsyncTask(ENamedThreads::GameThread, [this, Data = TArray<float>(PCM)]() {
        ProcessAudioOnGameThread(Data);
    });
});

UI

Button Cooldown

The SDK includes automatic 0.25s cooldown - don’t add your own:
// Just bind the event, cooldown is automatic
Button->OnTapStarted.AddDynamic(this, &AMyActor::HandleTap);

Showable Groups

Group related UI for batch operations:
ULCKShowablesGroup* SettingsGroup = NewObject<ULCKShowablesGroup>(this);
SettingsGroup->Add(FOVButton);
SettingsGroup->Add(DistanceButton);
SettingsGroup->Add(SmoothnessButton);

// Batch show/hide
SettingsGroup->Show();
SettingsGroup->Hide();

Performance

Scene Capture Optimization

CaptureComponent->CaptureSource = ESceneCaptureSource::SCS_FinalColorLDR;
CaptureComponent->bCaptureEveryFrame = false;
CaptureComponent->bCaptureOnMovement = false;

Memory Management

void AMyRecorder::StopAndRelease()
{
    Service->StopRecording();
    Service->UnregisterCaptureComponent(TEXT("MainCapture"));
}

Common Pitfalls

Problem: No feedback to user when recording starts/stops/fails.Solution: Subscribe to OnRecordingSaveFinished, OnRecordingError, and OnRecordingSaveProgress delegates.
Problem: Render target doesn’t match recording resolution.Solution: Ensure render target and recording parameters match exactly.
Problem: Memory leaks from orphaned capture components.Solution: Always call UnregisterCaptureComponent(ComponentName) when done.
Problem: Audio distortion or sync issues.Solution: Query and match sample rates between audio source and encoder.
Problem: Audio delegate is single, not multicast.Solution: Use BindLambda() instead of AddLambda() for OnAudioDataDelegate.

Platform Checklist

  • Vulkan enabled
  • RECORD_AUDIO permission
  • WRITE_EXTERNAL_STORAGE permission
  • LCKOboe plugin enabled (for low-latency mic)

Debugging

Log Categories

; DefaultEngine.ini
[Core.Log]
LogLCK=VeryVerbose
LogLCKEncoding=VeryVerbose
LogLCKAudio=VeryVerbose
LogLCKUI=Verbose

Common Log Messages

LogMeaning
LogLCK: Recording startedRecording began
LogLCKEncoding: Encoder initializedEncoder ready
LogLCKAudio: Audio source registeredAudio available
LogLCKUI: Button pressedUI interaction