How to make a Reolink camera's speaker play arbitrary audio files or TTS announcements from Home Assistant — usable as an intercom, alarm, doorbell follow-up, or trespasser deterrent.
This uses ONVIF two-way audio over HA + go2rtc. No Reolink cloud, no Reolink mobile app, no vendor SDK — the camera just needs an ONVIF backchannel, which every modern Reolink model with a speaker has.
- A Reolink camera that supports two-way audio (has a built-in speaker). Most wired and PoE models from the last ~5 years qualify; battery-powered Argus/Go models don't.
- Camera reachable from HA over the network on its ONVIF port (typically 8000 on Reolink — not 554, which is RTSP and has no backchannel).
Two routes. Both require installing something — the question is which set of features you want.
Install the AlexxIT/WebRTC HACS integration. It bundles its own go2rtc binary (on port 1984) and provides a media_player: webrtc platform on top. You get:
media_player.play_mediaentities → first-class HA media players, usable withtts.speak, scripts, automations, and anywhere a media_player is expected.rest_command→/api/ffmpegservice calls (lighter alternative, also works).- Low-latency Lovelace camera card, HLS proxy, embed URLs,
dash_castservice — not required for audio playback, but bundled.
Install:
- HACS → Integrations → ⋮ → Custom repositories → add
https://github.com/AlexxIT/WebRTCas "Integration". - Install WebRTC Camera from the HACS list, restart HA.
- Add a
go2rtc.yamlfile in your config directory with your camera streams (see Step 1 below). AlexxIT's bundled go2rtc picks it up automatically.
⚠️ Until AlexxIT/WebRTC#942 is merged,media_player.play_mediafails with"can't find consumer"on most cameras (hardcoded codec mismatch). Apply the ~15-line patch manually tocustom_components/webrtc/media_player.pyandutils.py— diff is in the PR.
Install the go2rtc add-on (community, from AlexxIT's repo — not in the default add-on store). This gives you a standalone go2rtc instance on port 1984, and that's it: no HA entities, no Lovelace card, no media_player.
With this option, only the rest_command service-call path is available. You cannot use media_player.play_media — that platform lives in the AlexxIT custom component, not in go2rtc itself.
Install:
- Settings → Add-ons → Add-on store → ⋮ → Repositories → add
https://github.com/AlexxIT/hassio-addons. - Install go2rtc from the list, start it, enable "Start on boot".
- Put
go2rtc.yamlin your HA config directory (Step 1 below).
When to pick B: you only need service calls (no media_player entities), you don't want any custom components, and you're fine maintaining the add-on separately.
HA 2024.8+ ships go2rtc as a built-in system integration, auto-loaded via default_config. It's a backend for HA's Camera WebRTC provider — not something you interact with directly. By default it listens on a Unix socket only; no HTTP port is bound unless you explicitly set debug_ui: true in a go2rtc: config block, which then binds port 11984 behind Basic Auth. The built-in also doesn't read go2rtc.yaml — it auto-discovers streams from HA Camera integrations (Reolink, Generic Camera, etc.), not from a YAML file.
Net: the built-in covers HA's own use of go2rtc. It does not expose the /api/ffmpeg endpoint conveniently for rest_command, and it does not provide a media_player platform. Use Option A or B above.
This step is identical for Option A and Option B — both read the same go2rtc.yaml in your HA config directory.
Critical: the stream must include an onvif:// source. Without it, go2rtc has no backchannel to send audio to, regardless of which option you chose.
# go2rtc.yaml
streams:
entrance:
- onvif://admin:PASSWORD@192.168.1.237:8000/
- ffmpeg:rtsp://admin:PASSWORD@192.168.1.237:554/h264Preview_01_sub#audio=opusNotes:
- URL-encode special characters in the password (
@→%40,+→%2B, etc.). - The
ffmpeg:…#audio=opusline is optional — it provides listen-in audio in browsers via Opus transcoding. The firstonvif://line is the one that enables talk-back. - After editing, restart the go2rtc add-on (Option B) or restart HA Core (Option A — AlexxIT's bundled go2rtc is a subprocess of HA Core, so it restarts with HA).
Verify: open the go2rtc web UI at http://<HA-host>:1984. Find your stream → click it. You should see the camera's video and a media list that includes something like audio, sendonly, PCMU/8000 — that's the backchannel. If it's missing, your ONVIF URL is wrong.
Declare your media_player entities:
# configuration.yaml
media_player:
- name: entrance
platform: webrtc
stream: entrance # must match the go2rtc stream nameThen call it:
action: media_player.play_media
target:
entity_id: media_player.entrance
data:
media_content_type: music
media_content_id: https://example.com/path/to/alarm.mp3Heads up about the entity name. HA often registers these entities with a
_speakersuffix (e.g.media_player.entrance_speakerrather thanmedia_player.entrance) when the stream name collides with an existing camera entity of the same name. Once assigned, the suffix sticks in the entity registry. Always check Developer Tools → States for the actual entity IDs before scripting against them.
Define the rest_command once:
# configuration.yaml
rest_command:
go2rtc_audio:
method: POST
url: http://127.0.0.1:1984/api/ffmpeg?dst={{ camera | urlencode }}&file={{ audio_url | urlencode }}Call it from automations or scripts:
action: rest_command.go2rtc_audio
data:
camera: entrance # the go2rtc stream name
audio_url: https://example.com/path/to/alarm.mp3 # must be reachable from the go2rtc processgo2rtc spawns ffmpeg, transcodes to whatever codec the camera advertises (auto-negotiated), and streams it up the backchannel. Audio comes out of the camera within a couple of seconds.
For text-to-speech announcements, combine either path with any HA TTS engine (Piper, Google Translate, Cloud TTS, etc.).
action: tts.speak
target:
entity_id: tts.piper
data:
media_player_entity_id: media_player.entrance
message: "Package at the front door"
cache: trueClean, native, handles caching, URL resolution, language selection via the TTS engine. This is the main reason to prefer Option A.
HA's core TTS doesn't expose a direct "get URL" service as of 2024.8+. The simplest workaround is a second rest_command that calls HA's internal /api/tts_get_url endpoint, then pass the resulting URL to go2rtc_audio:
# configuration.yaml
rest_command:
tts_get_url:
url: http://127.0.0.1:8123/api/tts_get_url
method: POST
headers:
Authorization: !secret ha_long_lived_token # a long-lived access token
Content-Type: application/json
payload: '{"engine_id": "tts.piper", "message": "{{ message }}", "cache": true}'Then in a script:
script:
say_at_entrance:
fields:
message: { description: What to say }
sequence:
- action: rest_command.tts_get_url
data:
message: "{{ message }}"
response_variable: tts
- action: rest_command.go2rtc_audio
data:
camera: entrance
audio_url: "{{ tts.content.url }}"can't find consumer (HTTP 500 from go2rtc)
Despite the message, this usually means go2rtc couldn't match your requested codec with what the camera's backchannel accepts. If you're on the rest_command path, this shouldn't happen — /api/ffmpeg auto-negotiates. If you're on media_player.play_media with an unpatched AlexxIT/WebRTC, the integration hardcodes the codec from the (now-ignored) audio: config; apply PR #942 or fall back to the rest_command.
Timeout, no error
ffmpeg can't reach your audio URL from where go2rtc runs. Common causes: HA's media-proxy URL contains an auth token that expires before ffmpeg connects, or the URL uses localhost / a hostname that the go2rtc container can't resolve. Try a plain public mp3 URL first to prove the path works, then fix the URL generation.
Stream has no audio, sendonly, … line in go2rtc's UI
Your source is RTSP-only. Add an onvif:// line (port 8000 on Reolink) to the stream in go2rtc.yaml and restart go2rtc (or HA, if using AlexxIT's bundled go2rtc).
Audio is quiet on the camera speaker Reolink backchannel is known to be quiet out of the box. Add a volume boost via ffmpeg in go2rtc:
# go2rtc.yaml
ffmpeg:
bin: ffmpeg
volume: '-af "volume=30dB"'Playback works once then fails until camera restart Some Reolink firmware versions drop idle backchannel sessions after ~30–60s and need fresh ONVIF auth on the next call. If you see this, don't try to hold the backchannel open with a dummy producer — just make sure you're only opening the backchannel when actually playing.
Same author, different scopes. AlexxIT started with rtsp2webrtc_server (~2021) for low-latency RTSP in HA browsers, generalized it into the standalone go2rtc project (~2022), then kept the HA-specific glue (Lovelace card, media_player: webrtc platform, dash_cast, HLS proxy views, embed URLs) as the AlexxIT/WebRTC custom integration. In HA 2024.8 the core team adopted go2rtc as an internal backend for the Camera WebRTC provider but did not port the media_player platform or the card, so the custom integration remains the only place those features live.
Install AlexxIT/WebRTC via HACS if you want full support — media_player.play_media, tts.speak, the Lovelace card. Fall back to the go2rtc add-on alone if all you need is rest_command service calls. The HA built-in go2rtc, while present in Core since 2024.8, isn't a useful standalone option here. In every case: an onvif:// stream source in go2rtc.yaml is what makes talk-back possible.