Clean up meta tags and docu

This commit is contained in:
badaix 2021-06-26 20:44:12 +02:00
parent 880ed00604
commit e94b5534b7
3 changed files with 133 additions and 46 deletions

View file

@ -40,8 +40,6 @@ public:
}
/// https://www.musicpd.org/doc/html/protocol.html#tags
/// the song file.
boost::optional<std::string> file;
/// the duration of the song
boost::optional<float> duration;
/// the artist name. Its meaning is not well-defined; see “composer” and “performer” for more specific tags.
@ -56,21 +54,13 @@ public:
boost::optional<std::vector<std::string>> album_artist;
/// same as albumartist, but for sorting.
boost::optional<std::vector<std::string>> album_artist_sort;
/// the song title.
// boost::optional<std::string> title;
/// the decimal track number within the album.
// boost::optional<uint16_t> track;
/// a name for this song. This is not the song title. The exact meaning of this tag is not well-defined. It is often used by badly configured internet radio
/// stations with broken tags to squeeze both the artist name and the song title in one tag.
boost::optional<std::string> name;
/// the music genre.
// boost::optional<std::string> genre;
/// the songs release date. This is usually a 4-digit year.
boost::optional<std::string> date;
/// the songs original release date.
boost::optional<std::string> original_date;
/// the artist who composed the song.
// boost::optional<std::string> composer;
/// the artist who performed the song.
boost::optional<std::string> performer;
/// the conductor who conducted the song.
@ -79,10 +69,6 @@ public:
boost::optional<std::string> work;
/// “used if the sound belongs to a larger category of sounds/music” (from the IDv2.4.0 TIT1 description).
boost::optional<std::string> grouping;
/// a human-readable comment about this song. The exact meaning of this tag is not well-defined.
// boost::optional<std::string> comment;
/// the decimal disc number in a multi-disc album.
// boost::optional<uint16_t> disc;
/// the name of the label or publisher.
boost::optional<std::string> label;
/// the artist id in the MusicBrainz database.
@ -146,7 +132,6 @@ public:
{
json j(json::object());
addTag(j, "trackId", track_id);
addTag(j, "file", file);
addTag(j, "duration", duration);
addTag(j, "artist", artist);
addTag(j, "artistSort", artist_sort);
@ -154,18 +139,13 @@ public:
addTag(j, "albumSort", album_sort);
addTag(j, "albumArtist", album_artist);
addTag(j, "albumArtistSort", album_artist_sort);
addTag(j, "title", title);
addTag(j, "name", name);
addTag(j, "genre", genre);
addTag(j, "date", date);
addTag(j, "originalDate", original_date);
addTag(j, "composer", composer);
addTag(j, "performer", performer);
addTag(j, "conductor", conductor);
addTag(j, "work", work);
addTag(j, "grouping", grouping);
addTag(j, "comment", comment);
addTag(j, "discNumber", disc_number);
addTag(j, "label", label);
addTag(j, "musicbrainzArtistId", musicbrainz_artist_id);
addTag(j, "musicbrainzAlbumId", musicbrainz_album_id);
@ -198,7 +178,6 @@ public:
void fromJson(const json& j)
{
static std::set<std::string> supported_tags = {"trackId",
"file",
"duration",
"artist",
"artistSort",
@ -206,18 +185,13 @@ public:
"albumSort",
"albumArtist",
"albumArtistSort",
"title",
"name",
"genre",
"date",
"originalDate",
"composer",
"performer",
"conductor",
"work",
"grouping",
"comment",
"discNumber",
"label",
"musicbrainzArtistId",
"musicbrainzAlbumId",
@ -251,7 +225,6 @@ public:
}
readTag(j, "trackId", track_id);
readTag(j, "file", file);
readTag(j, "duration", duration);
readTag(j, "artist", artist);
readTag(j, "artistSort", artist_sort);
@ -259,18 +232,13 @@ public:
readTag(j, "albumSort", album_sort);
readTag(j, "albumArtist", album_artist);
readTag(j, "albumArtistSort", album_artist_sort);
readTag(j, "title", title);
readTag(j, "name", name);
readTag(j, "genre", genre);
readTag(j, "date", date);
readTag(j, "originalDate", original_date);
readTag(j, "composer", composer);
readTag(j, "performer", performer);
readTag(j, "conductor", conductor);
readTag(j, "work", work);
readTag(j, "grouping", grouping);
readTag(j, "comment", comment);
readTag(j, "discNumber", disc_number);
readTag(j, "label", label);
readTag(j, "musicbrainzArtistId", musicbrainz_artist_id);
readTag(j, "musicbrainzAlbumId", musicbrainz_album_id);

View file

@ -131,6 +131,7 @@ status_mapping = {
# Player.Metadata
# MPD to Snapcast tag mapping: <mpd tag>: [<snapcast tag>, <type>, <is list?>]
tag_mapping = {
'file': ['url', str, False],
'id': ['trackId', str, False],
'album': ['album', str, False],
'albumsort': ['albumSort', str, False],
@ -151,8 +152,6 @@ tag_mapping = {
'lyricist': ['lyricist', str, True],
'title': ['title', str, False],
'track': ['trackNumber', int, False],
'file': ['file', str, False],
'url': ['url', str, False],
'arturl': ['artUrl', str, False],
'usecount': ['useCount', int, False],
'userrating': ['userRating', float, False],
@ -567,10 +566,10 @@ class MPDWrapper(object):
# where
# - "name" containts the name of the radio station
# - "title" has the format "<artist> - <title>"
# {'file': 'http://wdr-wdr2-aachenundregion.icecast.wdr.de/wdr/wdr2/aachenundregion/mp3/128/stream.mp3', 'title': 'Johannes Oerding - An guten Tagen', 'name': 'WDR 2 Aachen und die Region aktuell, Westdeutscher Rundfunk Koeln', 'trackId': '1'}
# {'url': 'http://wdr-wdr2-aachenundregion.icecast.wdr.de/wdr/wdr2/aachenundregion/mp3/128/stream.mp3', 'title': 'Johannes Oerding - An guten Tagen', 'name': 'WDR 2 Aachen und die Region aktuell, Westdeutscher Rundfunk Koeln', 'trackId': '1'}
if 'title' in snapmeta and 'name' in snapmeta and 'file' in snapmeta and not 'album' in snapmeta and not 'artist' in snapmeta:
if snapmeta['file'].find('http') == 0:
if 'title' in snapmeta and 'name' in snapmeta and 'url' in snapmeta and not 'album' in snapmeta and not 'artist' in snapmeta:
if snapmeta['url'].find('http') == 0:
fields = snapmeta['title'].split(' - ', 1)
if len(fields) == 2:
snapmeta['artist'] = [fields[0]]

View file

@ -1,8 +1,8 @@
# Stream plugin
A stream plugin is (this might change in future) a binary or script that is started by the server for a specific stream and offers playback control capabilities and provides information about the stream's state, as well as metadata for the currently playing track.
The server communicates via stdin/stdout with the plugin and sends newline delimited JSON-RPC commands and receives responses and notifications from the plugin, as described below. In upcoming releases shared library plugins might be supported as well.
A stream plugin is (this might change in future) an executable binary or script that is started by the server for a specific stream and offers playback control capabilities and provides information about the stream's state, as well as metadata for the currently playing track.
The Snapcast server communicates via stdin/stdout with the plugin and sends newline delimited JSON-RPC commands and receives responses and notifications from the plugin, as described below. In upcoming releases shared library plugins might be supported as well.
## Requests:
@ -10,12 +10,40 @@ A Stream plugin must support and handle the following requests, sent by the Snap
### Plugin.Stream.Player.Control:
Used to control the player
```json
{"id": 1, "jsonrpc": "2.0", "method": "Plugin.Stream.Player.Control", "params": {"command": "<command>", "params": { "<param 1>": <value 1>, "<param 2>": <value 2>}}}
```
Supported `command`s:
- `Play`: Start playback
- `params`: none
- `Pause`: Stop playback
- `params`: none
- `PlayPause`: Toggle play/pause
- `params`: none
- `Stop`: Stop playback
- `params`: none
- `Next`: Skip to next track
- `params`: none
- `Previous`: Skip to previous track
- `params`: none
- `Seek`: Seek forward or backward in the current track
- `params`:
- `Offset`: [float] seek offset in seconds
- `SetPosition`: Set the current track position in seconds
- `params`:
- `Position`: [float] the new track position
- `TrackId`: [string] the optional currently playing track's identifier
#### Example:
```json
{"id": 1, "jsonrpc": "2.0", "method": "Plugin.Stream.Player.Control", "params": {"command": "SetPosition", "params": { "Position": 170966827, "TrackId": "/org/mpris/MediaPlayer2/Track/2"}}}
```
Supported `command`s:
- TODO
#### Expected response:
@ -34,11 +62,18 @@ todo
### Plugin.Stream.Player.SetProperty:
```json
{"id": 1, "jsonrpc": "2.0", "method": "Plugin.Stream.Player.SetProperty", "params": {"<name>", <value>}}
{"id": 1, "jsonrpc": "2.0", "method": "Plugin.Stream.Player.SetProperty", "params": {"<property>", <value>}}
```
Supported `propertiey`s:
- TODO
#### Supported `property`s:
- `loopStatus`: [string] the current repeat status, one of:
- `none`: the playback will stop when there are no more tracks to play
- `track`: the current track will start again from the begining once it has finished playing
- `playlist`: the playback loops through a list of tracks
- `shuffle`: [bool] play playlist in random order
- `volume`: [int] voume in percent, valid range [0..100]
- `rate`: [float] The current playback rate, valid range (0..)
#### Expected response:
@ -68,6 +103,27 @@ Success:
{"id": 1, "jsonrpc": "2.0", "result": {"canControl":true,"canGoNext":true,"canGoPrevious":true,"canPause":true,"canPlay":true,"canSeek":false,"loopStatus":"none","playbackStatus":"playing","position":593.394,"shuffle":false,"volume":86}}
```
#### Supported `property`s
- `playbackStatus`: [string] The current playback status, one of:
- `playing`
- `paused`
- `stopped`
- `loopStatus`: [string] The current repeat status, one of:
- `none`: The playback will stop when there are no more tracks to play
- `track`: The current track will start again from the begining once it has finished playing
- `playlist`: The playback loops through a list of tracks
- `rate`: [float] The current playback rate, valid range (0..)
- `shuffle`: [bool] Traverse through the playlist in random order
- `volume`: [int] Voume in percent, valid range [0..100]
- `position`
- `canGoNext`: [bool] Whether the client can call the Next method on this interface and expect the current track to change
- `canGoPrevious`: [bool] Whether the client can call the Previous method on this interface and expect the current track to change
- `canPlay`: [bool] Whether playback can be started using Play or PlayPause
- `canPause`: [bool] Whether playback can be paused using Pause or PlayPause
- `canSeek`: [bool] Whether the client can control the playback position using Seek and SetPosition
- `canControl`: [bool] Whether the media player may be controlled over this interface
Error:
```json
@ -96,21 +152,83 @@ Success:
{"jsonrpc": "2.0", "method": "Plugin.Stream.Player.Metadata", "params": {"artist":["Travis Scott & HVME"],"file":"http://wdr-1live-live.icecast.wdr.de/wdr/1live/live/mp3/128/stream.mp3","name":"1Live, Westdeutscher Rundfunk Koeln","title":"Goosebumps (Remix)","trackId":"3"}}
```
#### Supported `tag`s
- `trackId`: [string] A unique identity for this track within the context of an MPRIS object (eg: tracklist).
- `file`: [string] The current song.
- `duration`: [float] The duration of the song in seconds; may contain a fractional part.
- `artist`: [list of strings] The track artist(s).
- `artistSort`: [list of strings] Same as artist, but for sorting. This usually omits prefixes such as “The”.
- `album`: [string] The album name.
- `albumSort`: [string] Same as album, but for sorting.
- `albumArtist`: [list of strings] The album artist(s).
- `albumArtistSort`: [list of strings] Same as albumartist, but for sorting.
- `name`: [string] A name for this song. This is not the song title. The exact meaning of this tag is not well-defined. It is often used by badly configured internet radio stations with broken tags to squeeze both the artist name and the song title in one tag.
- `date`: [string] The songs release date. This is usually a 4-digit year.
- `originalDate`: [string] The songs original release date.
- `composer`: [list of strings] The composer(s) of the track.
- `performer`: [string] The artist who performed the song.
- `conductor`: [string] The conductor who conducted the song.
- `work`: [string] “a work is a distinct intellectual or artistic creation, which can be expressed in the form of one or more audio recordings”
- `grouping`: [string] “used if the sound belongs to a larger category of sounds/music” (from the IDv2.4.0 TIT1 description).
- `comment`: [list of string] A (list of) freeform comment(s)
- `label`: [string] The name of the label or publisher.
- `musicbrainzArtistId`: [string] The artist id in the [MusicBrainz](https://picard-docs.musicbrainz.org/en/appendices/tag_mapping.html) database.
- `musicbrainzAlbumId`: [string] The album id in the [MusicBrainz](https://picard-docs.musicbrainz.org/en/appendices/tag_mapping.html) database.
- `musicbrainzAlbumArtistId`: [string] The album artist id in the [MusicBrainz](https://picard-docs.musicbrainz.org/en/appendices/tag_mapping.html) database.
- `musicbrainzTrackId`: [string] The track id in the [MusicBrainz](https://picard-docs.musicbrainz.org/en/appendices/tag_mapping.html) database.
- `musicbrainzReleaseTrackId`: [string] The release track id in the [MusicBrainz](https://picard-docs.musicbrainz.org/en/appendices/tag_mapping.html) database.
- `musicbrainzWorkId`: [string] The work id in the [MusicBrainz](https://picard-docs.musicbrainz.org/en/appendices/tag_mapping.html) database.
- `lyrics`: [list of strings] The lyricist(s) of the track
- `bpm`: [integer] The speed of the music, in beats per minute.
- `autoRating`: [float] An automatically-generated rating, based on things such as how often it has been played. This should be in the range 0.0 to 1.0.
- `comment`: [list of strings] A (list of) freeform comment(s).
- `composer`: [list of strings] The composer(s) of the track.
- `contentCreated`: [string] Date/Time: When the track was created. Usually only the year component will be useful.
- `discNumber`: [integer] The disc number on the album that this track is from.
- `firstUsed`: [string] Date/Time: When the track was first played.
- `genre`: [list of strings] List of Strings: The genre(s) of the track.
- `lastUsed`: [string] Date/Time: When the track was last played.
- `lyricist`: [list of strings] List of Strings: The lyricist(s) of the track.
- `title`: [string] The track title.
- `trackNumber`: [string] The track number on the album disc.
- `url`: [string uri] The location of the media file.
- `artUrl`: [string uri] The location of an image representing the track or album. Clients should not assume this will continue to exist when the media player stops giving out the URL.
- `useCount`: [integer] The number of times the track has been played.
- `userRating`: [float] A user-specified rating. This should be in the range 0.0 to 1.0.
- `spotifyArtistId`: [string] The [Spotify Artist ID](https://developer.spotify.com/documentation/web-api/#spotify-uris-and-ids)
- `spotifyTrackId`: [string] The [Spotify Track ID](https://developer.spotify.com/documentation/web-api/#spotify-uris-and-ids)
### Plugin.Stream.Player.Properties
```json
{"jsonrpc": "2.0", "method": "Plugin.Stream.Player.Properties", "params": {"canControl":true,"canGoNext":true,"canGoPrevious":true,"canPause":true,"canPlay":true,"canSeek":false,"loopStatus":"none","playbackStatus":"playing","position":593.394,"shuffle":false,"volume":86}}
```
[Supported `property`s](#supported-propertys)
### Plugin.Stream.Log
Send a log message
```json
{"jsonrpc": "2.0", "method": "Plugin.Stream.Log", "params": {"severity":"Info","message":"Logmessage"}}
{"jsonrpc": "2.0", "method": "Plugin.Stream.Log", "params": {"severity":"Info","message":"<Log message>"}}
```
#### Supported `severity`s
- `trace` verbose debug-level message
- `debug` debug-level message
- `info` informational message
- `notice` normal, but significant, condition
- `warning` warning conditions
- `error` error conditions
- `fatal` critical conditions
### Plugin.Stream.Ready
The plugin shall send this notification when it's ready to receive commands
The plugin shall send this notification when it's up and ready to receive commands
```json
{"jsonrpc": "2.0", "method": "Plugin.Stream.Ready"}
@ -119,6 +237,8 @@ The plugin shall send this notification when it's ready to receive commands
# Server:
TODO: this belongs to doc/json_rpc_api/v2_0_0.md
## Requests:
To control the stream state, the following commands can be sent to the Snapcast server and will be forwarded to the respective stream: