> ## Documentation Index
> Fetch the complete documentation index at: https://docs.liv.tv/llms.txt
> Use this file to discover all available pages before exploring further.

# Changelog

> Release history and version notes for the LIV Camera Kit (LCK) SDK for Unreal Engine, including new features, bug fixes, breaking changes, and code reorganization across all modules.

<Update label="v1.0.0" description="17 March 2026">
  ### Overview

  LCK v1.0 is the first public release of the LIV Camera Kit SDK. This release introduces **live streaming** to YouTube, Twitch, and custom RTMP endpoints via the new `LCKStreaming` plugin, adds a Getting Started wizard for first-time setup, and improves audio quality with per-source sample rate handling. Encoding stability on Android has been significantly improved.

  ### Highlights

  * **Live Streaming** — Stream directly to YouTube, Twitch, or custom RTMP endpoints from VR via the new `LCKStreaming` plugin
  * **Modular Streaming Architecture** — `ILCKStreamingFeature` modular feature interface for streaming integration, discoverable via `IModularFeatures`
  * **Getting Started Wizard** — Editor wizard guides first-time setup with audio plugin selection and configuration
  * **Improved Audio Quality** — Per-source sample rate handling for correct resampling across all audio plugins
  * **Quest 2 Optimizations** — Capped HD profile to 30 fps / 8 Mbps for reliable recording on Quest 2

  ### New Features

  #### LCK Core SDK

  | Feature                             | Description                                                                                        |
  | ----------------------------------- | -------------------------------------------------------------------------------------------------- |
  | `ILCKStreamingFeature` interface    | Modular feature interface for streaming providers with login, streaming, and lifecycle APIs        |
  | Getting Started wizard              | Editor wizard with step-by-step setup and audio plugin configuration                               |
  | Editor menu                         | LCK menu in the editor toolbar for quick access to settings and about                              |
  | SDK version check                   | Automatic version check on editor startup with update notification                                 |
  | Per-source audio resampling         | Audio mixer resamples each source independently using reported sample rate                         |
  | `AcquireEncoder` / `ReleaseEncoder` | Reference-counted encoder access — multiple consumers (recording, streaming) can share the encoder |
  | `IsEncoderActive()`                 | Query whether the encoder is held by any consumer                                                  |
  | Quest 2 HD profile cap              | Caps HD recording to 30 fps and 8 Mbps on Quest 2                                                  |

  #### LCKStreaming (New Plugin)

  | Feature                        | Description                                                                                   |
  | ------------------------------ | --------------------------------------------------------------------------------------------- |
  | `ULCKStreamingSubsystem`       | Game instance subsystem for full streaming lifecycle (login, stream, stop)                    |
  | Device login/pairing           | Device pairing flow with code display, polling, and expiry handling                           |
  | YouTube / Twitch / Manual RTMP | Stream to YouTube (with broadcast creation), Twitch (with ingest lookup), or custom RTMP URLs |
  | RTMPS by default               | YouTube and Twitch streams use `rtmps://` for encrypted transport                             |
  | Per-platform bitrate presets   | Framerate-aware bitrate presets for 720p/1080p streaming per platform                         |
  | `IsRtmpAvailable()`            | Runtime check for RTMP native library availability                                            |
  | Conditional RTMP packaging     | RTMP libraries only packaged when `bEnableStreaming=true` in DefaultGame.ini                  |
  | App lifecycle handling         | Stop streaming on app backgrounding, re-validate auth on resume (Quest)                       |
  | Auto-logout on 401/403         | Expired auth tokens trigger automatic logout with `OnLoggedOut`                               |
  | User-friendly error messages   | Technical errors replaced with user-facing strings                                            |

  #### LCKTablet

  | Feature                | Description                                                                                                                                                              |
  | ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
  | Streaming integration  | `StartLogin()`, `CancelLogin()`, `Logout()`, `StartStreaming()`, `StopStreaming()`, `IsStreaming()`, `LaunchHub()`, `IsHubInstalled()` on `ULCKService`                  |
  | Streaming delegates    | `OnStreamingPairingCode`, `OnStreamingAuthenticated`, `OnStreamingStarted`, `OnStreamingStopped`, `OnStreamingError`, `OnStreamingLoggedOut`, `OnStreamingConfigChanged` |
  | `EnsureMicPermission`  | Async mic permission request with callback before recording/streaming                                                                                                    |
  | `FOnNotificationShown` | Delegate for notification display state changes                                                                                                                          |
  | Streaming UI elements  | GoLive button, Stream button, Live indicator, LIV Hub button, streaming timer                                                                                            |

  #### LCKUI

  | Feature              | Description                                                             |
  | -------------------- | ----------------------------------------------------------------------- |
  | GoLive button        | 3D button with long-press to start/stop streaming                       |
  | Live indicator       | Animated live status indicator with horizontal/vertical support         |
  | Stream button        | Streaming state toggle with disabled states                             |
  | LIV Hub button       | Button to launch LIV Hub companion app                                  |
  | Screen label         | Base class for text labels on 3D screens                                |
  | Long press support   | `BaseButton` long-press functionality with animation lock               |
  | `ELCKStreamingState` | Streaming state enum: `Idle`, `Pairing`, `Paired`, `Streaming`, `Error` |

  #### Audio Plugins

  | Plugin         | Changes                                                              |
  | -------------- | -------------------------------------------------------------------- |
  | LCKFMOD        | Pass sample rate through audio delegate for correct resampling       |
  | LCKOboe        | Pass sample rate, add idempotency guard to `StartCapture`            |
  | LCKUnrealAudio | Pass sample rate, add idempotency guards, fix mic capture flag reset |
  | LCKWwise       | Pass sample rate through audio delegate                              |
  | LCKVivox       | Pass sample rate through audio delegate                              |

  ### Bug Fixes

  | Fix                              | Platform | Description                                                                          |
  | -------------------------------- | -------- | ------------------------------------------------------------------------------------ |
  | Crash when stopping a stream     | Android  | Fixed multiple crash scenarios when stopping streaming or recording on Android       |
  | Encoder stability                | All      | Multiple crash, deadlock, and resource leak fixes in the encoding pipeline           |
  | Mic capture flag not resetting   | Android  | `bIsMicrophoneCapturing` now correctly resets on `StopCapture` in UnrealAudio source |
  | Mic not restarting after failure | All      | `SetMicrophoneEnabled(true)` now retries capture after a previous failed attempt     |
  | Encoder overload on Quest 2      | Android  | HD profile capped to 30 fps / 8 Mbps to prevent encoder overload on Quest 2          |

  ### Breaking Changes

  1. **`TSharedPtr` → `TSharedPtr<..., ESPMode::ThreadSafe>`** — All encoder and module shared pointers changed to thread-safe mode. Code holding `TSharedPtr<ILCKEncoder>` or `TSharedPtr<ILCKEncoderFactory>` must add `ESPMode::ThreadSafe`.

     ```cpp theme={null}
     // Before (v0.9.2)
     TSharedPtr<ILCKEncoderFactory> EncoderFactory;
     TSharedPtr<ILCKEncoder> Encoder;

     // After (v1.0)
     TSharedPtr<ILCKEncoderFactory, ESPMode::ThreadSafe> EncoderFactory;
     TSharedPtr<ILCKEncoder, ESPMode::ThreadSafe> Encoder;
     ```

  2. **`FDelegateRenderAudio` signature changed** — Audio delegate gained a `SampleRate` parameter. Code binding to `OnAudioDataDelegate` must update the callback signature.

     ```cpp theme={null}
     // Before (v0.9.2)
     DECLARE_MULTICAST_DELEGATE_ThreeParams(FDelegateRenderAudio,
         TArrayView<const float>, int32/*Channels*/, ELCKAudioChannel);

     // After (v1.0)
     DECLARE_MULTICAST_DELEGATE_FourParams(FDelegateRenderAudio,
         TArrayView<const float>, int32/*Channels*/, int32/*SampleRate*/, ELCKAudioChannel);
     ```

  3. **`FOnRecordStateChage` → `FOnRecordStateChange`** — Typo fix in delegate name.

     ```cpp theme={null}
     // Before (v0.9.2)
     DECLARE_MULTICAST_DELEGATE_OneParam(FOnRecordStateChage, ILCKRecordable*);

     // After (v1.0)
     DECLARE_MULTICAST_DELEGATE_OneParam(FOnRecordStateChange, ELCKRecordingState);
     ```

  4. **`LCKService::StartRecording()` return type changed** — Changed from `void` to `bool` and made `BlueprintCallable`.

     ```cpp theme={null}
     // Before (v0.9.2)
     void StartRecording();

     // After (v1.0)
     UFUNCTION(BlueprintCallable, Category = "LCK Service")
     bool StartRecording();
     ```

  5. **`ULCKNotificationController::WriteLine()` removed** — Use `ShowNotification()` instead.

     ```cpp theme={null}
     // Before (v0.9.2)
     void WriteLine(const FString& NewLine, float Duration = 3.0f);

     // After (v1.0) — removed, use:
     void ShowNotification(FLCKNotificationPtr Notification);
     ```

  6. **Telemetry structs simplified** — `FLCKGeoLocation`, `FLCKMetaData`, `FLCKTelemetryData`, and `FLCKTelemetryPayload` were removed from `LCKTelemetry.h`. `SendTelemetry(FLCKTelemetryEvent)` and `GetCurrentTrackingId()` still work as before.

  7. **LCKCore `Build.cs` dependency changes** — `HTTP` module removed from public dependencies. `Json`, `JsonUtilities` added as public. `ToolMenus` added for editor. If your module depended on `HTTP` being transitively available through LCKCore, add it to your own `Build.cs`.

  ### Migration Guide (v0.9.2 → v1.0)

  1. **Update shared pointer types** — If you hold `TSharedPtr<ILCKEncoder>` or `TSharedPtr<ILCKEncoderFactory>`, add `ESPMode::ThreadSafe` as the second template parameter.

  2. **Update audio delegate bindings** — `OnAudioDataDelegate` now has 4 parameters (added `int32 SampleRate` between `Channels` and `SourceChannel`). Update your callback signatures.

  3. **Update `FOnRecordStateChage` → `FOnRecordStateChange`** — Fix the typo in any delegate bindings.

  4. **Update `StartRecording()` callers** — Now returns `bool`. Update any code that called it as `void`.

  5. **Replace `WriteLine()` calls** — `ULCKNotificationController::WriteLine()` was removed. Use `ShowNotification()` instead.

  6. **Check telemetry type usage** — If you used `FLCKGeoLocation`, `FLCKMetaData`, `FLCKTelemetryData`, or `FLCKTelemetryPayload`, these structs were removed. Use `FLCKTelemetryEvent` directly.

  7. **Add `HTTP` module if needed** — `HTTP` was removed from LCKCore's public dependencies. If your module relied on it transitively, add `"HTTP"` to your own `Build.cs`.

  8. **Add `LCKStreaming` plugin dependency** — If your project uses streaming, add the `LCKStreaming` plugin to your `.uproject` or `.uplugin` file.

  9. **Enable streaming in config** — Set `bEnableStreaming=true` in `DefaultGame.ini` under `[/Script/LCKCore.LCKDeveloperSettings]` to package RTMP libraries.

  ### Platform Support

  | Platform             | Status                                                                    |
  | -------------------- | ------------------------------------------------------------------------- |
  | Meta Quest (Android) | Full support — recording, streaming, gallery save                         |
  | Windows (PCVR)       | Full support — recording, streaming                                       |
  | Linux                | Build support (listed in `SupportedTargetPlatforms`), not actively tested |
</Update>

<Update label="v0.9.2" description="2 February 2026">
  ### Highlights

  * **PCVR Support** — LCK is a single implementation for PCVR and Meta Quest Standalone
  * **Microphone Mute Control** — New `SetMicrophoneEnabled()` API for runtime mic control
  * **Audio Config Validation** — Real-time validation with editor warnings in Project Settings
  * **Permission Handling** — Improved Android microphone permission flow with callbacks
  * **Developer Settings UI** — Full settings panel in Project Settings with audio plugin configuration

  ### New Features

  #### LCK Core SDK

  | Feature                 | Description                                                                      |
  | ----------------------- | -------------------------------------------------------------------------------- |
  | Audio Config Validation | `ValidateAudioConfig()` method with FMOD > Wwise > UnrealAudio priority          |
  | Build Info API          | `GetLoadedAudioPlugins()`, `GetBuildInfoDescription()` with dynamic build number |
  | Microphone Mute Control | `SetMicrophoneEnabled()`, `IsMicrophoneEnabled()` for runtime mic control        |
  | Developer Settings UI   | Full settings panel in Project Settings with audio plugin checkboxes             |
  | Voice Chat Audio Source | `FLCKAudioSourceVoiceChat` struct for Vivox integration                          |
  | Plugin Detection        | Improved detection via IPluginManager with dependency checks                     |
  | Settings Categories     | Organized settings with headers, tooltips, and category grouping                 |
  | Audio Buffer Cleanup    | Clear previously buffered audio on state change                                  |

  #### LCKUI

  | Feature                | Description                                                   |
  | ---------------------- | ------------------------------------------------------------- |
  | Debug Mode System      | `ILCKVisuallyDebuggable` interface for debug visualization    |
  | Debug Button           | New debug toggle button in UI                                 |
  | ELCKMicState Enum      | Three-state: `On`, `Off`, `No_Access` for permission handling |
  | Audio Level Indicator  | Real-time microphone level display on recording button        |
  | Demo Dashboard         | `LCKDemoUIBoard` with FOV, quality, orientation, mic controls |
  | JSON State Persistence | Replaced USaveGame with JSON for tablet state                 |

  #### LCKTablet

  | Feature                        | Description                                                |
  | ------------------------------ | ---------------------------------------------------------- |
  | Android Permission Handling    | `RequestMicAccess()` with proper callback flow             |
  | Mic State Management           | `ToggleMicState()` with `No_Access` state support          |
  | Recording State Manager        | Mic level reading integrated into RecorderController       |
  | Developer Settings Integration | Uses `ULCKDeveloperSettings` for camera modes and profiles |
  | Data Model Delegates           | Added delegates for state change notifications             |
  | JSON Data Persistence          | Save/load tablet state as JSON with platform paths         |
  | Mic Audio Level API            | Read mic audio level via ULCKService                       |

  #### Audio Plugins

  | Plugin   | Changes                                          |
  | -------- | ------------------------------------------------ |
  | LCKVivox | SDK settings binding, microphone output fix      |
  | LCKOboe  | SDK settings binding for StartCapture            |
  | LCKWwise | SDK settings binding, documentation              |
  | LCKFMOD  | Capture fix, SDK settings binding, documentation |

  ### Bug Fixes

  | Fix                          | Platform | Description                                                      |
  | ---------------------------- | -------- | ---------------------------------------------------------------- |
  | Photo capture not triggering | All      | Fixed TSharedPtr notification handling                           |
  | TabletDataModel null crash   | All      | Use `NewObject` in BeginPlay instead of `CreateDefaultSubobject` |
  | Settings not restoring       | All      | Removed forced defaults on initialization                        |
  | Notification callbacks       | All      | Execute callback per queued notification                         |
  | Mic check on Windows         | Windows  | Return true for non-Android platforms                            |
  | SetupBindingToDataModel null | All      | Added null guard check                                           |

  ### Improvements

  | Improvement        | Description                                                      |
  | ------------------ | ---------------------------------------------------------------- |
  | Cleaned Constants  | Consolidated constants across LCKUI and LCKTablet modules        |
  | Camera Modes Moved | Camera modes moved from LCKUI to LCKTablet for better modularity |
  | JSON Helper Moved  | JSON utilities centralized in LCKTablet                          |
  | Plugin Icons       | Added icons for LCKUI and LCKTablet plugins                      |
  | Audio Sub-Levels   | Added audio sub-levels for middleware variants                   |

  ### Breaking Changes

  1. **`FLCKMetaData.Build`** — Changed from `int32` to `FString`

     ```cpp theme={null}
     // Before (v0.9.1)
     int32 BuildNumber = MetaData.Build;

     // After (v0.9.2)
     FString BuildString = MetaData.Build;
     ```

  2. **Mic state type** — Use `ELCKMicState` enum instead of `bool`

     ```cpp theme={null}
     // Before (v0.9.1)
     bool bMicEnabled = true;

     // After (v0.9.2)
     ELCKMicState MicState = ELCKMicState::On;
     // Values: On, Off, No_Access
     ```

  ### Code Reorganization

  Several components were moved between modules for better organization:

  | Component                       | From  | To        |
  | ------------------------------- | ----- | --------- |
  | Camera modes (`ELCKCameraMode`) | LCKUI | LCKTablet |
  | JSON helper utilities           | LCKUI | LCKTablet |
  | Tablet data model               | LCKUI | LCKTablet |
  | Tablet UI components            | LCKUI | LCKTablet |

  If you were importing these from LCKUI, update your includes to reference LCKTablet instead.
</Update>

<Update label="v0.9.1" description="16 December 2025">
  * Open Beta release
</Update>
