]> git.ipfire.org Git - thirdparty/shairport-sync.git/commitdiff
some MQTT metadata improvements 1384/head
authorCody Cutrer <cody@cutrer.us>
Fri, 24 Dec 2021 02:07:09 +0000 (19:07 -0700)
committerCody Cutrer <cody@cutrer.us>
Fri, 24 Dec 2021 02:09:16 +0000 (19:09 -0700)
document some more of the fields that can come through, and add
a few more "parsed" messages:
 * active_remote_id
 * dacp_id
 * server_ip

MQTT.md
mqtt.c

diff --git a/MQTT.md b/MQTT.md
index 3dee3f22a625d87f0bc4179178382989415d3820..ec41a0b1daa600694f2f3ee81b732dde221ebcef 100644 (file)
--- a/MQTT.md
+++ b/MQTT.md
@@ -95,31 +95,35 @@ The first 4-character code, called the `type`, is either:
 * For `ssnc` metadata, the second 4-character code is used to distinguish the messages. Cover art, coming from the source, is not tagged in the same way as other metadata, it seems, so is sent as an `ssnc` type metadata message with the code `PICT`. Progress information, similarly, is not tagged like other source-originated metadata, so it is sent as an `ssnc` type with the code `prgr`.
 
 Here are some of the `core` codes commonly passed from the source:
- * `asar` -- "artist"
- * `asal` -- "album"
- * `minm` -- "title"
- * `asgn` -- "genre"
- * `asfm` -- "format"
- * `asal` -- "songalbum'
- * `pvol` -- "volume"
- * `clip` -- "client_ip"
+ * `asal` -- album
+ * `asar` -- artist
+ * `ascp` -- composer
+ * `asgn` -- genre
+ * `astm` -- song time
+ * `caps` -- play status (stopped, paused, playing)
+ * `minm` -- title
+ * `mper` -- track persistent id
 
 Here are the 'ssnc' codes defined so far:
  * `PICT` -- the payload is a picture, either a JPEG or a PNG. Check the first few bytes to see which.
- * `clip` -- the payload is the IP number of the client, i.e. the sender of audio. Can be an IPv4 or an IPv6 number.
+ * `acre` -- Active Remote
+ * `clip` -- the payload is the IP address of the client, i.e. the sender of audio. Can be an IPv4 or an IPv6 address.
+ * `daid` -- DACP ID
+ * `dapo` -- DACP Port
+ * `mden` -- a sequence of metadata has ended. The RTP timestamp associated with the metadata sequence is included as data, if available.
+ * `mdst` -- a sequence of metadata is about to start. The RTP timestamp associated with the metadata sequence is included as data, if available.
  * `pbeg` -- play stream begin. No arguments
+ * `pcen` -- a picture has been sent. The RTP timestamp associated with it is included as data, if available.
+ * `pcst` -- a picture is about to be sent. The RTP timestamp associated with it is included as data, if available.
  * `pend` -- play stream end. No arguments
  * `pfls` -- play stream flush. No arguments
  * `prsm` -- play stream resume. No arguments
- * `pvol` -- play volume. The volume is sent as a string -- "airplay_volume,volume,lowest_volume,highest_volume", where "volume", "lowest_volume" and "highest_volume" are given in dB. The "airplay_volume" is what's sent by the source (e.g. iTunes) to the player, and is from 0.00 down to -30.00, with -144.00 meaning "mute". This is linear on the volume control slider of iTunes or iOS AirPlay. If the volume setting is being ignored by Shairport Sync itself, the volume, lowest_volume and highest_volume values are zero.
  * `prgr` -- progress -- this is metadata from AirPlay consisting of RTP timestamps for the start of the current play sequence, the current play point and the end of the play sequence.
- * `mdst` -- a sequence of metadata is about to start. The RTP timestamp associated with the metadata sequence is included as data, if available.
- * `mden` -- a sequence of metadata has ended. The RTP timestamp associated with the metadata sequence is included as data, if available.
- * `pcst` -- a picture is about to be sent. The RTP timestamp associated with it is included as data, if available.
- * `pcen` -- a picture has been sent. The RTP timestamp associated with it is included as data, if available.
+ * `pvol` -- play volume. The volume is sent as a string -- "airplay_volume,volume,lowest_volume,highest_volume", where "volume", "lowest_volume" and "highest_volume" are given in dB. The "airplay_volume" is what's sent by the source (e.g. iTunes) to the player, and is from 0.00 down to -30.00, with -144.00 meaning "mute". This is linear on the volume control slider of iTunes or iOS AirPlay. If the volume setting is being ignored by Shairport Sync itself, the volume, lowest_volume and highest_volume values are zero.
  * `snam` -- a device e.g. "Joe's iPhone" has started a play session. Specifically, it's the "X-Apple-Client-Name" string.
  * `snua` -- a "user agent" e.g. "iTunes/12..." has started a play session. Specifically, it's the "User-Agent" string.
  * `stal` -- this is an error message meaning that reception of a large piece of metadata, usually a large picture, has stalled; bad things may happen.
+ * `svip` -- the payload is the IP address of the server, i.e. shairport-sync. Can be an IPv4 or an IPv6 address.
 
 
 Parsed Messages
@@ -127,14 +131,17 @@ Parsed Messages
 
 The MQTT service can parse the above raw messages into a subset of human-readable topics that include, 
 
+* `active_remote_id` -- Active Remote ID
 * `artist` -- text of artist name 
 * `album` -- text of album name
-* `title` -- text of song title
-* `genre` -- text of genre
+* `client_ip` -- IP address of the connected client
+* `dacp_id` -- DACP ID
 * `format` -- ??
+* `genre` -- text of genre
+* `server_ip` -- IP address of shairport-sync that the client is connected to
 * `songalbum` -- 
+* `title` -- text of song title
 * `volume` -- The volume is sent as a string -- "airplay_volume,volume,lowest_volume,highest_volume", where "volume", "lowest_volume" and "highest_volume" are given in dB. (see above)
-* `client_ip` -- IP address of the connected client
 
 and empty messages at the following topics are published.
 
diff --git a/mqtt.c b/mqtt.c
index ad5a4c407e2024228425cfb5726352ac2e8ae256..912d618c67311697b6398be8a23ba13bcfec072e 100644 (file)
--- a/mqtt.c
+++ b/mqtt.c
@@ -1,3 +1,4 @@
+#include <inttypes.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -11,6 +12,7 @@
 #include "rtp.h"
 
 #include "dacp.h"
+#include "metadata_hub.h"
 #include "mqtt.h"
 #include <mosquitto.h>
 
@@ -129,6 +131,10 @@ void mqtt_process_metadata(uint32_t type, uint32_t code, char *data, uint32_t le
   }
   if (config.mqtt_publish_parsed) {
     if (type == 'core') {
+      int32_t r;
+      uint64_t trackid;
+      char trackidstring[32];
+
       switch (code) {
       case 'asar':
         mqtt_publish("artist", data, length);
@@ -136,32 +142,39 @@ void mqtt_process_metadata(uint32_t type, uint32_t code, char *data, uint32_t le
       case 'asal':
         mqtt_publish("album", data, length);
         break;
-      case 'minm':
-        mqtt_publish("title", data, length);
+      case 'asfm':
+        mqtt_publish("format", data, length);
         break;
       case 'asgn':
         mqtt_publish("genre", data, length);
         break;
-      case 'asfm':
-        mqtt_publish("format", data, length);
+      case 'minm':
+        mqtt_publish("title", data, length);
         break;
+      case 'mper':
+        trackid = *(uint64_t *)(data);
+        r = snprintf(trackidstring, sizeof(trackidstring), "%" PRIX64 "", trackid);
+        mqtt_publish("track_id", trackidstring, r);
       }
     } else if (type == 'ssnc') {
       switch (code) {
+      case 'abeg':
+        mqtt_publish("active_start", data, length);
+        break;
+      case 'acre':
+        mqtt_publish("active_remote_id", data, length);
+        break;
+      case 'aend':
+        mqtt_publish("active_end", data, length);
+        break;
       case 'asal':
         mqtt_publish("songalbum", data, length);
         break;
-      case 'pvol':
-        mqtt_publish("volume", data, length);
-        break;
       case 'clip':
         mqtt_publish("client_ip", data, length);
         break;
-      case 'abeg':
-        mqtt_publish("active_start", data, length);
-        break;
-      case 'aend':
-        mqtt_publish("active_end", data, length);
+      case 'daid':
+        mqtt_publish("dacp_id", data, length);
         break;
       case 'pbeg':
         mqtt_publish("play_start", data, length);
@@ -172,14 +185,21 @@ void mqtt_process_metadata(uint32_t type, uint32_t code, char *data, uint32_t le
       case 'pfls':
         mqtt_publish("play_flush", data, length);
         break;
-      case 'prsm':
-        mqtt_publish("play_resume", data, length);
-        break;
       case 'PICT':
         if (config.mqtt_publish_cover) {
           mqtt_publish("cover", data, length);
         }
         break;
+      case 'prsm':
+        mqtt_publish("play_resume", data, length);
+        break;
+      case 'pvol':
+        mqtt_publish("volume", data, length);
+        break;
+      case 'svip':
+        mqtt_publish("server_ip", data, length);
+        break;
+
       }
     }
   }