What Problem Does This Solve?
ULCKStreamingSubsystem is the Blueprint-friendly entry point for live streaming:
- Authenticate with LIV’s streaming service via device pairing
- Start and stop live streams to YouTube, Twitch, or custom RTMP targets
- Monitor stream state, errors, and configuration changes
It implements ILCKStreamingFeature and exposes everything as BlueprintCallable / BlueprintAssignable.
When to Use This
Use ULCKStreamingSubsystem when:
- Building a “Go Live” button in your game
- Creating a streaming dashboard UI
- Integrating streaming into your game flow
Don’t use this directly if: You’re building a custom streaming backend — implement ILCKStreamingFeature instead.
Accessing the Subsystem
ULCKStreamingSubsystem* Streaming =
GetGameInstance()->GetSubsystem<ULCKStreamingSubsystem>();
Delegates
All delegates are BlueprintAssignable.
| Delegate | Signature | Description |
|---|
OnPairingCodeReceived | FOnLCKPairingCodeReceived(const FString&, Code) | Pairing code ready for display |
OnAuthenticated | FOnLCKAuthenticated() | User successfully authenticated |
OnStreamingConfigReceived | FOnLCKStreamingConfigReceived(ELCKStreamingTargetType, const FLCKUserSubscription&) | Config loaded from server |
OnStreamStarted | FOnLCKStreamStarted() | Live stream has started |
OnStreamStopped | FOnLCKStreamStopped() | Live stream ended normally |
OnStreamError | FOnLCKStreamError(const FString&, ErrorMessage) | Streaming error occurred |
OnLoggedOut | FOnLCKLoggedOut() | User logged out |
Authentication Methods
| Method | Return | Description |
|---|
StartLogin() | void | Begin device-code login flow (polls every 2.5s) |
CancelLogin() | void | Cancel in-progress login |
GetPairingCode() | FString | Current pairing code (BlueprintPure) |
IsAuthenticated() | bool | Check if authenticated (BlueprintPure) |
Logout() | void | Log out and clear credentials |
Configuration Methods
| Method | Return | Description |
|---|
RefreshStreamingConfig(bool bSilent) | void | Refresh config from server (bSilent suppresses errors) |
HasStreamingTarget() | bool | Has YouTube/Twitch/Manual target? (BlueprintPure) |
HasActiveSubscription() | bool | Has active LIV subscription? (BlueprintPure) |
GetStreamingTargetType() | ELCKStreamingTargetType | Current target type (BlueprintPure) |
Streaming Methods
| Method | Return | Description |
|---|
StartStreaming() | bool | Start live stream (15s timeout) |
StopStreaming() | void | Stop live stream |
IsStreaming() | bool | Is currently streaming? (BlueprintPure) |
IsStartingOrStreaming() | bool | Starting or streaming? |
| Method | Return | Description |
|---|
LaunchHub() | void | Open LIV Hub (Android only) |
IsHubInstalled() | bool | Is LIV Hub installed? |
GetStreamingTargetName() | FString | Display name (e.g., “YouTube”) |
GetLastLogoutReason() | FString | Reason for last automatic logout |
Streaming Bitrate Presets
YouTube
| Quality | Video Bitrate | Audio Bitrate |
|---|
| SD | 4 Mbps | 128 Kbps |
| HD @30 | 8 Mbps | 128 Kbps |
| HD @60 | 12 Mbps | 128 Kbps |
| 2K | 24 Mbps | 128 Kbps |
| 4K | 35 Mbps | 128 Kbps |
Twitch
| Quality | Video Bitrate | Audio Bitrate |
|---|
| SD | 3 Mbps | 96 Kbps |
| HD @30 | 4.5 Mbps | 96 Kbps |
| HD @60 | 6 Mbps | 96 Kbps |
| 2K | 9 Mbps | 96 Kbps |
| 4K | 10 Mbps | 96 Kbps |
Keyframe interval is fixed at 2 seconds. Bitrates are applied automatically based on the streaming target and quality profile.
Timing Constants
| Constant | Value | Description |
|---|
| Auth poll interval | 2.5s | Pairing confirmation polling |
| Stream start timeout | 15s | Maximum RTMP connection wait |
| Health check interval | 5s | Encoder health monitoring |
| Health check tolerance | 2 | Consecutive failures before stopping |
Usage Example
UCLASS()
class UStreamingManager : public UActorComponent
{
GENERATED_BODY()
public:
virtual void BeginPlay() override
{
Super::BeginPlay();
auto* Streaming = GetWorld()->GetGameInstance()
->GetSubsystem<ULCKStreamingSubsystem>();
if (!Streaming) return;
Streaming->OnPairingCodeReceived.AddDynamic(
this, &UStreamingManager::OnCode);
Streaming->OnAuthenticated.AddDynamic(
this, &UStreamingManager::OnAuth);
Streaming->OnStreamStarted.AddDynamic(
this, &UStreamingManager::OnLive);
Streaming->OnStreamError.AddDynamic(
this, &UStreamingManager::OnError);
}
UFUNCTION(BlueprintCallable)
void Login()
{
auto* S = GetWorld()->GetGameInstance()
->GetSubsystem<ULCKStreamingSubsystem>();
S->StartLogin();
}
UFUNCTION(BlueprintCallable)
void ToggleStream()
{
auto* S = GetWorld()->GetGameInstance()
->GetSubsystem<ULCKStreamingSubsystem>();
if (S->IsStreaming())
S->StopStreaming();
else if (S->HasStreamingTarget())
S->StartStreaming();
}
private:
UFUNCTION() void OnCode(const FString& Code) { ShowPairingUI(Code); }
UFUNCTION() void OnAuth() { ShowStreamControls(); }
UFUNCTION() void OnLive() { ShowLiveIndicator(); }
UFUNCTION() void OnError(const FString& E) { ShowError(E); }
};
Key Takeaways
GameInstance subsystem — Available globally, survives level transitions
Blueprint-ready — All methods and delegates are Blueprint accessible
Auth-first flow — Login, configure target, then stream
Check prerequisites — Verify IsAuthenticated() and HasStreamingTarget() before streaming