The Reolink RTMP server does not percent-decode query parameter values - it compares the raw bytes from the URL against the stored password. URLSearchParams.set() percent-encodes values when the URL is serialised (WHATWG application/x-www-form-urlencoded), which corrupts passwords containing characters such as '!' (-> '%21'), '#' (-> '%23'), '+' (-> '%2B'), space, etc.
Affected: users whose firmware causes getLoginParameters to return {user, password} (instead of a Login-API token) and whose password contains any of those characters. Symptom: rebroadcast prebuffer fails with 'Socket received FIN' immediately after 'Sending play command'.
Append the RTMP credential pairs as raw bytes instead of going through URLSearchParams. Token-only path is unaffected (hex tokens contain no characters that require encoding). Mirrors the rationale of #1509 for the HTTP API path.
Fixes#2057
Co-authored-by: thllxb <223556219+Copilot@users.noreply.github.com>
* fix: show stream selection options when synthetic streams are configured
* fix: show stream selection options and enforce FFmpeg parser for synthetic streams
The ReolinkCameraClient never called the Logout API before requesting a
new token, causing stale sessions to accumulate on the camera. When the
camera's session limit was reached (~68 min cycle), it would close the
RTMP/RTSP connection, dropping the stream.
Add a logout() method that releases the old token session before login()
requests a new one, matching the pattern already used by ReolinkNvrClient.
This prevents session buildup and eliminates periodic stream drops.
Fixes#1873
Co-authored-by: Josh Casada <joshcasada@Joshs-Mac-mini.ts.net lan>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
The RTMP client's totalBytesReceived counter grows unbounded as a
JavaScript number. When it exceeds 2^31 (~2.15 GB received), the
writeUInt32BE call in sendAcknowledgementIfNeeded throws a RangeError
because JavaScript bitwise operations produce signed 32-bit integers.
This crashes the RTMP session and drops the video stream.
For a high-bitrate camera like the Reolink D340P (~4 Mbps main stream),
this overflow occurs after approximately 90 minutes of continuous
streaming, causing periodic stream drops at a consistent interval.
Fix by using the unsigned right shift operator (>>> 0) to keep
totalBytesReceived and bytesToAck in the unsigned uint32 range [0,
4294967295], matching the RTMP spec's sequence number wrapping behavior.
Co-authored-by: Josh Casada <joshcasada@Joshs-Mac-mini.ts.net lan>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* replace tool to use `ffmpeg` and bump v0.0.8
* format code
* wip
* wip: update components
* wip: remove websocket for cameras since they are not supported
* wip: allow changing between different login methods
It will prefer logging in with `Tuya (Smart Life) App` if there was no previous `userId`. Else, it will fall back to `Tuya Developer Account`.
* wip: fetch rtsp from Tuya Sharing SDK
* wip
* feat: add support for light accessory in camera
* fix: resolve indicator not updating
* wip: prevent setting motion if device has no motion detection
* improve mqtt reconnect, also update status
* bump version
* update commit
* bump to beta 3
* quick fix
* changelog
* fixchangelog
* bump version
* fix: resolve mqtt connection issues
* chore: bump version
* fix: use correct property for checking connection state
* chore: update changelog
* chore: bump version
* fix: ensure timeout is actually correct and bound corretly
* chore: update changelog
* bump version
* fix: fix setTimeout undefined function
* chore: update changelog
* fix: fix issue with camera not found
---------
Co-authored-by: ErrorErrorError <16653389+ErrorErrorError@users.noreply.github.com>
Co-authored-by: Erik Bautista Santibanez <erikbautista15@gmail.com>