> ## 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.

# ILCKStreamingFeature (Unreal)

> Modular feature interface for live streaming backends in Unreal Engine.

## What Problem Does This Solve?

`ILCKStreamingFeature` abstracts live streaming so multiple backends can coexist:

* LIV cloud streaming (built-in)
* Custom RTMP backends
* Third-party streaming services

The interface uses Unreal's modular features system, allowing streaming implementations to register at runtime without compile-time dependencies.

## When to Use This

**Read this if:**

* Building a custom streaming backend
* Integrating a third-party streaming service
* Understanding how `ULCKService` discovers streaming providers

**Skip this if:** You're using the built-in streaming subsystem. Use `ULCKStreamingSubsystem` directly.

***

## Interface Definition

```cpp theme={null}
class LCKCORE_API ILCKStreamingFeature : public IModularFeature
{
public:
    virtual ~ILCKStreamingFeature() = default;

    DECLARE_MULTICAST_DELEGATE_OneParam(FOnPairingCode, const FString&);
    DECLARE_MULTICAST_DELEGATE(FOnAuthenticated);
    DECLARE_MULTICAST_DELEGATE(FOnStreamStarted);
    DECLARE_MULTICAST_DELEGATE(FOnStreamStopped);
    DECLARE_MULTICAST_DELEGATE_OneParam(FOnStreamError, const FString&);
    DECLARE_MULTICAST_DELEGATE(FOnLoggedOut);
    DECLARE_MULTICAST_DELEGATE(FOnStreamingConfigChanged);

    FOnPairingCode OnPairingCodeDelegate;
    FOnAuthenticated OnAuthenticatedDelegate;
    FOnStreamStarted OnStreamStartedDelegate;
    FOnStreamStopped OnStreamStoppedDelegate;
    FOnStreamError OnStreamErrorDelegate;
    FOnLoggedOut OnLoggedOutDelegate;
    FOnStreamingConfigChanged OnStreamingConfigChangedDelegate;

    static FName GetModularFeatureName() noexcept;

    virtual void StartLogin() = 0;
    virtual void CancelLogin() = 0;
    virtual void Logout() = 0;
    virtual bool IsAuthenticated() const = 0;

    virtual bool StartStreaming() = 0;
    virtual void StopStreaming() = 0;
    virtual bool IsStreaming() const = 0;
    virtual bool IsStartingOrStreaming() const;

    virtual void LaunchHub() = 0;
    virtual bool IsHubInstalled() const;
    virtual FString GetStreamingTargetName() const;
    virtual FString GetLastLogoutReason() const;
    virtual int32 GetPriority() const;
};
```

***

## Delegates

| Delegate                           | Signature                              | Description                              |
| ---------------------------------- | -------------------------------------- | ---------------------------------------- |
| `OnPairingCodeDelegate`            | `FOnPairingCode(const FString& Code)`  | New pairing code generated during login  |
| `OnAuthenticatedDelegate`          | `FOnAuthenticated()`                   | User successfully authenticated          |
| `OnStreamStartedDelegate`          | `FOnStreamStarted()`                   | Live stream has started                  |
| `OnStreamStoppedDelegate`          | `FOnStreamStopped()`                   | Live stream ended normally               |
| `OnStreamErrorDelegate`            | `FOnStreamError(const FString& Error)` | Streaming error occurred                 |
| `OnLoggedOutDelegate`              | `FOnLoggedOut()`                       | User logged out or was logged out        |
| `OnStreamingConfigChangedDelegate` | `FOnStreamingConfigChanged()`          | Streaming configuration changed remotely |

***

## Methods

### Authentication

| Method            | Signature                                  | Description                    |
| ----------------- | ------------------------------------------ | ------------------------------ |
| `StartLogin`      | `virtual void StartLogin() = 0`            | Begin device-code login flow   |
| `CancelLogin`     | `virtual void CancelLogin() = 0`           | Cancel in-progress login       |
| `Logout`          | `virtual void Logout() = 0`                | Log out and clear credentials  |
| `IsAuthenticated` | `virtual bool IsAuthenticated() const = 0` | Check if user is authenticated |

### Streaming

| Method                  | Signature                                    | Description                                                        |
| ----------------------- | -------------------------------------------- | ------------------------------------------------------------------ |
| `StartStreaming`        | `virtual bool StartStreaming() = 0`          | Start the live stream (returns false on failure)                   |
| `StopStreaming`         | `virtual void StopStreaming() = 0`           | Stop the live stream                                               |
| `IsStreaming`           | `virtual bool IsStreaming() const = 0`       | Check if currently streaming                                       |
| `IsStartingOrStreaming` | `virtual bool IsStartingOrStreaming() const` | True during startup or active streaming (default: `IsStreaming()`) |

### Platform & Utility

| Method                   | Signature                                        | Default | Description                                |
| ------------------------ | ------------------------------------------------ | ------- | ------------------------------------------ |
| `LaunchHub`              | `virtual void LaunchHub() = 0`                   | —       | Open the LIV Hub companion app             |
| `IsHubInstalled`         | `virtual bool IsHubInstalled() const`            | `true`  | Check if LIV Hub is installed              |
| `GetStreamingTargetName` | `virtual FString GetStreamingTargetName() const` | `""`    | Display name of streaming target           |
| `GetLastLogoutReason`    | `virtual FString GetLastLogoutReason() const`    | `""`    | Reason for last automatic logout           |
| `GetPriority`            | `virtual int32 GetPriority() const`              | `0`     | Priority when multiple backends registered |

***

## Discovery via Modular Features

The modular feature name is `"LCKStreamingFeature"`. Streaming features are discovered at runtime:

```cpp theme={null}
#include "LCKStreamingFeature.h"

ILCKStreamingFeature* FindStreamingFeature()
{
    auto& ModularFeatures = IModularFeatures::Get();
    FName FeatureName = ILCKStreamingFeature::GetModularFeatureName();

    if (ModularFeatures.IsModularFeatureAvailable(FeatureName))
    {
        TArray<ILCKStreamingFeature*> Features =
            ModularFeatures.GetModularFeatureImplementations<ILCKStreamingFeature>(
                FeatureName);

        // Sort by priority (highest first)
        Features.Sort([](const ILCKStreamingFeature& A, const ILCKStreamingFeature& B)
        {
            return A.GetPriority() > B.GetPriority();
        });

        return Features.Num() > 0 ? Features[0] : nullptr;
    }

    return nullptr;
}
```

***

## Usage Example

```cpp theme={null}
void UMyStreamingWidget::StartStream()
{
    ILCKStreamingFeature* Feature = FindStreamingFeature();
    if (!Feature) return;

    Feature->OnPairingCodeDelegate.AddLambda([this](const FString& Code)
    {
        ShowPairingCode(Code);
    });

    Feature->OnStreamStartedDelegate.AddLambda([this]()
    {
        ShowLiveIndicator();
    });

    if (!Feature->IsAuthenticated())
    {
        Feature->StartLogin();
    }
    else
    {
        Feature->StartStreaming();
    }
}
```

***

## Key Takeaways

<Check>**Modular features** — Runtime discovery, no compile-time coupling</Check>
<Check>**Priority system** — Multiple backends can coexist, highest priority wins</Check>
<Check>**Delegate-driven** — Subscribe to events for async state changes</Check>
<Check>**Auth before stream** — Always check `IsAuthenticated()` before `StartStreaming()`</Check>

***

## Related

* [Streaming Subsystem](/api-reference/unreal/streaming-subsystem) — Blueprint-friendly wrapper
* [Streaming Types](/api-reference/unreal/streaming-types) — Enums and data types
* [Packet Sink Interface](/api-reference/unreal/packet-sink-interface) — Custom transport layer
* [Encoder Interface](/api-reference/unreal/encoder-interface) — Video/audio encoding
