Documentation Index
Fetch the complete documentation index at: https://docs.daydream.live/llms.txt
Use this file to discover all available pages before exploring further.
Integration API
The Daydream TouchDesigner plugin exposes a Python API for scripting, automation, and building custom interfaces.
Accessing the Extension
# Get the extension from your Daydream component
ext = op('/daydream').ext.Daydream
Public Contract
The extension exposes PUBLIC_CONTRACT with introspectable metadata:
PUBLIC_CONTRACT = {
'extension_name': 'Daydream',
'lifecycle_methods': ['Login', 'Start', 'Stop', 'ResetParameters'],
'state_properties': ['state', 'Active', 'IsLoggedIn', 'ApiToken', 'stream_id', 'whip_url', 'whep_url'],
'states': ['IDLE', 'CREATING', 'STREAMING', 'ERROR'],
'listener_api': ['register_listener', 'unregister_listener'],
'events': [
'initialized',
'login_started', 'login_success', 'login_failed',
'stream_create_started', 'stream_created', 'stream_create_failed',
'streaming_started', 'streaming_stopped',
'params_update_sent', 'params_update_result',
'state_changed', 'error',
],
}
GetCapabilities
Query runtime capabilities for the current model:
ext = op('/daydream').ext.Daydream
caps = ext.GetCapabilities()
# Returns:
# {
# 'backend': 'daydream',
# 'version': 'x.y.z',
# 'model': 'stabilityai/sdxl-turbo',
# 'supported_models': ['stabilityai/sdxl-turbo', 'stabilityai/sd-turbo', ...],
# 'controlnets': ['depth', 'canny', 'tile'],
# 'ip_adapter_types': ['regular', 'faceid'],
# }
Use this to build adaptive interfaces that show only available options.
State Properties
Read the current state:
ext = op('/daydream').ext.Daydream
# Current state
print(ext.state) # 'IDLE', 'CREATING', 'STREAMING', or 'ERROR'
# Stream info
print(ext.stream_id)
print(ext.whip_url)
print(ext.whep_url)
# Auth status
print(ext.IsLoggedIn)
print(ext.Active)
Lifecycle Methods
Control the component programmatically:
ext = op('/daydream').ext.Daydream
# Start authentication flow
ext.Login()
# Start streaming (requires login)
ext.Start()
# Stop streaming
ext.Stop()
# Reset all parameters to defaults
ext.ResetParameters()
Event Listeners
Register a callback to receive lifecycle events without polling:
def on_daydream_event(event, payload):
# payload always includes: owner_path, state, stream_id
print(f"Event: {event}")
print(f"Payload: {payload}")
ext = op('/daydream').ext.Daydream
ext.register_listener(on_daydream_event)
# Later, to stop listening:
# ext.unregister_listener(on_daydream_event)
Event Reference
| Event | Payload | Description |
|---|
initialized | logged_in | Extension ready |
login_started | auth_port | Auth flow began |
login_success | — | Successfully logged in |
login_failed | error | Login error |
stream_create_started | model | Creating stream |
stream_created | whip_url, model_id | Stream ready |
stream_create_failed | error | Creation error |
streaming_started | whip_url, whep_url, model_id | Streaming active |
streaming_stopped | prev_stream_id | Streaming ended |
params_update_sent | changed, params | Parameters sent |
params_update_result | success, error | Update response |
state_changed | from, to, reason, error | State transition |
error | error, context, will_retry | Error occurred |
Example: State Machine Monitor
def on_event(event, payload):
if event == 'state_changed':
from_state = payload.get('from', 'unknown')
to_state = payload.get('to', 'unknown')
reason = payload.get('reason', '')
print(f"State: {from_state} → {to_state} ({reason})")
# Update UI based on state
if to_state == 'STREAMING':
op('status_text').par.text = 'Live!'
op('status_text').par.fontcolorr = 0
op('status_text').par.fontcolorg = 1
op('status_text').par.fontcolorb = 0
elif to_state == 'ERROR':
op('status_text').par.text = f'Error: {payload.get("error", "unknown")}'
op('status_text').par.fontcolorr = 1
op('status_text').par.fontcolorg = 0
op('status_text').par.fontcolorb = 0
elif event == 'streaming_started':
whep_url = payload.get('whep_url')
print(f"Watch at: {whep_url}")
elif event == 'error':
context = payload.get('context', 'unknown')
error = payload.get('error', 'unknown error')
will_retry = payload.get('will_retry', False)
print(f"Error in {context}: {error}")
if will_retry:
print("Will retry automatically...")
ext = op('/daydream').ext.Daydream
ext.register_listener(on_event)
Example: Dynamic Parameter Control
Control parameters from CHOPs for audio-reactive visuals:
# In an Execute DAT triggered by a CHOP
def onValueChange(channel, sampleIndex, val, prev):
daydream = op('/daydream')
if channel.name == 'audio_bass':
# Map bass to guidance scale
guidance = tdu.remap(val, 0, 1, 1.0, 2.5)
daydream.par.Guidance = guidance
elif channel.name == 'audio_mid':
# Map mids to delta
delta = tdu.remap(val, 0, 1, 0.3, 0.8)
daydream.par.Delta = delta
elif channel.name == 'beat':
# On beat, randomize seeds
if val > 0.5:
daydream.ext.Daydream.RandomizeSeeds()
Example: Custom Control Panel
Build a custom UI that shows only relevant controls:
# In a Panel Execute DAT
def onReady():
ext = op('/daydream').ext.Daydream
caps = ext.GetCapabilities()
# Show/hide ControlNet sliders based on model
available_controlnets = caps.get('controlnets', [])
for cn in ['depth', 'canny', 'tile', 'openpose', 'hed', 'color']:
slider = op(f'slider_{cn}')
if slider:
slider.par.display = cn in available_controlnets
# Show/hide IP Adapter based on model
ip_types = caps.get('ip_adapter_types', [])
op('ip_adapter_panel').par.display = len(ip_types) > 0
Next Steps