Commit Graph
14 Commits
Author SHA1 Message Date
petere f1f2bfe1a3 feat: portal-based monitor enumeration fallback
Add a xdg-desktop-portal ScreenCast fallback to monitor enumeration so
the GUI picker works on compositors without hyprctl (GNOME/KDE etc.).
ListMonitors now tries hyprctl first, then creates a portal session,
selects monitor sources, starts capture and parses the stream list.

Verified on Hyprland: the portal path returns the 1920x1200 monitor,
confirming the compositor-agnostic mechanism works.
2026-09-19 20:40:56 +01:00
petere aab2006e78 feat: screen capture scaling / downsampling
Add a Scale option (1.0 native, 0.5 half, etc.) that downsamples the
captured BGRA frame with bilinear interpolation before JPEG encoding.
Config carries the scale factor; the GUI exposes a Scale dropdown
(100%/75%/50%/25%) that applies live via SetConfig.

Verified: OBS displays the image at the reduced resolution matching the
selected scale, without restarting the stream.
2026-09-19 20:33:40 +01:00
petere 583274d9e6 feat: add bitrate measurement and quality presets
- sender tracks payload bytes; engine measures stream bitrate over a
  sliding window and exposes it in Status
- GUI status label and tray tooltip show the live bitrate (e.g. 36 Mbps)
- add a Preset dropdown (Low/Medium/High/Ultra) that sets quality+fps
  together and applies live via SetConfig

Verified: 36 Mbps shown for Medium (quality 70 @ 30fps) matches the
wire measurement.
2026-09-19 17:53:49 +01:00
petere 95f47abadb feat: live settings changes mid-stream
Add flinger.SetConfig to update FPS/quality/name/audio/announce without
restarting the stream. Fields that require a restart (source, port,
stream-index) are preserved. The video loop reads the live config each
frame so changes apply immediately, and the GUI Quality/Frame-rate
dropdowns push changes to a running engine.

Verified live: fps 12->33 and JPEG size 210KB->1.3MB on quality change.
2026-09-19 17:37:47 +01:00
petere 5663fb6b36 feat: add monitor picker to the GUI settings
Enumerate monitors via hyprctl (Hyprland) and present them as a
dropdown in the settings window instead of a raw index. The picker is
enabled only for the screen source and persists the selected monitor as
stream_index. Falls back to a single indexed option when enumeration is
unavailable (non-Hyprland).
2026-09-19 10:13:23 +01:00
petere 50955fd606 feat: surface runtime errors in engine status
Record the most recent runtime error (capture, encode, packet, audio)
in the engine and expose it via Status.Err. The GUI shows it in the
status label (highlighted as a danger) and in the tray tooltip, so a
denied screen-share or encoder failure is visible without reading logs.
2026-09-19 10:13:17 +01:00
petere c1ad3416a1 docs: clarify audio format in flinger audio loop
The PipeWire stream negotiates S16LE stereo at 48 kHz; document that the
WAVE packets carry this directly.
2026-09-19 10:03:32 +01:00
petere 34efbaf26d feat: support custom --config path in CLI and GUI
Add config.LoadFrom/SaveTo for arbitrary paths and thread a --config
flag through both entry points:
- CLI: --config loads a file first; explicit flags override file values
- GUI: --config selects the settings file used for load and save
- tests for LoadFrom/SaveTo and default fallback
2026-09-19 08:35:07 +01:00
petere bb4073f8a3 feat: add tray streaming status and app icon
- tray icon and tooltip now reflect engine state: grey when stopped,
  green + live frame/drop counters in the tooltip while streaming
- generate a proper app icon (assets/, via cmd/teleportfling-icon) and
  embed it so the window and tray carry the icon without runtime files
- add a .desktop entry template for launching from an app menu
- run Fyne UI updates (status label, tray icon/tooltip) on the main
  thread via fyne.Do to satisfy the threading model
2026-09-18 21:20:52 +01:00
petere 2b3fd54934 feat: harden engine config, discovery and backpressure stats
- config: validate port/quality/fps/source/stream-index ranges on load
  and before engine start (flinger.Config.Validate)
- discovery: add Announce option to disable multicast (GUI checkbox,
  CLI --no-announce); absent JSON key keeps the default true
- backpressure: count dropped frames in the TCP sender, expose via
  engine Status and a live counter in the GUI status label
- docs: record M3/M4 decisions and X11 coverage via the portal backend
2026-09-18 20:44:39 +01:00
petere cb27a0d63d feat: add Fyne desktop GUI with system tray (M3)
- internal/gui: settings form (name, port, source, quality, fps, audio)
  wired to the flinger engine, config save/load, start/stop toggle
- system tray via Fyne's StatusNotifierItem: Show (raises window),
  Start/Stop, Quit; left-click shows the settings window
- cmd/teleportfling-gui entry point

Verified on Hyprland: tray icon registers, start/stop streaming works,
window shows and focuses from the tray.
2026-09-18 20:32:49 +01:00
petere ba423eb944 refactor: extract streaming engine into internal/flinger
Move the capture/encode/send pipeline out of cmd/teleportfling into a
GUI-free Engine so the CLI and the desktop app share one implementation:
- flinger: Config/Engine/Status, audio+video+stats loops, pattern source
- config: JSON persistence at ~/.config/teleportfling/config.json
- cmd/teleportfling: thin CLI wrapper around the engine (same flags)
- golangci: extend exclusions to flinger/config
2026-09-18 20:32:45 +01:00
petere 0cb96b5792 feat: add PipeWire screen and system audio capture (M2)
Capture the Wayland desktop via xdg-desktop-portal + PipeWire using
go2tv.app/screencast (MIT), and stream it to OBS:
- internal/capture: Capture/FrameSource/AudioSource interfaces and the
  PipeWire backend (BGRA frames at monitor resolution, S16 48 kHz stereo
  system audio)
- protocol: EncodeBGRA fast path producing 4:2:0 YCbCr JPEGs
- cmd: --source screen|pattern, --audio, --stream-index flags; real
  capture feeds the existing sender
- share one wall-clock reference between the audio and video loops so
  OBS receives aligned A/V timestamps (avoids multi-second latency)

Verified end-to-end: real desktop at 30 fps renders in OBS with
sub-second latency.
2026-09-18 19:19:22 +01:00
petere 10fa72b228 feat: implement M1 teleport protocol sender
Stream a synthetic test pattern and silent PCM audio over the OBS
Teleport protocol:
- protocol: wire format (Header/ImageHeader/WaveHeader), BT.709 full
  range colour matrix, JPEG encode via turbojpeg cgo, WAVE packet builder
- output: TCP sender with per-connection buffered channels and drop-on-overflow
- discovery: multicast announce via peerdiscovery
- cmd: teleportfling CLI with flags, test-pattern frame generator

Verified end-to-end: OBS discovers and renders the stream with correct
colours and motion.
2026-09-18 18:36:25 +01:00