Sample Shairport Sync Metadata Player
This sample program reads the pipe of metadata optionally generated by Shairport Sync 2.4 and later. Shairport Sync is an AirTunes emulator with audio synchronization and multi-room capability -- https://github.com/mikebrady/shairport-sync. To use shairport-sync-metadata-reader, read the pipe via standard input, e.g.
shairport-sync-metadata-reader < /tmp/shairport-sync-metadata
or
shairport-sync-metadata-reader --raw < /tmp/shairport-sync-metadata
You'll get an output like this:
"ssnc" "pfls": "".
"ssnc" "mdst": "".
Album Name: "Pergolesi: Stabat mater".
Artist: "Andreas Scholl, Barbara Bonney, Christophe Rousset & Les Talens Lyriques".
Comment: "".
Composer: "Giovanni Battista Pergolesi".
Genre: "Classical".
File kind: "Purchased AAC audio file".
Title: "Stabat Mater: I. Stabat mater".
Sort as: "Stabat Mater: I. Stabat mater".
"ssnc" "mden": "".
"ssnc" "sndr": "iTunes/12.1 (Macintosh; OS X 10.10.2)".
Picture received, length 39461 bytes.
"ssnc" "prgr": "2373925818/2373941178/2385081354".
"ssnc" "prsm": "".
With the --raw
option, you'll just get the raw metadata items.
Metadata is not used directly by Shairport Sync. Instead, it is routed to a pipe for other apps to use. All metadata received from the player is sent into the pipe in the order it is received. In addition, some metadata is generated by Shairport Sync itself and sent through the pipe. Metadata is sent in a uniform XML-style format, where each item comprises a type
, a code
, the length
of the data and finally the base64-encoded data, if any. The type
and code
are 4-character codes each encoded as 8 hexadecimal digits -- they can be read into C as 32-bit integers.
In some cases, an "RTP timestamp" is included as a piece of data. This is a 32-bit unsigned integer that can wrap around from its maximum value of 2^32-1 to zero and upwards. It appears to be the index number of an audio frame, with 44,100 frames to the second.
Here are more details:
-
We use two 4-character codes to identify each piece of data, the
type
and thecode
. -
The first 4-character code, called the
type
, is either: -
core
for all the regular metadadata coming from iTunes, etc., or -
ssnc
(for 'shairport-sync') for all metadata coming from Shairport Sync itself, such as start/end delimiters, etc. -
For
core
metadata, the second 4-character code is the 4-character metadata code that comes from iTunes etc. See, for example, https://code.google.com/p/ytrack/wiki/DMAP for information about the significance of the codes. The original data supplied by the source, if any, follows, and is encoded in base64 format. The length of the data is also provided. -
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 anssnc
type metadata message with the codePICT
. Progress information, similarly, is not tagged like other source-originated metadata, so it is sent as anssnc
type with the codeprgr
.
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.pbeg
-- play stream begin. No argumentspend
-- play stream end. No argumentspfls
-- play stream flush. No argumentsprsm
-- play stream resume. No argumentspvol
-- 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.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.
The next two two tokens are to facilitiate remote control of the source. There is some information at http://nto.github.io/AirPlay.html about remote control of the source.
daid
-- this is the source's DACP-ID (if it has one -- it's not guaranteed), useful if you want to remotely control the source. Use this string to identify the source's remote control on the network.acre
-- this is the source's Active-Remote token, necessary if you want to send commands to the source's remote control (if it has one).dapo
-- the payload is the port number (as text) of the source's remote control, to which commands should be sent. It is 3689 for iTunes but varies for iOS devices.clip
-- the payload is the IP number of the client, i.e. the sender of audio. It can be an IPv4 or an IPv6 number. In AirPlay 2 operation, it is sent as soon as the client has exclusive access to the player and after any existing play session has been interrupted and terminated.conn
-- the payload is the IP number of the client, i.e. the sender of audio. Can be an IPv4 or an IPv6 number. This is an AirPlay-2-only message. It is sent as soon as the client requests access to the player. If Shairport Sync is already playing, this message is sent before the current play session is stopped.svip
-- the payload is the IP number of the server, i.e. the player itself. Can be an IPv4 or an IPv6 number.disc
-- the payload is the IP number of the client, i.e. the sender of audio. Can be an IPv4 or an IPv6 number. This is an AirPlay-2-only message. It is sent when a client has been disconnected.
$autoreconf -i -f
$./configure
$make
$sudo make install