feat: expose r:resMD as Track.ResMD when parsing favorites - #226
Merged
Conversation
Sonos favorites report their own container UpnpClass (often the malformed 'object.itemobject.item.sonos-favorite'), which is not a valid CurrentURIMetaData class for playback and gets rejected by the speaker with UPnP error 402. The actual playable resource's metadata (with the correct upnp:class) is carried separately in the r:resMD attribute, which ParseDIDLTrack silently discarded. ResMD now surfaces that pre-encoded DIDL-Lite metadata (decoded, ready to pass as a raw CurrentURIMetaData string) so favorites can be played back directly via AVTransportService.SetAVTransportURI without callers having to re-parse the raw Browse response themselves.
Coverage Report for CI Build 28782200864Coverage remained the same at 73.387%Details
Uncovered ChangesNo uncovered changes found. Coverage RegressionsNo coverage regressions found. Coverage Stats
💛 - Coveralls |
There was a problem hiding this comment.
Pull request overview
This PR improves favorites playback interoperability by preserving the playable resource’s DIDL-Lite metadata carried in favorites’ r:resMD, exposing it on parsed Track objects so consumers can use it as CurrentURIMetaData instead of the favorite entry’s often-invalid upnp:class.
Changes:
- Parse and decode
r:resMDinMetadataHelper.ParseDIDLTrackand expose it asTrack.ResMD. - Add unit tests covering presence/absence of
r:resMD. - Extend the
GetFavorites()end-to-end test to assert the decodedResMDis surfaced.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
src/helpers/metadata-helper.ts |
Decodes r:resMD during DIDL parsing and attaches it to the returned Track. |
src/models/track.ts |
Adds optional ResMD field to the Track model with JSDoc explaining intended usage. |
src/tests/helpers/metadata-helper.test.ts |
Adds unit tests verifying r:resMD decoding and undefined behavior when absent. |
src/tests/sonos-device.test.ts |
Extends GetFavorites() test to assert decoded ResMD is present in parsed results. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+13
to
+17
| /** | ||
| * Pre-encoded DIDL-Lite metadata (`r:resMD`) for the underlying playable resource, only | ||
| * present on some favorites. Use this as CurrentURIMetaData instead of the favorite's own | ||
| * UpnpClass, which describes the favorite entry itself and isn't valid for playback. | ||
| */ |
| expect(result).toHaveProperty('NumberReturned', 6); | ||
| expect(result).toHaveProperty('TotalMatches', 6); | ||
| expect(result).toHaveProperty('UpdateID', 3); | ||
| expect(result.Result[0]).toHaveProperty('ResMD', '<DIDL-Lite xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:upnp="urn:schemas-upnp-org:metadata-1-0/upnp/" xmlns:r="urn:schemas-rinconnetworks-com:metadata-1-0/" xmlns="urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/"><item id="10032020spotify%3atrack%3a7nDoBWDvf02SyD8kEQuuPO" parentID="100e206cspotify%3aartistTopTracks%3a5q8HGNo0BjLWaTAhRtbwxa" restricted="true"><dc:title>Bottoms Up</dc:title><upnp:class>object.item.audioItem.musicTrack</upnp:class><desc id="cdudn" nameSpace="urn:schemas-rinconnetworks-com:metadata-1-0/">SA_RINCON2311_X_#Svc2311-0-Token</desc></item></DIDL-Lite>'); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Sonos favorites report their own container
UpnpClass(often the well-known malformed valueobject.itemobject.item.sonos-favorite), which is not a validCurrentURIMetaDataclass for playback - passing a favoriteTrackstraight intoSetAVTransportURIgets rejected by the speaker with UPnP error 402.The actual playable resource's metadata (with the correct
upnp:classfor the underlying track/stream) is carried separately in ther:resMDattribute of the favorite's DIDL-Lite item, butMetadataHelper.ParseDIDLTracksilently discarded it, forcing consumers to re-parse the rawContentDirectoryService.Browseresponse themselves to get at it.Fix
ParseDIDLTracknow decodesr:resMD(when present) intoTrack.ResMD- a ready-to-use, already-decoded DIDL-Lite XML string. Consumers can pass it directly as a rawCurrentURIMetaDatastring toAVTransportService.SetAVTransportURIto play a favorite without hitting the 402.Testing
MetadataHelper.ParseDIDLTrackcovering decoding ofr:resMDand the absent case.GetFavorites()end-to-end test with an assertion on the decodedResMDvalue using a real captured Sonos favorites response.Purely additive (new optional field) - not a breaking change.