Commit Graph

17 Commits

Author SHA1 Message Date
Test User c6e9f71cf4 Add a YouTube provider backed by yt-dlp
The new ytdy crate mounts /youtube: login-free search terms exactly
like tidal's (creatable, renamable, deletable, results as queueable
downloadable tracks) and, when a cookies file is configured, the
user's playlists. All extraction runs through one bounded subprocess
seam (argv-only, per-call timeout, stdout cap, typed errors) so tests
drive the provider with a fake script. yt-dlp is declared in devenv;
a failed binary probe disables the provider, never the server.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-21 14:01:58 +02:00
Test User 7f0e900c56 Capture library subtrees with downloaded audio
W on a downloadable library node mirrors the subtree into /captures
(a fourth fsdy instance) like a bookmark, but downloads every track's
audio next to its toml; the toml points at the sibling by relative
name, so captures play with no provider round trip. Nodes opt in via
the new is_downloadable flags — Tidal blesses queueable and
track-listing nodes. The bookmark walk is now the shared capture walk
parameterized by a per-track sink.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-21 13:45:04 +02:00
Test User 4e44f672e8 Persist queues as fs-provider folders
Queues now survive restarts, built entirely on the fs provider:
fsdy::Client is instance-mountable and a second, read-only instance
serves <config>/crabidy/queues/ as /queues. Every queue is a folder of
order-prefixed link track files plus a hidden state sidecar, written
only by the new QueueStore (tmp-and-swap). The playback loop streams
every queue change through a latest-wins watch channel to a debouncing
persister task and restores queues/current/ (tracks, position,
modifiers) at startup without autoplay. w on the queue pane asks for a
name and drives the previously stubbed SaveQueue rpc; reloading a
saved queue is just queueing /queues/<name>, since link entries
rewrite to their targets at listing time. The old "no links into /fs"
parse rejection gave way to one-hop link semantics so queues can
reference fs tracks.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-21 10:41:49 +02:00
Test User 4dd5f01217 Add a filesystem provider for serialized track nodes
A new fsdy crate exposes a configured root directory as /fs:
*.track.toml files are track nodes carrying metadata plus exactly one
playable reference — a local audio file, an http(s) URL, or a
crabidy-internal link. Link tracks rewrite Track.path to the target at
listing time, so playback routes through the existing prefix routing;
links into /fs are rejected, making chains impossible. Paths are
percent-encoded segments validated in one place (no root escape), the
orchestrator wires the provider optionally (a broken local config only
costs the /fs subtree), and the default chunked resolve walk provides
progressive queueing for free.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-21 01:58:55 +02:00
AI User 21e1b10c0b Drop redundant log-to-tracing bridge init
tracing-subscriber .init() already installs the LogTracer via its
default tracing-log feature; the explicit init only produced a startup
warning. Remove it and the direct tracing-log dependency.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-19 22:01:22 +02:00
AI User d504ebc85f Fix intermittent playback stops and harden the queue
Root causes found and fixed:

- QueueManager could panic and kill the playback task permanently:
  is_last_track() underflowed on an empty queue, remove_tracks accepted
  pos == len (Vec::remove panic) and corrupted positions when removing
  multiple tracks (indices shifted mid-loop), shuffle_behind indexed
  out of range on an empty play order, insert_tracks shifted play-order
  entries by the queue length instead of the inserted count and then
  assert!()ed on the resulting inconsistency, and clear() left
  play_order stale. All mutation methods are now guarded, multi-remove
  works highest-position-first, and an inconsistent play order is
  rebuilt instead of panicking. Regression tests cover these cases.

- The tidal access token was only obtained at startup and never
  refreshed, so long-running sessions ended with every track fetch
  failing (playback just stopped at the next track boundary). Login
  state now lives behind a lock; tokens are refreshed proactively
  before expiry (5 min margin) and once reactively on a 401, and all
  API responses are status-checked (new ClientError::ApiError) instead
  of being fed to the JSON decoder blind. The http client also got a
  30s timeout so a hung connection cannot wedge the provider loop.

- (from the rodio rewrite, same bug class) end of stream used to be
  detected by string-comparing an io::Error message; any other decode
  or network error ended the stream silently without an EndOfStream
  message, so playback never advanced. EOS is now a guaranteed
  callback with a generation counter.

Plus workspace-wide clippy cleanup (zero warnings), cargo-machete
cleanup, and fmt.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-19 22:00:22 +02:00
AI User 6eb5a87b15 Update all dependencies to current versions
- tonic 0.9 -> 0.14 (tonic-prost/tonic-prost-build split), prost 0.14
- ratatui 0.20 -> 0.30 (Frame no longer generic, Line instead of Spans),
  crossterm 0.29
- rodio 0.17 -> 0.22: replace the custom symphonia decoder with rodio's
  built-in decoder, seeking (try_seek) and position tracking (get_pos);
  end-of-stream is now signalled via an EmptyCallback source with a
  generation counter so a replaced track can never emit a stale EOS
- replace the vendored stream-download crate with the published
  stream-download 0.24 (rustls), with a 30s open timeout
- reqwest 0.12->0.13 (rustls/webpki-roots/query features), base64 0.22
  Engine API, rand 0.10, flume 0.12, thiserror 2, dirs 6, toml 1
- unify everything under [workspace.dependencies]; drop unused deps
  (once_cell, serde_json in server; confique, secrecy in tidaldy)
- devenv: add protobuf (protoc) for prost-build

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-19 21:41:10 +02:00
chmanie 17a0e8606e Try to add release files
stable / fmt Details
stable / cross-${{ matrix.target }} (armv7-unknown-linux-gnueabihf) Details
stable / cross-${{ matrix.target }} (aarch64-unknown-linux-gnu) Details
2023-06-12 18:06:00 +02:00
chmanie 2e167e6714 Add simple gitea runner demo
ubuntu / stable / fmt Details
2023-06-11 20:20:37 +02:00
Hans Mündelein 9be9039a05
Add shuffle and repeat for server 2023-06-09 16:02:35 +02:00
Hans Mündelein a31608aae9
Integrate new audio player 2023-06-08 16:10:17 +02:00
Hans Mündelein 4043865ad4
Fix broken song deadlock and improve observability 2023-06-03 13:04:59 +02:00
chmanie 553f34a111 Use proper config directory 2023-06-02 20:28:38 +02:00
Hans Mündelein 46937b3d6e
Allow multiple concurrent clients receive streams 2023-05-28 09:21:17 +02:00
Hans Mündelein 9e1efb886a
Add first streaming server version 2023-05-26 19:11:55 +02:00
Hans Mündelein 0b9e6ceebe
Add server stubs for newly stuctred RPCs 2023-05-23 13:11:22 +02:00
Hans Mündelein 0af8829987
Add cargo-server with liby service draft
It is not smart, fetches everything all the time  and totally hardcoded with the tidal client
But tidal login and library discovery with tidal should somewhat work.
2023-05-22 22:05:38 +02:00