Skip to content

Feature Request: Support Multiple Streams Per Camera Entity #158129

@Spittie68

Description

@Spittie68

The problem

Description:

The Problem

Home Assistant's camera entity architecture currently supports only one stream source per camera entity. This limitation affects multiple integrations and forces users to create duplicate camera entities as a workaround.

Current Behavior:

  • Each camera entity can only expose one stream via the stream_source() method
  • The method returns a single URL string, not a list or dictionary of streams
  • Users must create multiple camera entities to access different streams (main/sub) from the same physical camera

Affected Integrations:

Use Case

Modern IP cameras universally provide multiple simultaneous streams for different purposes:

  • Main stream (high resolution): For recording and detailed viewing (e.g., 2560×1920, 4K)
  • Sub stream (low resolution): For detection, thumbnails, and low-bandwidth viewing (e.g., 640×480, 720p)

Real-world scenario:
A user with 12 security cameras wants to:

  1. Display a grid dashboard using sub-streams (low bandwidth, fast loading)
  2. Click any camera to view HD popup with main stream (high quality, detailed view)
  3. Use sub-stream for object detection (lower CPU usage, faster processing)
  4. Record main stream for archival quality

Current Workaround

Users must create duplicate camera entities for each physical camera:

Example with Frigate:

go2rtc:
  streams:
    camera1_sub:
      - rtsp://camera1:554/stream2    # Sub stream
    camera1_main:
      - rtsp://camera1:554/stream1    # Main stream

cameras:
  camera1:           # For detection and grid view
    ffmpeg:
      inputs:
        - path: rtsp://127.0.0.1:8554/camera1_sub
          roles: [detect]
      
  camera1_hd:        # For HD viewing
    ffmpeg:
      inputs:
        - path: rtsp://127.0.0.1:8554/camera1_main
          roles: [record]

Problems with this approach:

  • Doubles (or triples) the number of camera entities
  • Increases system resource usage (duplicate processing)
  • Creates confusion in the UI (which entity to use?)
  • Requires extensive manual configuration
  • Breaks the logical relationship between streams from the same device

Proposed Solution

Option 1: Stream Dictionary (Minimal Breaking Change)

Extend the camera entity model to support multiple named streams:

async def stream_sources(self) -> dict[str, str] | None:
    """Return available stream sources."""
    return {
        "main": "rtsp://camera/main_stream",
        "sub": "rtsp://camera/sub_stream",
    }

Frontend integration:

  • Add stream selector dropdown in camera view
  • Allow card configuration to specify which stream to use
  • Default to first stream for backward compatibility

Option 2: Automatic Sub-entities

Integration automatically creates related entities for each stream:

  • camera.front_door (primary/default stream)
  • camera.front_door_main (high resolution stream)
  • camera.front_door_sub (low resolution stream)

All linked to the same device with clear naming convention.

Option 3: Stream Configuration in Integration Options

Allow users to configure which streams to expose via integration options UI, with ability to enable/disable specific stream entities.

Comparison with Design Philosophy

I understand Home Assistant's design philosophy is "one entity = one feature" (per architecture discussion #1061). However, I would argue that multiple streams from the same physical camera are not different features, but quality variants of the same feature (video streaming).

This is analogous to existing patterns in Home Assistant:

  • Media players - Support multiple quality/bitrate streams
  • Lights - Single entity exposes brightness, color temp, RGB (multiple attributes of illumination)
  • Climate - Single entity exposes heat/cool/auto modes (multiple variants of temperature control)
  • Covers - Single entity with position and tilt (multiple control dimensions)

The current limitation forces integrations into an awkward position:

  1. ✗ Limit functionality (expose only one stream) - Poor user experience
  2. ✗ Create duplicate entities (current workaround) - Violates DRY principle
  3. ✗ Build custom solutions outside camera platform - Fragments ecosystem

Benefits of Implementation

  1. Reduced Entity Count - One camera = one primary entity (with optional related entities)
  2. Lower Resource Usage - Eliminate duplicate processing for the same camera
  3. Improved UX - Clear, intuitive interface for stream selection
  4. Better Integration - Standardized way for integrations to expose stream variants
  5. Ecosystem Growth - Enables better support for modern camera features

Related Issues & Discussions

Additional Information

Camera models commonly affected:

  • Reolink (RLC-520A, RLC-810A, TrackMix, Duo series)
  • Foscam (all models with dual streams)
  • Hikvision (all modern IP cameras)
  • Dahua (all modern IP cameras)
  • Amcrest (all IP camera models)
  • Axis (multi-sensor cameras)
  • Virtually all modern IP security cameras

Integrations that would benefit:

  • Reolink (official)
  • Foscam (official)
  • ONVIF (official)
  • Generic Camera (official)
  • Frigate (custom, highly popular)
  • Blue Iris (custom)
  • UniFi Protect (custom)

I believe this enhancement would significantly improve the camera experience for a large portion of Home Assistant users, especially those with security camera systems.

What version of Home Assistant Core has the issue?

core-2025.10.1

What was the last working version of Home Assistant Core?

No response

What type of installation are you running?

Home Assistant OS

Integration causing the issue

No response

Link to integration documentation on our website

No response

Diagnostics information

No response

Example YAML snippet

Anything in the logs that might be useful for us?

Additional information

No response

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions