# Creating Streaming Service Outputs with OBS_OUTPUT_SERVICE Protocol Support in OBS Studio

> **OBS Studio uses the `OBS_OUTPUT_SERVICE` protocol flag to bind streaming outputs to service objects that provide connection details like server URLs and stream keys, enabling a modular streaming architecture where outputs han...

- Repository: [OBS Project/obs-studio](https://github.com/obsproject/obs-studio)
- Tags: 
- Published: 2026-03-03

---

**OBS Studio uses the `OBS_OUTPUT_SERVICE` protocol flag to bind streaming outputs to service objects that provide connection details like server URLs and stream keys, enabling a modular streaming architecture where outputs handle encoding and delivery while services manage endpoint configuration.**

OBS Studio's plugin architecture separates the concerns of media delivery from connection management through the `OBS_OUTPUT_SERVICE` protocol flag. When building custom streaming outputs, implementing support for this flag allows your code to integrate seamlessly with OBS's existing service ecosystem, including RTMP, WHIP (WebRTC), and custom service configurations. This guide explains how to create streaming service outputs using the `OBS_OUTPUT_SERVICE` protocol based on the actual implementation in the obsproject/obs-studio repository.

## Declaring the OBS_OUTPUT_SERVICE Flag

To create an output that requires service configuration, you must declare the `OBS_OUTPUT_SERVICE` flag in your `obs_output_info` structure. This flag, defined in [`libobs/obs-output.h`](https://github.com/obsproject/obs-studio/blob/main/libobs/obs-output.h) as `(1 << 3)`, signals to OBS that your output expects an associated service object at runtime.

In [`libobs/obs-output.h`](https://github.com/obsproject/obs-studio/blob/main/libobs/obs-output.h) line 29, the flag is defined:

```c
#define OBS_OUTPUT_SERVICE (1 << 3)

```

When OBS loads your plugin, it checks this flag to determine if the output supports service binding. The internal helper `obs_output_has_service()` in [`libobs/obs-output.c`](https://github.com/obsproject/obs-studio/blob/main/libobs/obs-output.c) (line 110) verifies this:

```c
return (output->info.flags & OBS_OUTPUT_SERVICE) != 0;

```

Real-world implementations demonstrate this pattern across multiple protocols. The RTMP output in [`plugins/obs-outputs/rtmp-stream.c`](https://github.com/obsproject/obs-studio/blob/main/plugins/obs-outputs/rtmp-stream.c) (line 1798) registers with:

```c
.flags = OBS_OUTPUT_AV | OBS_OUTPUT_ENCODED | OBS_OUTPUT_SERVICE | OBS_OUTPUT_MULTI_TRACK_AV,

```

Similarly, the WHIP output for WebRTC streaming in [`plugins/obs-webrtc/whip-output.cpp`](https://github.com/obsproject/obs-studio/blob/main/plugins/obs-webrtc/whip-output.cpp) (line 723) uses:

```cpp
const uint32_t base_flags = OBS_OUTPUT_ENCODED | OBS_OUTPUT_SERVICE | OBS_OUTPUT_MULTI_TRACK_AV;

```

## Registering Outputs and Services

The registration process involves two distinct steps: registering the output that requires service support, and registering the service that provides connection data.

First, register your output using `obs_register_output()`:

```c
static struct obs_output_info my_output_info = {
    .id = "my_custom_output",
    .flags = OBS_OUTPUT_SERVICE | OBS_OUTPUT_ENCODED,
    .create = my_output_create,
    .destroy = my_output_destroy,
    .start = my_output_start,
    .stop = my_output_stop,
    .get_name = my_output_get_name,
};

// In your plugin load function
obs_register_output(&my_output_info);

```

Services are registered separately via `obs_register_service()`. Built-in services like RTMP Common in [`plugins/rtmp-services/rtmp-common.c`](https://github.com/obsproject/obs-studio/blob/main/plugins/rtmp-services/rtmp-common.c) (line 1160) implement the `obs_service_info` structure:

```c
struct obs_service_info rtmp_common_service = {
    .id = "rtmp_common",
    .create = rtmp_common_create,
    .destroy = rtmp_common_destroy,
    .get_connect_info = rtmp_common_get_connect_info,
    // ...
};

```

## Binding Services to Outputs

During configuration, OBS binds a service instance to your output using the public API declared in [`libobs/obs.h`](https://github.com/obsproject/obs-studio/blob/main/libobs/obs.h) (lines 2061-2064). The workflow involves creating both objects and then associating them:

```c
// Create the output
obs_output_t *output = obs_output_create("my_custom_output", "My Output", settings, NULL);

// Create the service
obs_service_t *service = obs_service_create("rtmp_common", "My Service", service_settings, NULL);

// Bind service to output
obs_output_set_service(output, service);

```

The output holds a reference to the service through reference counting (`obs_service_addref`/`obs_service_release`), ensuring the service remains valid throughout the streaming session.

## Retrieving Connection Information

Once streaming starts, your output retrieves connection parameters from the bound service using `obs_service_get_connect_info()`. The API in [`libobs/obs.h`](https://github.com/obsproject/obs-studio/blob/main/libobs/obs.h) (line 2555) provides:

```c
const char *obs_service_get_connect_info(const obs_service_t *service, uint32_t type);

```

The WHIP output implementation in [`plugins/obs-webrtc/whip-output.cpp`](https://github.com/obsproject/obs-studio/blob/main/plugins/obs-webrtc/whip-output.cpp) (lines 252-264) demonstrates this pattern:

```cpp
obs_service_t *service = obs_output_get_service(output);
if (!service) {
    // Handle missing service error
    return false;
}

const char *endpoint_url = obs_service_get_connect_info(
    service, OBS_SERVICE_CONNECT_INFO_SERVER_URL);
const char *bearer_token = obs_service_get_connect_info(
    service, OBS_SERVICE_CONNECT_INFO_BEARER_TOKEN);

```

Available connection info types include:
- `OBS_SERVICE_CONNECT_INFO_SERVER_URL`
- `OBS_SERVICE_CONNECT_INFO_STREAM_KEY`
- `OBS_SERVICE_CONNECT_INFO_BEARER_TOKEN`

The FFmpeg muxer in [`plugins/obs-ffmpeg/obs-ffmpeg-mux.c`](https://github.com/obsproject/obs-studio/blob/main/plugins/obs-ffmpeg/obs-ffmpeg-mux.c) (line 894) also utilizes this protocol:

```c
.flags = OBS_OUTPUT_AV | OBS_OUTPUT_ENCODED | OBS_OUTPUT_MULTI_TRACK | OBS_OUTPUT_SERVICE,

```

## Complete Implementation Example

Below is a complete skeleton demonstrating how to implement an output with `OBS_OUTPUT_SERVICE` support:

```c
#include <obs-module.h>

struct my_stream_output {
    obs_output_t *output;
    // Your custom data
};

static const char *my_output_get_name(void *unused)
{
    UNUSED_PARAMETER(unused);
    return "My Service Output";
}

static void *my_output_create(obs_data_t *settings, obs_output_t *output)
{
    struct my_stream_output *data = bzalloc(sizeof(struct my_stream_output));
    data->output = output;
    return data;
}

static void my_output_destroy(void *data)
{
    bfree(data);
}

static bool my_output_start(void *data)
{
    struct my_stream_output *out = data;
    
    // Retrieve the bound service
    obs_service_t *service = obs_output_get_service(out->output);
    if (!service) {
        blog(LOG_ERROR, "No service attached to output");
        return false;
    }
    
    // Get connection details
    const char *server_url = obs_service_get_connect_info(
        service, OBS_SERVICE_CONNECT_INFO_SERVER_URL);
    const char *stream_key = obs_service_get_connect_info(
        service, OBS_SERVICE_CONNECT_INFO_STREAM_KEY);
    
    if (!server_url || !stream_key) {
        blog(LOG_ERROR, "Missing connection information");
        return false;
    }
    
    // Initialize your streaming connection using server_url and stream_key
    // ...
    
    return true;
}

static void my_output_stop(void *data, uint64_t ts)
{
    // Cleanup streaming connection
}

static struct obs_output_info my_output_info = {
    .id = "my_service_output",
    .flags = OBS_OUTPUT_SERVICE | OBS_OUTPUT_ENCODED | OBS_OUTPUT_AV,
    .get_name = my_output_get_name,
    .create = my_output_create,
    .destroy = my_output_destroy,
    .start = my_output_start,
    .stop = my_output_stop,
};

OBS_MODULE_EXPORT uint32_t obs_module_ver(void)
{
    return LIBOBS_API_VER;
}

OBS_MODULE_EXPORT bool obs_module_load(void)
{
    obs_register_output(&my_output_info);
    return true;
}

```

## Summary

- **`OBS_OUTPUT_SERVICE`** is defined in [`libobs/obs-output.h`](https://github.com/obsproject/obs-studio/blob/main/libobs/obs-output.h) as `(1 << 3)` and indicates that an output requires service configuration.
- Outputs declare this flag in their `obs_output_info` structure during registration via `obs_register_output()`.
- Services are registered separately using `obs_register_service()` and implement `obs_service_get_connect_info()` to expose connection data.
- The binding occurs through `obs_output_set_service()`, which the OBS frontend calls when users select streaming profiles.
- During streaming, outputs call `obs_output_get_service()` followed by `obs_service_get_connect_info()` to retrieve server URLs, stream keys, and authentication tokens.

## Frequently Asked Questions

### What is the difference between an output and a service in OBS Studio?

An **output** is the code module that encodes and transmits media data to a destination, while a **service** is a configuration object that provides connection parameters like server URLs and stream keys. The `OBS_OUTPUT_SERVICE` protocol allows outputs to remain generic while services handle platform-specific connection details.

### How does OBS know if an output requires a service?

OBS checks the `flags` field of the `obs_output_info` structure when the output is registered. If the flag includes `OBS_OUTPUT_SERVICE` (verified by `obs_output_has_service()` in [`libobs/obs-output.c`](https://github.com/obsproject/obs-studio/blob/main/libobs/obs-output.c)), OBS enables service binding functionality for that output instance.

### Can third-party plugins create custom services for existing outputs?

Yes, third-party plugins can implement custom services by filling an `obs_service_info` structure and registering it with `obs_register_service()`. Any output that declares the `OBS_OUTPUT_SERVICE` flag can automatically use any registered service, including custom implementations that provide connection info through `obs_service_get_connect_info()`.

### What connection information types are available through the service API?

The service API supports multiple connection info types including `OBS_SERVICE_CONNECT_INFO_SERVER_URL` for the streaming endpoint, `OBS_SERVICE_CONNECT_INFO_STREAM_KEY` for authentication, and `OBS_SERVICE_CONNECT_INFO_BEARER_TOKEN` for token-based protocols like WHIP, as implemented in [`plugins/obs-webrtc/whip-output.cpp`](https://github.com/obsproject/obs-studio/blob/main/plugins/obs-webrtc/whip-output.cpp).