2026.8.2-dev pre-release: WE HAVE A F...ING ESPHOME VIDEOPHONE!
Pre-release2026.8.2-dev pre-release: WE HAVE A F...ING ESPHOME VIDEOPHONE!
2026.8.2-dev remains an active pre-release and work in progress. The tag and
HACS archive may be refreshed while field qualification continues. Use
2026.8.0 when you need the current stable release.
🔧 What 2026.8.2-dev adds
The original P4 videophone milestone is all still here. Since that first
development candidate, the project has also received a deep consolidation of
the PBX, SIP and media lifecycles:
- one generation-owned call session now governs direct, trunk, forwarded,
grouped, conference, browser and Assist calls; - answer, bridge activation, losing-leg settlement, projection, rollback and
termination now use shared authoritative primitives instead of parallel call
paths; - public idle is published only after call-scoped tasks, media owners, relays,
sockets and RTP reservations have crossed the cleanup barrier; - SIP interoperability now includes reliable provisional responses and PRACK,
initial and in-dialog delayed offers, RFC 4028 session refresh, remote forks
and late 2xx settlement, REFER/NOTIFY, stronger Digest authentication,
RFC 3263 discovery, TLS and IPv6; - registered clients, trunks and local endpoints share the same atomic
audio/video renegotiation mechanics, including audio-first video add, remove
and re-add without sacrificing the established audio call; - forwarding, ring groups, conference calls, DTMF routing and browser phones
retain one call owner and release failed or losing destinations without
disturbing the remaining members; - the P4 JPEG and H.264 paths gained bounded presentation work, bidirectional
cadence stabilization, post-call LVGL recovery and one-shot framebuffer
capture for direct physical-panel verification; - the ESP voice assistant is now documented as an independent optional device
capability, separate from a SIP call to Home Assistant Assist; - the local qualification toolkit now covers real Home Assistant, Chromium,
SIPp, baresip, registered clients, trunks, S3/P4 hardware, firmware metadata
and post-call quiescence without running jobs automatically on GitHub pushes.
This is still a development release. The stable baseline remains 2026.8.0.
🏠 Home Assistant and VoIP Stack
- The Home Assistant audio and video media paths now share one lifecycle for
authenticated ownership, replacement barriers, live-session resolution,
bridge leases, cleanup and final state publication. - Physical ESPHome phones and Home Assistant softphones now use the same
device_idsource selector. The service dispatches each phone through its
native adapter, and an ESP service response is no longer resolved again as
a browser phone. - The new
packages/voip/ha_phone.yamlpackage provides the complete physical
phone surface in one include: discovery entities, native call-control
actions and the Home Assistant managed phonebook. - SIP routing identity and presentation identity remain separate. Stable URI
users route calls, while standard quoted display names preserve spaces from
ESP friendly names, local accounts and external callers. RFC 4916 connected
identity lets the caller learn the resolved callee after answer. - SIP-to-SIP bridges negotiate each leg independently. Compatible codecs stay
on direct RTP, while the optional bounded FFmpeg fallback converts an
incompatible active direction to H.264, VP8 or RTP/JPEG as required by the
receiving endpoint. - An established audio call can add, remove and add video again through
standard in-dialog re-INVITE without restarting its audio relay. RTP profile,
direction, payload type and codec changes commit as one media generation. - Transcoded SIP audio is paced by its negotiated packet time, and immediate
redial waits for the previous bounded transcoder to release its slot. - Negotiated RFC 4733 DTMF payload types and media direction are retained
through direct, bridged and trunk call paths. - Browser ownership follows the logical phone, committed SIP transaction,
active call and media direction. Dashboard reloads and multiple cards can
hand media over without creating a second call owner. - Mixed browser and SIP ring groups let the first valid answer win, cancel the
losing INVITEs and settle every remaining leg. - Inbound routing, forwarding, conference ringing, SIP bridge handling and
browser media claims now use focused lifecycle owners whileCallRegistry
remains the observable compatibility index. - In-dialog video activation now follows the bridge relay that is actually active, not merely the presence of a dormant
recvonlySDP media line. Re-INVITEs preserve the negotiated RTP audio codec and payload instead of accidentally changing PCMA, PCMU, G.722 or Opus into L16. - Completed dialogs retain a bounded SIP transaction tombstone. A delayed retransmission of the original INVITE now receives
481 Call/Transaction Does Not Existand cannot reclaim a softphone after BYE. - Unexpected teardown failures are surfaced instead of being silently hidden,
and completed calls release their sessions, sockets, bridges and RTP ports. - FRITZ!Box REGISTER now uses the bare registrar URI, keeps the account AOR in
To and From, refreshes CSeq and Via branch after authentication, follows SIP
Timer F and runs without blocking Home Assistant setup. - FRITZ!Box interoperability has been improved for authenticated registration
and internal service dial strings such as**621. Thanks to
@ruedigerhanses-stack for the careful hardware testing and iterative
validation in issue #95. - RTP audio with valid packet boundaries different from negotiated
ptimeis
accumulated and reframed by the shared PCM converter. This fixes the
reported FRITZ!Box PCMA/16000 320-byte input without forcing a codec change. - ESPHome phonebook delivery now tracks exact content per device. Reconnects
restore only the restarted phone, while duplicate callbacks and unchanged
setup retries no longer republish the roster to every ESP. - Home Assistant configuration, entities, issues, system health and service
errors now include complete Brazilian Portuguese and German translations.
The Lovelace card, editor and phonebook follow the active HA language too. - dnspython SRV and NAPTR record parsers are preloaded outside Home Assistant's
event loop, removing the blocking-import warning during RFC 3263 trunk
resolution without changing dial-plan or DNS behavior. - Renaming a logical phone and then changing one of its entity IDs no longer
lets stale entity metadata restore the previous device name.
🎬 Browser video worker and card
-
JPEG encoding and decoding, plus H.264 and VP8 WebCodecs decoding when the
browser supports it, can run in a dedicated worker instead of blocking the
card UI. -
Worker generations prevent stale frames from a replaced call from reaching
the screen.VideoFrameandImageBitmapobjects are closed on success,
replacement and error paths. -
The card editor and view builder are now focused modules without changing
the public card configuration. -
The card remains the GUI and media surface of a logical softphone. The
softphone itself continues to exist and ring independently of an open card. -
Browser calls verify secure context, Web Audio support and microphone access
before signaling. A web view withoutgetUserMediano longer accepts a call
and immediately tears it down with BYE. -
Thanks to @csfrussa, browser microphone downsampling now applies a
fourth-order Butterworth anti-alias filter before decimation. In Chromium
validation it reduced a 12 kHz tone folding into 4 kHz by 23.4 dB while the
wanted 1 kHz signal remained unchanged. -
A
Microphone anti-alias filterswitch in the card's idleOptionspanel
lets each browser and logical phone compare the filtered and legacy paths.
It is enabled by default, applies from the next call and adds no filtering
cost when the browser and negotiated transmit rates already match. -
Browser softphones can now enumerate and remember the preferred microphone,
speaker and camera for each browser and logical phone. If no preference has
been selected, the existing browser defaults remain unchanged. -
Media devices can be changed while a call is ringing or established. Camera
replacement preserves the active SIP session and disposes the superseded
capture track instead of creating a parallel sender lifecycle. -
The card keeps one responsive
Optionssurface in idle, audio calls and
video calls. During video it becomes a compact settings icon inside the call
bar, while the opaque options view replaces the card content for clear and
accessible device selection. -
The existing hangup control now reacts subtly to received audio level without
overriding its responsive dimensions or adding a second audio capture path.
🎥 WE HAVE A F...ING ESPHOME VIDEOPHONE!
Everything started when @Psix-anp shared a working ESP32-P4 camera build based
on the ESPHome camera work by @youkorr. What can I say, half a second later I
was already experimenting with bidirectional SIP video on ESPHome.
And we made it. A P4 can now be a real audio and video SIP endpoint, including
bidirectional video on its own display. Better still, the JPEG path is light
enough to live inside the full P4 profile alongside Micro Wake Word, Voice
Assistant, AFE echo cancellation, LVGL, TTS and Sendspin.
This opens the door to custom ESPHome videophones and doorbells with echo
cancellation, full P4 voice-assistant tablets, and direct room-to-room audio
and video calls between P4 devices.
The implementation stays close to the accelerated Espressif media paths:
esp_video2.3.0 owns the MIPI-CSI and V4L2 camera pipeline. JPEG SIP TX
borrows the camera's already encoded access unit, so it does not capture or
encode the same frame a second time.- The JPEG camera follows Espressif's V4L2 startup practice and discards the
first two CSI buffers afterSTREAMON. Cross-codec calls therefore begin
with a color-stable JPEG and VP8 keyframe instead of publishing a transient
ISP startup frame. - The H.264 profile uses
esp_h2641.3.6 for the ESP32-P4 hardware encoder and
software decoder, withesp_image_effects1.1.0 for its optimized I420
conversion. - ESP-IDF PPA handles scaling, rotation and color conversion. Hardware JPEG
decode and direct MIPI DSI presentation keep the P4 display path lean. - JPEG and H.264 are gated at compile time. A JPEG firmware does not include
the H.264 media path, and the H.264 firmware does not include JPEG SIP video.
The P4 profiles are now:
- the canonical full AFE JPEG videophone,
waveshare-p4-touch-full-afe-landscape-videophone-jpeg.yaml; - the lightweight bidirectional RTP/JPEG videophone,
waveshare-p4-touch-videophone-jpeg.yaml; - the experimental bidirectional H.264 videophone,
waveshare-p4-touch-videophone-h264.yaml.
H.264 remains experimental in this pre-release. JPEG is the current full P4
baseline.
⌨️ Smaller ESPHome improvements
The compact Spotpear profile now has a dedicated touch keypad that keeps
contact navigation and direct extension dialing on the device.
Existing ESP audio profiles keep their native PCM transport and audio-stack
behavior. This update does not replace the audio backend or reduce configured
sample rates. P4 codec selection remains compile-time gated and its media tasks
remain event driven.
⚠️ Breaking change
The former P4 full landscape profile was promoted to the canonical full JPEG
videophone and renamed:
yamls/full-experience/single-bus/waveshare-p4-touch-full-afe-landscape.yaml
is now:
yamls/full-experience/single-bus/waveshare-p4-touch-full-afe-landscape-videophone-jpeg.yaml
Review the complete
breaking changes
before updating an existing installation.
✅ Qualification
1620Python tests plus140subtests passed on the published candidate.- Ruff passed for the custom component, ESPHome components, tests and tools.
- Every shipped JavaScript file passed syntax validation.
- The canonical full JPEG profile completed repeated real HA-to-P4 calls with
bidirectional audio and video, zero reported RTP loss or media drops, clean
BYE handling and quiescent call-scoped resource cleanup. - A Zoiper-style PCMA and VP8 call completed audio-to-video re-INVITE through
the HA B2BUA and its JPEG fallback. The first returned VP8 frame was a valid,
color-stable keyframe; all four audio/video RTP flows reported zero packet
loss and both JPEG depacketizers reported zero dropped access units. - The dedicated JPEG and experimental H.264 P4 profiles have both completed
real bidirectional audio and video calls on hardware. - Real
voip_stack.callservice tests originated calls from P4 to WS3 and
from WS3 to P4 using their Home Assistant Device IDs. Both directions
reachedin_call, returned the physical ESP source descriptor and cleaned
both endpoints back toidleafter hangup. - Ten consecutive real SIP cycles completed audio to video to audio renegotiation, bidirectional RTP, immediate redial and
BYE / 200 OK. A real card-originated call succeeded immediately after the tenth cleanup. - The final hardware matrix completed 12 calls across P4, WS3 and a real
trunk, including H.264 audio-video-audio-video renegotiation, SIP INFO and
RFC 2833 DTMF, hangup from both directions, immediate redial and zero
call-scoped resources after cleanup.
💖 Thanks for the donations
Special thanks to @jjhelin, @kuid87 and @jftkcs for supporting the project. If
VoIP Stack has been useful to you and you would like to support its continued
development, you can do so through
GitHub Sponsors.
📦 Installation and feedback
In HACS, enable pre-release versions for VoIP Stack. Open VoIP Stack, use the
three-dot menu, select Redownload and choose 2026.8.2-dev. Restart Home
Assistant, then clear the browser or Companion app cache so the updated card
multimedia engine is loaded.
When reporting a regression, include the exact test time, call direction,
endpoint models, selected codec and sanitized logs from INVITE through final
cleanup. The GitHub release contains the flat voip_stack.zip archive used by
HACS.
⚠️ Known issue: OnePlus high-refresh audio
On a OnePlus Nord 5, browser softphone receive audio can develop audible gaps
and increment the playback underrun counter at a high display refresh rate,
especially during touch interaction or orientation changes. The same call path
is stable on that phone at 60 Hz and has not reproduced on a Samsung S20 or
desktop browser.
The current workaround is to select the standard 60 Hz display mode, globally
or specifically for Chrome and the Home Assistant app. Initial evidence points
to device-side Chromium or OxygenOS scheduling under high-refresh rendering
load, but the exact cause is not yet proven. Deeper investigation is planned
after this release.
📞 Live SIP phonebook presence
- Local SIP accounts now appear in the Home Assistant managed phonebook only while they have an active registrar binding.
- REGISTER, explicit de-registration and natural Contact expiry rebuild and publish the same canonical roster to every connected ESPHome phone.
- Static contacts and browser phones remain independent from SIP registration state, while offline ESPHome endpoints continue to follow their own availability.


