* feat(capture): toggle mouse pointer via capture.video.show_pointer
- config: register capture.video.show_pointer config option
- config: default pointer to visible (ShowPointer: true) on the
hardcoded fallback pipeline, override applies only when the flag is
explicitly set, so per-pipeline YAML overrides stay untouched
- compose: document NEKO_CAPTURE_VIDEO_SHOW_POINTER example
* fix(capture): apply show_pointer to all pipelines
- capture: thread capture.video.show_pointer into broadcast and
screencast gstreamer pipelines, previously hardcoded show-pointer=true
and silently ignored the flag
- config: resolve capture.video.show_pointer once into
Capture.VideoShowPointer so all pipeline builders share one value
- docs: document capture.video.show_pointer in configuration/capture.md,
including its reach into broadcast and screencast, and regenerate
help.txt/help.json
- compose: drop stray commented-out example, default compose file is
not meant to list every option
* This is a no-op with the default configuration: when only a single video pipeline is configured, there is nothing for the stream selector to switch to. The change only has an effect when the operator configures multiple pipelines and enables the bandwidth estimator.
* fix(session): guard against nil WebRTC peer in profileChanged"
---------
Co-authored-by: alvarorichard <alvarorichard@tuta.io>
we used to have file neko.yaml with default configuration, but if we would add neko.yml the default configuration would still be read. so instead, default configuartion was moved to the sever itself and no file is distributed with it by defautl.
* feat: add openinapp plugin to open chat links in shared neko instance
* lint.
* feat(openinapp): implement open link handler and route for opening links.
* feat(openinapp): switched to http backend and removed example in docker-compose.yaml
* lint.
---------
Co-authored-by: Miroslav Šedivý <sedivy.miro@gmail.com>
* fix(filetransfer): remove auth.AdminsOnly middleware wrapper from routes
* fix(filetransfer): add config option to allow non-admin users to download and upload files.
* fix(filetransfer): implement user permissions for file download and upload in client.
---------
Co-authored-by: Miroslav Šedivý <sedivy.miro@gmail.com>
* Add H265 support
Adds H265 as a selectable video codec with software (x265enc), VAAPI
(vah265enc), and NVENC (nvh265enc) pipeline paths in both the legacy
pipeline builder and the RTPCodec definition.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* Replace legacy vaapih264enc with vah264enc
The gstreamer-vaapi plugin suite (vaapih264enc) is superseded by the va
plugin (vah264enc) in gst-plugins-bad. Switch to it and update the
parameters accordingly: CBR instead of VBR for lower-latency streaming,
key-int-max instead of keyframe-period, and target-usage instead of
quality-level.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* Unify keyframe interval to 60 frames for NVENC H264/H265 encoder paths
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix: reduce audio jitter buffer latency
- Release listenersMu before dispatching samples to listeners
- Buffer Track.sample channel (size 2) with non-blocking WriteSample
- Buffer pipeline.sample channel (size 4) to unblock GStreamer thread
- Add leaky=downstream max-size-buffers=5 to audio queue to prevent burst accumulation
- Set sync=false on appsink to deliver buffers immediately without clock wait
These changes break the backpressure chain that caused the GStreamer
streaming thread to stall. When the Go scheduler has a hiccup, buffered
frames were delivered in a burst, causing the browser audio jitter buffer
to grow to ~10 seconds over time.
Fixes: #598
* fix: log message when dropping samples due to full track channel
* feat(client): add microphone passthrough button to controls toolbar
Add mic toggle button to the bottom controls bar that enables users to
share their local microphone with the remote neko session via WebRTC.
The server already supports microphone capture (capture.microphone.enabled)
but the legacy client had no UI to trigger getUserMedia and send an audio
track to the peer connection.
Changes:
- base.ts: Add enableMicrophone/disableMicrophone methods that call
getUserMedia and addTrack/removeTrack on the RTCPeerConnection.
Mic is cleaned up automatically on disconnect.
- controls.vue: Add mic button (fa-microphone/fa-microphone-slash) between
play/pause and volume controls with tooltip and error handling.
- en-us.ts: Add i18n strings for mic tooltips and error dialog.
* if the error is not io.EOF, log it. Otherwise, it's a normal closure of the track.
* tie microphone to active host and auto-disable on control loss
---------
Co-authored-by: h1n054ur <admin@haniumer.com>
Co-authored-by: Miroslav Šedivý <sedivy.miro@gmail.com>
we always keep running the last clipboard function as that is supposed to contain the clipboard data being pasted. as soon as a new one is spawn, the old one is stutdown.