Files
Mike Brady b405c0b896 Version 5.0 Major Release.
New Features:
Multi-Channel and High-Resolution Audio Support
48,000 frames per second ("48k") operation.
48k lossless stereo support.
5.1 and 7.1 surround sound support.
Multi-channel and multi-rate operation on ALSA, PipeWire, PulseAudio, FreeBSD, stdout and Unix pipe output backends.
Automatic Audio Format Selection
Flexible and controllable output format selection.
Automatic rate, sample format, and channel count selection.
Full FFmpeg Integration
Support for transcoding.
Advanced resampling capabilities.
New audio format support.
Enhanced Resampling
New vernier resampling and interpolation method optimized for low-power CPUs.
Better performance on resource-constrained devices.

Convolution and Loudness Enhancements:
Convolution system is now multithreaded and works on stereo and multichannel audio at 48k and 44.1k.
Multiple impulse response (IR) files can now be provided via convolution_ir_files setting.
New convolution_thread_pool_size setting for multithreaded processing (defaults to 1).
Loudness processing now works with stereo and multichannel audio at 48k and 44.1k.
Updated to the most recent HiFi-LoFi FFT convolver.

MQTT Enhancements:
Added new publish_retain boolean option. When enabled, published MQTT messages have the retain flag set, so the MQTT broker stores the last message per topic and new subscribers receive the most recent value immediately. Thanks to lululombard for PR #2142.

D-Bus Enhancements:
Added new dbus_default_message_bus command-line argument (can be system or session) to set the default message bus for both D-Bus native service and MPRIS service.

Performance Improvements:
Enhanced compatibility with AirPlay 2 AutoMix and Smart Tracklists resulting in less unexplained track skipping.
Better operation on low-power devices down to Raspberry Pi B.
Improved efficiency on embedded systems.
Enhanced timestamp handling for better synchronization.
Improved sync error calculation.
Rebuilt buffered audio processor for cleaner handling of immediate and deferred flush requests.

Docker Enhancements:
Reduced Docker image sizes with slimmed-down FFmpeg library.
Removed dhclient from Docker images for smaller footprint.

Bug Fixes:
Fixed MQTT warning on service startup: "Could not establish a mqtt connection". The startup script now correctly states that the mosquitto service is required. Thanks to Hugo Villeneuve for PR #2137.
Fixed compatibility with mbedtls library version 3.4+ (present on recent Linux versions). Thanks to Christian Beier for finding and fixing the bug.
Fixed PulseAudio backend so that PA_ERR_NODATA returns "No latency data yet". Thanks to Vladimir Shakov for the report and fix.
Ensured old flush requests are deleted when a new play session starts. Thanks to saujanyashah for the report.
Fixed format warnings on 64-bit and 32-bit systems
Removed compilation warnings on 32-bit builds
Improved argument checking for debug(), inform(), warn() and die() functions
Fixed "daemon" typos throughout codebase. Thanks to Chris Boot for PR #1981.
Added warning if a convolution impulse response file cannot be read due to bad path or permissions

Build System Improvements:
Unified service file with variable substitution for Avahi support, making it easier to add future service dependencies. Thanks to Hugo Villeneuve.
Network interface selection now only considers interfaces that are up, running and not loopback interfaces. Thanks to Carl Johnson for the suggestion.
Configuration File Changes and Deprecations

New settings: convolution_ir_files (replaces convolution_ir_file), convolution_enabled (replaces convolution), convolution_max_length_in_seconds (replaces convolution_max_length), loudness_enabled (replaces loudness).
New convolution_thread_pool_size setting (defaults to 1).
Deprecated settings: convolution_ir_file, convolution, convolution_max_length, loudness.
Corresponding D-Bus methods and properties have been updated.

Deprecation Notice:
The Jack Audio and soundio backends are deprecated and will be removed in a future release. Consider using the updated PipeWire backend instead.

Documentation Updates
Updated BUILD.md with latest build instructions.
Updated AIRPLAY2.md with feature information.
Enhanced convolution and loudness documentation.

Maintenance:
Fixed FFmpeg deprecation warnings.
Bumped actions/checkout from 6.0.1 to 6.0.2.
Bumped docker/login-action from 3.6.0 to 3.7.0.
Bumped docker/build-push-action from 6.13.0 to 6.15.0.
Bumped docker/setup-qemu-action from 3.4.0 to 3.6.0.
Bumped docker/setup-buildx-action from 3.9.0 to 3.10.0.
2026-02-13 15:17:40 +00:00

236 lines
12 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# MQTT in Shairport Sync
To enable Shairport Sync to act as an MQTT publisher, you need to:
1. Install the mosquitto library:
```
# apt install libmosquitto-dev
```
2. Add the configuration flag `--with-mqtt-client` to the list of parameters to the `./configure...` command. For example:
```
$ ./configure --with-mqtt-client --sysconfdir=/etc --with-alsa --with-avahi --with-ssl=openssl --with-systemd
```
If Shairport Sync has MQTT support, it will have the string `mqtt` in its configuration string. For example:
```
$ shairport-sync -V
3.3.8-OpenSSL-Avahi-ALSA-metadata-mqtt-sysconfdir:/etc
```
**Note:** [The Docker image](https://hub.docker.com/r/mikebrady/shairport-sync) will have MQTT support enabled by default.
## Setting Up MQTT Publishing
This is a rough guide on the setup of MQTT publishing in ShairPort Sync. The MQTT service listens for and publishes metadata generated by the AirPlay source and Shairport Sync.
### Example Configuration
In the following example, Shairport Sync is configured to publish parsed metadata information and album-art to a MQTT server under the topic "shairport".
```xml
metadata =
{
enabled = "yes"; // Set this to yes to get Shairport Sync to solicit metadata from the source and to pass it on via a pipe.
include_cover_art = "yes"; // Set to "yes" to get Shairport Sync to solicit cover art from the source and pass it via the pipe. You must also set "enabled" to "yes".
cover_art_cache_directory = "/tmp/shairport-sync/.cache/coverart"; // Artwork will be stored in this directory if the dbus or MPRIS interfaces are enabled or if the MQTT client is in use. Set it to "" to prevent caching, which may be useful on some systems.
pipe_name = "/tmp/shairport-sync-metadata";
pipe_timeout = 5000; // Wait for this number of milliseconds for a blocked pipe to unblock before giving up.
};
mqtt =
{
enabled = "yes"; // Set this to yes to enable the mqtt-metadata-service.
hostname = "192.168.1.111"; // Hostname of the MQTT Broker.
port = 1883; // Port on the MQTT Broker to connect to.
username = "username"; // Set this to your MQTT user's username in order to enable username authentication.
password = "password"; // Set this to your MQTT user's password in order to enable username & password authentication.
topic = "shairport"; // MQTT topic where this instance of Shairport Sync should publish. If not set, the general.name value is used.
// publish_raw = "no"; // Whether to publish all available metadata under the codes given in the 'metadata' docs.
publish_parsed = "yes"; // Whether to publish a small (but useful) subset of metadata under human-understandable topics.
publish_cover = "yes"; // Whether to publish the cover over MQTT in binary form. This may lead to a bit of load on the broker.
// publish_retain = "no"; // Whether to set the retain flag on published MQTT messages. When enabled, the broker stores the last message for each topic so new subscribers receive the most recent value immediately.
// enable_remote = "no"; // Whether to remote control via MQTT. RC is available under `topic`/remote.
};
```
**Important:** Either `publish_raw`, `publish_parsed`, or `publish_cover` need to be set in the MQTT configuration. Otherwise, no messages will be published.
## Overall Active States
`active_start` and `active_end` represent a stable on/off flag for the current AirPlay session.
`active_start` is plublished when any new AirPlay session begins.
`active_end` will fire after a configured timeout period unless the AirPlay stream is resumed.
```xml
sessioncontrol =
{
// "active" state starts when play begins, and ends when the active_state_timeout has elapsed after play ends, unless another play session starts before the timeout has fully elapsed.
active_state_timeout = 30.0;
};
```
## Metadata Parsing
Additional details regarding the metadata can be found at https://github.com/mikebrady/shairport-sync-metadata-reader.
Metadata is generated by both the stream source (iOS, iTunes, etc.) and by Shairport Sync itself. This data is coded as two 4-character codes to identify each piece of data, the `type` and the `code`.
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.
Additionally:
* 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 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:
* `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.
* `acre` -- Active Remote
* `cdid` -- Client advertised Device ID
* `clip` -- the payload is the IP address of the client, i.e. the sender of audio. Can be an IPv4 or an IPv6 address.
* `cmac` -- Client advertised MAC address
* `cmod` -- Client advertised model ("iPhone14,2")
* `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
* `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.
* `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 for AP1, or direct from the configuration Plist for AP2.
* `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
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
* `client_ip` -- IP address of the connected client
* `client_device_id` -- Client advertised Device ID
* `client_mac_address` -- Client advertised MAC address
* `client_model` -- Client advertised model ("iPhone14,2")
* `client_name` -- Client advertised name ("Joe's iPhone")
* `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)
Additionally, empty messages (`--`) at the following topics are published.
* `play_start` -- fired at the begining of every song
* `play_end` -- fired at the end of every song
* `play_flush` -- fired when song is skipped or on positional change
* `play_resume` -- fired when song play resumes from pause
* `active_start` -- fired when a new active AirPlay session begins
* `active_end` -- fired after a configured timeout period after the stream ends (unless a new stream begins)
## Consuming MQTT Data
MQTT provides users with the flexibility to consume the MQTT data in various home automation projects. If you have an interesting use, please raise a new issue to suggest adding it to the guide, or simply fork the development branch and create a pull request.
### [Home Assistant](https://www.home-assistant.io/) Examples
The `active_start` and `active_end` have good potential use as triggers to turn on and off various connected receivers/zones. Note that `payload_off` is set to prevent accidental triggering.
```yml
mqtt:
- binary_sensor:
name: "shairport active start"
state_topic: "shairport/active_start"
payload_on: "--"
payload_off: "OFF"
off_delay: 300
- binary_sensor:
name: "shairport active end"
state_topic: "shairport/active_end"
payload_on: "--"
payload_off: "OFF"
off_delay: 300
```
In the below example, the parsed data is saved into the Home Assistant database as sensor data. Please note the conversion of the volume from dB to percentage.
```yml
mqtt:
sensor:
- name: "shairport album"
state_topic: "shairport/album"
expire_after: 600
- name: "shairport artist"
state_topic: "shairport/artist"
expire_after: 600
- name: "shairport title"
state_topic: "shairport/title"
expire_after: 600
- name: "shairport genre"
state_topic: "shairport/genre"
expire_after: 600
- name: "shairport volume (dB)"
state_topic: "shairport/volume"
- name: "shairport volume (PCT)"
state_topic: "shairport/volume"
value_template: "{{ value | regex_findall_index(find='^(.+?),', index=0, ignorecase=False) | float / 30 + 1 }}"
unit_of_measurement: 'percent'
```
### [Homebridge](https://homebridge.io/) [MQTTThing](https://github.com/arachnetech/homebridge-mqttthing#readme) Examples
**Homebridge** is a lightweight Node.js server that brings non-HomeKit devices to Apple’s Home app, and **MQTTThing** is a versatile Homebridge plugin that integrates MQTT-enabled devices with HomeKit.
While MQTTThing offers a speaker characteristic, it does not seem to be recognized by HomeKit. Instead, the **contact sensor** characteristic can effectively represent Shairport Sync’s `active` status within HomeKit, enabling users to trigger automations based on this status.
Below is an example configuration for Homebridge's JSON Config to represent Shairport Sync's `active` status:
```json
"accessories": [
{
"type": "contactSensor",
"name": "Shairport",
"url": "hostname:1883",
"username": "user",
"password": "password",
"topics": {
"getContactSensorState": "shairport/active"
},
"onValue": "1",
"offValue": "0",
"otherValueOff": false,
"accessory": "mqttthing"
}
]
```
* Replace hostname:1883, user, and password with the details of your MQTT broker.
* The topic shairport/active should match the one configured in Shairport Sync’s MQTT settings.
* The onValue and offValue correspond to the MQTT messages indicating whether Shairport Sync is active (1) or inactive (0).
MQTTThing supports a wide range of characteristics, allowing additional topics from Shairport Sync or other devices to be represented in HomeKit as different accessory types (e.g., switches, lights, or sensors) in a similar manner.