Find handed-off Tracks in a Source's catalog by ISRC #53

Open
opened 2026-10-13 20:49:32 +02:00 by SBDeveloper · 1 comment
Owner

Part of #49

During a Handoff the receiving Device looks for an equivalent Track by ISRC and by similar title/artist/duration, but only in its Library. A local file on the PC that the phone has no copy of is skipped, even when the phone is logged in to Deezer and Deezer has the same recording.

Wanted: when a handed-off Track does not resolve in the Library, ask the receiving Device's catalog Sources for a Track with the same ISRC (and only then fall back to skipping). Played-as-similar and skipped Tracks keep being listed in the notice.

Needs a way for a Source to look a Track up by ISRC: a new optional export in the plugin API (crates/plugin-api), implemented by the Deezer plugin. Consider the cost: one lookup per unresolved Track, and the Handoff must still get ready within its timeout (resolve the current Track first, or batch).

See ADR 0009 and the resolution in crates/core/src/handoff.rs.

Part of #49 During a Handoff the receiving Device looks for an equivalent Track by ISRC and by similar title/artist/duration, but only in its **Library**. A local file on the PC that the phone has no copy of is skipped, even when the phone is logged in to Deezer and Deezer has the same recording. Wanted: when a handed-off Track does not resolve in the Library, ask the receiving Device's catalog Sources for a Track with the same ISRC (and only then fall back to skipping). Played-as-similar and skipped Tracks keep being listed in the notice. Needs a way for a Source to look a Track up by ISRC: a new optional export in the plugin API (`crates/plugin-api`), implemented by the Deezer plugin. Consider the cost: one lookup per unresolved Track, and the Handoff must still get ready within its timeout (resolve the current Track first, or batch). See ADR 0009 and the resolution in `crates/core/src/handoff.rs`.
Author
Owner

This was generated by AI during triage.

Agent Brief

Category: enhancement
Summary: During Handoff, resolve Tracks the receiving Device lacks by looking them up by ISRC in its usable Sources' catalogs, before falling back to similarity or skipping.

Current behavior:
The receiving Device resolves each handed-off Queue entry: same Source and Track id (catalog Source logged in, or Track in Library), else a Library Track with the same ISRC, else a Library Track with similar title/artist/duration, else skipped. A local file from the other Device with an ISRC is skipped even when a logged-in catalog Source has the same recording. The plugin API has no lookup-by-ISRC export.

Desired behavior:

  • Resolution order becomes: same Source/Track id, Library ISRC match, catalog ISRC lookup, Library similarity match, skipped.
  • Catalog lookup asks every Source that exports track_by_isrc and is usable here (logged in if it has an account), in Source ranking order; first hit wins.
  • A hit counts as Same: no entry in the "played as similar" notice. It plays as a catalog Track and is not added to the Library.
  • A lookup error, or a Source without the export, counts as a miss; resolution continues. Tracks without an ISRC skip the lookup.
  • Latency: resolve the current Track first. Remaining unresolved Tracks are looked up in parallel under a total budget of 5s inside prepare; Tracks still unresolved when the budget runs out fall through to similarity, then skipped, as today. Results are cached per Track reference within one Handoff (as already done).
  • The Handoff must still become ready within HANDOFF_TIMEOUT (10s).

Key interfaces:

  • plugin-api: new optional export track_by_isrc, input {isrc}, output Track or null. Add it to the export tables in the crate docs next to continuation. A Source without it is simply never asked.
  • Host Source: a way to call it and tell whether a Source exports it.
  • Deezer plugin: implement track_by_isrc using Deezer's lookup by ISRC; return the same Track shape as search/track.
  • Handoff resolution (Resolved::Same carrying a non-Library Track) must keep playing correctly when the Track is not in the Library.
  • Test fixture plugin fake-source should export it so core integration tests can drive it.

Acceptance criteria:

  • A handed-off local-file Track with an ISRC, absent from the receiving Library, resolves to the catalog Track when a logged-in fixture Source returns one for that ISRC; it is not skipped and not in the similar notice.
  • The resolved catalog Track is not added to the receiving Library.
  • With two exporting Sources, the higher-ranked one's hit wins; a logged-out Source is not asked.
  • A Source whose lookup errors or returns null does not abort the Handoff; the Track falls through to similarity, then skipped.
  • A Track without an ISRC triggers no lookup.
  • With a Source that responds slower than the budget, prepare returns within the budget plus resolving overhead and unresolved Tracks are skipped.
  • The current Track is resolved before the others.
  • Deezer plugin exports track_by_isrc and returns a Track for a known ISRC (fixture-based test).
  • ADR 0009 resolution rule and plugin-api docs describe the new step.

Out of scope:

  • Matching by title/artist/duration against a catalog (ISRC only).
  • Streaming audio from the handing Device (#52).
  • Remote control (#51).
  • Changing Track matching/Recordings, or adding Handoff results to the Library.
  • Background resolution after playback starts.
> *This was generated by AI during triage.* ## Agent Brief **Category:** enhancement **Summary:** During Handoff, resolve Tracks the receiving Device lacks by looking them up by ISRC in its usable Sources' catalogs, before falling back to similarity or skipping. **Current behavior:** The receiving Device resolves each handed-off Queue entry: same Source and Track id (catalog Source logged in, or Track in Library), else a Library Track with the same ISRC, else a Library Track with similar title/artist/duration, else skipped. A local file from the other Device with an ISRC is skipped even when a logged-in catalog Source has the same recording. The plugin API has no lookup-by-ISRC export. **Desired behavior:** - Resolution order becomes: same Source/Track id, Library ISRC match, **catalog ISRC lookup**, Library similarity match, skipped. - Catalog lookup asks every Source that exports `track_by_isrc` and is usable here (logged in if it has an account), in Source ranking order; first hit wins. - A hit counts as `Same`: no entry in the "played as similar" notice. It plays as a catalog Track and is **not** added to the Library. - A lookup error, or a Source without the export, counts as a miss; resolution continues. Tracks without an ISRC skip the lookup. - Latency: resolve the current Track first. Remaining unresolved Tracks are looked up in parallel under a total budget of 5s inside `prepare`; Tracks still unresolved when the budget runs out fall through to similarity, then skipped, as today. Results are cached per Track reference within one Handoff (as already done). - The Handoff must still become ready within `HANDOFF_TIMEOUT` (10s). **Key interfaces:** - plugin-api: new optional export `track_by_isrc`, input `{isrc}`, output `Track` or null. Add it to the export tables in the crate docs next to `continuation`. A Source without it is simply never asked. - Host `Source`: a way to call it and tell whether a Source exports it. - Deezer plugin: implement `track_by_isrc` using Deezer's lookup by ISRC; return the same Track shape as `search`/`track`. - Handoff resolution (`Resolved::Same` carrying a non-Library Track) must keep playing correctly when the Track is not in the Library. - Test fixture plugin `fake-source` should export it so core integration tests can drive it. **Acceptance criteria:** - [ ] A handed-off local-file Track with an ISRC, absent from the receiving Library, resolves to the catalog Track when a logged-in fixture Source returns one for that ISRC; it is not skipped and not in the similar notice. - [ ] The resolved catalog Track is not added to the receiving Library. - [ ] With two exporting Sources, the higher-ranked one's hit wins; a logged-out Source is not asked. - [ ] A Source whose lookup errors or returns null does not abort the Handoff; the Track falls through to similarity, then skipped. - [ ] A Track without an ISRC triggers no lookup. - [ ] With a Source that responds slower than the budget, `prepare` returns within the budget plus resolving overhead and unresolved Tracks are skipped. - [ ] The current Track is resolved before the others. - [ ] Deezer plugin exports `track_by_isrc` and returns a Track for a known ISRC (fixture-based test). - [ ] ADR 0009 resolution rule and plugin-api docs describe the new step. **Out of scope:** - Matching by title/artist/duration against a catalog (ISRC only). - Streaming audio from the handing Device (#52). - Remote control (#51). - Changing Track matching/Recordings, or adding Handoff results to the Library. - Background resolution after playback starts.
Sign in to join this conversation.
No milestone
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
SBDeveloper/medley#53
No description provided.