diff --git a/docker/Dockerfile b/docker/Dockerfile index a34d2c50..11647acd 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -16,21 +16,18 @@ RUN apk -U add \ dbus \ alsa-lib-dev \ popt-dev \ - mbedtls-dev \ soxr-dev \ avahi-dev \ libconfig-dev \ libsndfile-dev \ mosquitto-dev \ - xmltoman \ - openssh-client \ libsodium-dev \ + libgcrypt-dev \ ffmpeg-dev \ xxd \ libressl-dev \ openssl-dev \ - libplist-dev \ - libgcrypt-dev + libplist-dev ##### ALAC ##### RUN git clone https://github.com/mikebrady/alac @@ -76,7 +73,6 @@ RUN apk -U add \ dbus \ popt \ glib \ - mbedtls \ soxr \ avahi \ avahi-tools \ @@ -86,8 +82,8 @@ RUN apk -U add \ libuuid \ ffmpeg \ libsodium \ - libplist \ - libgcrypt + libgcrypt \ + libplist # Copy build files. COPY --from=builder /shairport-sync/build/install/usr/local/bin/shairport-sync /usr/local/bin/shairport-sync @@ -111,6 +107,4 @@ RUN addgroup -g 29 docker_audio && addgroup shairport-sync docker_audio && addgr # Remove anything we don't need. RUN rm -rf /lib/apk/db/* -ENTRYPOINT [ "/init" ] - -CMD [ "/usr/local/bin/shairport-sync", "-v", "--statistics" ] \ No newline at end of file +ENTRYPOINT [ "/init", "s6-setuidgid", "shairport-sync", "/usr/local/bin/shairport-sync" ] diff --git a/docker/README.md b/docker/README.md index 2b27e77f..648996cb 100644 --- a/docker/README.md +++ b/docker/README.md @@ -2,43 +2,37 @@ Available at: https://hub.docker.com/r/mikebrady/shairport-sync -The following docker tags are available: -``` -[tag] -[tag]-classic +Versions with tags including `-classic` provide classic AirPlay, the same as Shairport Sync versions up to 3.3.9. -(build from newest tag) -stable -stable-classic - -(latest build from master) -latest -latest-classic - -(latest build from development) -development -development-classic -``` +(**Note:** At this time, `stable` tags may not be available.) ## Example Docker Compose File See the `docker-compose.yaml` file in this folder for an example. -## Example Docker Run +## Docker Run + +To run the latest stable release of Shairport Sync, which provides AirPlay 2 service: ``` $ docker run -d --restart unless-stopped --net host --device /dev/snd \ - mikebrady/shairport-sync: + mikebrady/shairport-sync:stable +``` +To run the classic version: + +``` +$ docker run -d --restart unless-stopped --net host --device /dev/snd \ + mikebrady/shairport-sync:stable-classic ``` ### Options -You can change the default commands passed to Shairport Sync. Here is an example: +Command line options will be passed to Shairport Sync. Here is an example: ``` $ docker run -d --restart unless-stopped --net host --device /dev/snd \ - mikebrady/shairport-sync: shairport-sync -v \ - --statistics -a DenSystem -d hw:0 -c PCM + mikebrady/shairport-sync:stable \ + -v --statistics -a DenSystem -d hw:0 -c PCM ``` -This will sent audio to alsa hardware device `hw:0` and make use of the that device's mixer control called `PCM`. The service will be visible as `DenSystem` on the network. +This will send audio to alsa hardware device `hw:0` and make use of the that device's mixer control called `PCM`. The service will be visible as `DenSystem` on the network. ## Configuration File @@ -48,15 +42,15 @@ To get access to the full range of configuration options, pass the configuration ### Build Example (for arm7 devices) ``` -docker buildx build --platform linux/arm/v7 -f ./docker/Dockerfile --build-arg SHAIRPORT_SYNC_BRANCH=development --build-arg NQPTP_BRANCH=development --no-cache -t shairport-sync:unstable-development . +docker buildx build --platform linux/arm/v7 -f ./docker/Dockerfile --build-arg SHAIRPORT_SYNC_BRANCH=development --build-arg NQPTP_BRANCH=development --no-cache -t shairport-sync:development . ``` `SHAIRPORT_SYNC_BRANCH` and `NQPTP_BRANCH` are required to ensure the image is built using the expected branch. `--no-cache` needs to be used to force buildx to pull the NQPTP branch for new updates. This slows down the build time though so can be removed when it is not beneficial during testing. -### AirPlay 1 Only +### "Classic" AirPlay -The AirPlay 1 only dockerfile is in the `classic` folder. This also includes the `start.sh` script used by the container. Please note that the AirPlay 1 image built via the AirPlay 2 branch has missing functionality, e.g. it does not work with multiple instances on the same hardware; does not support iTunes for Windows etc. +The "Classic" AirPlay only dockerfile is in the `classic` folder. This also includes the `start.sh` script used by the container. ### GitHub Action Builds @@ -64,4 +58,4 @@ Requires the following secrets to be set in the repo: - `DOCKER_REGISTRY` - docker.io if using Docker Hub, else set to your registry URL. - `DOCKER_REGISTRY_TOKEN` - Access token for your registry. - `DOCKER_REGISTRY_USER` - Login user for your registry. -- `DOCKER_IMAGE_NAME` - The name of the image, for example `your-registry.com/shairport-sync` or just `your-username/shairport-sync` if using Docker Hub. \ No newline at end of file +- `DOCKER_IMAGE_NAME` - The name of the image, for example `your-registry.com/shairport-sync` or just `your-username/shairport-sync` if using Docker Hub. diff --git a/docker/classic/Dockerfile b/docker/classic/Dockerfile index 0556cd94..3010ca11 100644 --- a/docker/classic/Dockerfile +++ b/docker/classic/Dockerfile @@ -1,5 +1,12 @@ -FROM alpine AS builder-base -# General Build System: +FROM alpine:3.12 AS builder + +# Classic (aka AirPlay 1) Build + +# Check required arguments exist. These will be provided by the Github Action +# Workflow and are required to ensure the correct branches are being used. +ARG SHAIRPORT_SYNC_BRANCH +RUN test -n "$SHAIRPORT_SYNC_BRANCH" + RUN apk -U add \ git \ build-base \ @@ -7,63 +14,42 @@ RUN apk -U add \ automake \ libtool \ dbus \ - su-exec \ alsa-lib-dev \ - libdaemon-dev \ popt-dev \ mbedtls-dev \ soxr-dev \ avahi-dev \ libconfig-dev \ - libsndfile-dev \ mosquitto-dev \ - xmltoman - -# ALAC Build System: -FROM builder-base AS builder-alac + libsndfile-dev +##### ALAC ##### RUN git clone https://github.com/mikebrady/alac -WORKDIR alac -RUN autoreconf -fi +WORKDIR /alac +RUN autoreconf -i RUN ./configure RUN make RUN make install +WORKDIR / +##### ALAC END ##### -# Shairport Sync Build System: -FROM builder-base AS builder-sps - -# This will be modified by the Github Action Workflow and is required -# to ensure the correct branch is being used. -ARG SHAIRPORT_SYNC_BRANCH -RUN test -n "$SHAIRPORT_SYNC_BRANCH" - -COPY --from=builder-alac /usr/local/lib/libalac.* /usr/local/lib/ -COPY --from=builder-alac /usr/local/lib/pkgconfig/alac.pc /usr/local/lib/pkgconfig/alac.pc -COPY --from=builder-alac /usr/local/include /usr/local/include - +##### SPS ##### WORKDIR /shairport-sync COPY . . RUN git checkout "$SHAIRPORT_SYNC_BRANCH" -RUN autoreconf -fi -RUN ./configure \ - --with-alsa \ - --with-dummy \ - --with-pipe \ - --with-stdout \ - --with-avahi \ - --with-ssl=mbedtls \ - --with-soxr \ - --sysconfdir=/etc \ - --with-dbus-interface \ - --with-mpris-interface \ - --with-mqtt-client \ - --with-apple-alac \ - --with-convolution +WORKDIR /shairport-sync/build +RUN autoreconf -i ../ +RUN ../configure --sysconfdir=/etc --with-alsa --with-soxr --with-avahi --with-ssl=mbedtls \ + --with-metadata --with-dummy --with-pipe --with-dbus-interface \ + --with-stdout --with-mpris-interface --with-mqtt-client \ + --with-apple-alac --with-convolution RUN make -j $(nproc) -RUN make install +RUN DESTDIR=install make install +WORKDIR / +##### SPS END ##### -# Shairport Sync Runtime System: -FROM alpine +# Shairport Sync Runtime System +FROM crazymax/alpine-s6:3.12-3.1.1.2 RUN apk -U add \ alsa-lib \ @@ -75,30 +61,29 @@ RUN apk -U add \ avahi \ avahi-tools \ libconfig \ - libsndfile \ - mosquitto-libs \ - su-exec \ - libgcc \ - libgc++ + mosquitto \ + libsndfile-dev -RUN rm -rf /lib/apk/db/* -COPY --from=builder-alac /usr/local/lib/libalac.* /usr/local/lib/ -COPY --from=builder-sps /etc/shairport-sync* /etc/ -COPY --from=builder-sps /etc/dbus-1/system.d/shairport-sync-dbus.conf /etc/dbus-1/system.d/ -COPY --from=builder-sps /etc/dbus-1/system.d/shairport-sync-mpris.conf /etc/dbus-1/system.d/ -COPY --from=builder-sps /usr/local/bin/shairport-sync /usr/local/bin/shairport-sync +# Copy build files. +COPY --from=builder /shairport-sync/build/install/usr/local/bin/shairport-sync /usr/local/bin/shairport-sync +COPY --from=builder /usr/local/lib/libalac.* /usr/local/lib/ +COPY --from=builder /shairport-sync/build/install/etc/dbus-1/system.d/shairport-sync-dbus.conf /etc/dbus-1/system.d/ +COPY --from=builder /shairport-sync/build/install/etc/dbus-1/system.d/shairport-sync-mpris.conf /etc/dbus-1/system.d/ + +COPY ./docker/classic/etc/s6-overlay/s6-rc.d /etc/s6-overlay/s6-rc.d +RUN chmod +x /etc/s6-overlay/s6-rc.d/startup/script.sh # Create non-root user for running the container -- running as the user 'shairport-sync' also allows # Shairport Sync to provide the D-Bus and MPRIS interfaces within the container -RUN addgroup shairport-sync +RUN addgroup shairport-sync RUN adduser -D shairport-sync -G shairport-sync # Add the shairport-sync user to the pre-existing audio group, which has ID 29, for access to the ALSA stuff -RUN addgroup -g 29 docker_audio && addgroup shairport-sync docker_audio +RUN addgroup -g 29 docker_audio && addgroup shairport-sync docker_audio && addgroup shairport-sync audio -COPY ./docker/classic/start.sh / -RUN chmod +x /start.sh +# Remove anything we don't need. +RUN rm -rf /lib/apk/db/* -ENTRYPOINT [ "/start.sh" ] +ENTRYPOINT [ "/init", "s6-setuidgid", "shairport-sync", "/usr/local/bin/shairport-sync" ] diff --git a/docker/classic/README.md b/docker/classic/README.md index 09ac8872..abc69b66 100644 --- a/docker/classic/README.md +++ b/docker/classic/README.md @@ -1,3 +1,3 @@ -# Classic (AirPlay 1 Only) Docker Image +# Classic (aka AirPlay 1 Only) Docker Image See the [Shairport Sync Docker Hub Repo](https://hub.docker.com/r/mikebrady/shairport-sync) for available tags. \ No newline at end of file diff --git a/docker/classic/etc/s6-overlay/s6-rc.d/01-dbus/finish b/docker/classic/etc/s6-overlay/s6-rc.d/01-dbus/finish new file mode 100644 index 00000000..e4a13866 --- /dev/null +++ b/docker/classic/etc/s6-overlay/s6-rc.d/01-dbus/finish @@ -0,0 +1,2 @@ +#!/command/execlineb -S0 +/run/s6/basedir/bin/halt diff --git a/docker/classic/etc/s6-overlay/s6-rc.d/01-dbus/run b/docker/classic/etc/s6-overlay/s6-rc.d/01-dbus/run new file mode 100644 index 00000000..bf1cb501 --- /dev/null +++ b/docker/classic/etc/s6-overlay/s6-rc.d/01-dbus/run @@ -0,0 +1,4 @@ +#!/command/with-contenv sh +rm -rf /var/run/dbus.pid +echo "Starting dbus" +exec dbus-daemon --system --nofork diff --git a/docker/classic/etc/s6-overlay/s6-rc.d/01-dbus/type b/docker/classic/etc/s6-overlay/s6-rc.d/01-dbus/type new file mode 100644 index 00000000..5883cff0 --- /dev/null +++ b/docker/classic/etc/s6-overlay/s6-rc.d/01-dbus/type @@ -0,0 +1 @@ +longrun diff --git a/docker/classic/etc/s6-overlay/s6-rc.d/02-avahi/finish b/docker/classic/etc/s6-overlay/s6-rc.d/02-avahi/finish new file mode 100644 index 00000000..e4a13866 --- /dev/null +++ b/docker/classic/etc/s6-overlay/s6-rc.d/02-avahi/finish @@ -0,0 +1,2 @@ +#!/command/execlineb -S0 +/run/s6/basedir/bin/halt diff --git a/docker/classic/etc/s6-overlay/s6-rc.d/02-avahi/run b/docker/classic/etc/s6-overlay/s6-rc.d/02-avahi/run new file mode 100644 index 00000000..2f6be7b4 --- /dev/null +++ b/docker/classic/etc/s6-overlay/s6-rc.d/02-avahi/run @@ -0,0 +1,8 @@ +#!/command/with-contenv sh +sleep 5 +while [ ! -f /var/run/dbus.pid ]; do + "dbus is not running, sleeping for 5 seconds before trying to start avahi" + sleep 5 +done +echo "Starting avahi" +exec avahi-daemon --no-chroot diff --git a/docker/classic/etc/s6-overlay/s6-rc.d/02-avahi/type b/docker/classic/etc/s6-overlay/s6-rc.d/02-avahi/type new file mode 100644 index 00000000..5883cff0 --- /dev/null +++ b/docker/classic/etc/s6-overlay/s6-rc.d/02-avahi/type @@ -0,0 +1 @@ +longrun diff --git a/docker/classic/etc/s6-overlay/s6-rc.d/startup/script.sh b/docker/classic/etc/s6-overlay/s6-rc.d/startup/script.sh new file mode 100644 index 00000000..3037e98a --- /dev/null +++ b/docker/classic/etc/s6-overlay/s6-rc.d/startup/script.sh @@ -0,0 +1,2 @@ +#!/bin/sh +echo "STARTING - $(date)" diff --git a/docker/classic/etc/s6-overlay/s6-rc.d/startup/type b/docker/classic/etc/s6-overlay/s6-rc.d/startup/type new file mode 100644 index 00000000..bdd22a18 --- /dev/null +++ b/docker/classic/etc/s6-overlay/s6-rc.d/startup/type @@ -0,0 +1 @@ +oneshot diff --git a/docker/classic/etc/s6-overlay/s6-rc.d/startup/up b/docker/classic/etc/s6-overlay/s6-rc.d/startup/up new file mode 100644 index 00000000..06df8350 --- /dev/null +++ b/docker/classic/etc/s6-overlay/s6-rc.d/startup/up @@ -0,0 +1 @@ +/etc/s6-overlay/s6-rc.d/startup/script.sh diff --git a/docker/classic/etc/s6-overlay/s6-rc.d/user/contents.d/01-dbus b/docker/classic/etc/s6-overlay/s6-rc.d/user/contents.d/01-dbus new file mode 100644 index 00000000..e69de29b diff --git a/docker/classic/etc/s6-overlay/s6-rc.d/user/contents.d/02-avahi b/docker/classic/etc/s6-overlay/s6-rc.d/user/contents.d/02-avahi new file mode 100644 index 00000000..e69de29b diff --git a/docker/classic/etc/s6-overlay/s6-rc.d/user/contents.d/startup b/docker/classic/etc/s6-overlay/s6-rc.d/user/contents.d/startup new file mode 100644 index 00000000..e69de29b diff --git a/docker/classic/start.sh b/docker/classic/start.sh index 5e24ff59..23b41efb 100644 --- a/docker/classic/start.sh +++ b/docker/classic/start.sh @@ -10,4 +10,4 @@ dbus-daemon --system avahi-daemon --daemonize --no-chroot -su-exec shairport-sync shairport-sync "$@" \ No newline at end of file +su-exec shairport-sync shairport-sync "$@" diff --git a/docker/docker-compose.yaml b/docker/docker-compose.yaml index 6b2394a1..5867d7ba 100644 --- a/docker/docker-compose.yaml +++ b/docker/docker-compose.yaml @@ -2,7 +2,7 @@ services: shairport-sync: - image: mikebrady/shairport-sync: + image: mikebrady/shairport-sync:stable network_mode: host restart: unless-stopped devices: @@ -12,4 +12,4 @@ services: logging: options: max-size: "200k" - max-file: "10" \ No newline at end of file + max-file: "10" diff --git a/docker/etc/s6-overlay/s6-rc.d/01-dbus/finish b/docker/etc/s6-overlay/s6-rc.d/01-dbus/finish index a8222fb0..e4a13866 100644 --- a/docker/etc/s6-overlay/s6-rc.d/01-dbus/finish +++ b/docker/etc/s6-overlay/s6-rc.d/01-dbus/finish @@ -1,2 +1,2 @@ #!/command/execlineb -S0 -/run/s6/basedir/bin/halt \ No newline at end of file +/run/s6/basedir/bin/halt diff --git a/docker/etc/s6-overlay/s6-rc.d/01-dbus/run b/docker/etc/s6-overlay/s6-rc.d/01-dbus/run index 8757e5d5..bf1cb501 100644 --- a/docker/etc/s6-overlay/s6-rc.d/01-dbus/run +++ b/docker/etc/s6-overlay/s6-rc.d/01-dbus/run @@ -1,4 +1,4 @@ #!/command/with-contenv sh rm -rf /var/run/dbus.pid echo "Starting dbus" -exec dbus-daemon --system --nofork \ No newline at end of file +exec dbus-daemon --system --nofork diff --git a/docker/etc/s6-overlay/s6-rc.d/01-dbus/type b/docker/etc/s6-overlay/s6-rc.d/01-dbus/type index 1780f9f4..5883cff0 100644 --- a/docker/etc/s6-overlay/s6-rc.d/01-dbus/type +++ b/docker/etc/s6-overlay/s6-rc.d/01-dbus/type @@ -1 +1 @@ -longrun \ No newline at end of file +longrun diff --git a/docker/etc/s6-overlay/s6-rc.d/02-avahi/finish b/docker/etc/s6-overlay/s6-rc.d/02-avahi/finish index a8222fb0..e4a13866 100644 --- a/docker/etc/s6-overlay/s6-rc.d/02-avahi/finish +++ b/docker/etc/s6-overlay/s6-rc.d/02-avahi/finish @@ -1,2 +1,2 @@ #!/command/execlineb -S0 -/run/s6/basedir/bin/halt \ No newline at end of file +/run/s6/basedir/bin/halt diff --git a/docker/etc/s6-overlay/s6-rc.d/02-avahi/run b/docker/etc/s6-overlay/s6-rc.d/02-avahi/run index fc509297..2f6be7b4 100644 --- a/docker/etc/s6-overlay/s6-rc.d/02-avahi/run +++ b/docker/etc/s6-overlay/s6-rc.d/02-avahi/run @@ -5,4 +5,4 @@ while [ ! -f /var/run/dbus.pid ]; do sleep 5 done echo "Starting avahi" -exec avahi-daemon --no-chroot \ No newline at end of file +exec avahi-daemon --no-chroot diff --git a/docker/etc/s6-overlay/s6-rc.d/02-avahi/type b/docker/etc/s6-overlay/s6-rc.d/02-avahi/type index 1780f9f4..5883cff0 100644 --- a/docker/etc/s6-overlay/s6-rc.d/02-avahi/type +++ b/docker/etc/s6-overlay/s6-rc.d/02-avahi/type @@ -1 +1 @@ -longrun \ No newline at end of file +longrun diff --git a/docker/etc/s6-overlay/s6-rc.d/03-nqptp/finish b/docker/etc/s6-overlay/s6-rc.d/03-nqptp/finish index a8222fb0..e4a13866 100644 --- a/docker/etc/s6-overlay/s6-rc.d/03-nqptp/finish +++ b/docker/etc/s6-overlay/s6-rc.d/03-nqptp/finish @@ -1,2 +1,2 @@ #!/command/execlineb -S0 -/run/s6/basedir/bin/halt \ No newline at end of file +/run/s6/basedir/bin/halt diff --git a/docker/etc/s6-overlay/s6-rc.d/03-nqptp/run b/docker/etc/s6-overlay/s6-rc.d/03-nqptp/run index 7af2c601..27a489b8 100644 --- a/docker/etc/s6-overlay/s6-rc.d/03-nqptp/run +++ b/docker/etc/s6-overlay/s6-rc.d/03-nqptp/run @@ -1,3 +1,3 @@ #!/command/with-contenv sh echo "Starting nqptp" -exec /usr/local/bin/nqptp -v \ No newline at end of file +exec /usr/local/bin/nqptp diff --git a/docker/etc/s6-overlay/s6-rc.d/03-nqptp/type b/docker/etc/s6-overlay/s6-rc.d/03-nqptp/type index 1780f9f4..5883cff0 100644 --- a/docker/etc/s6-overlay/s6-rc.d/03-nqptp/type +++ b/docker/etc/s6-overlay/s6-rc.d/03-nqptp/type @@ -1 +1 @@ -longrun \ No newline at end of file +longrun diff --git a/docker/etc/s6-overlay/s6-rc.d/startup/script.sh b/docker/etc/s6-overlay/s6-rc.d/startup/script.sh index c975a403..3037e98a 100644 --- a/docker/etc/s6-overlay/s6-rc.d/startup/script.sh +++ b/docker/etc/s6-overlay/s6-rc.d/startup/script.sh @@ -1,2 +1,2 @@ #!/bin/sh -echo "STARTING - $(date)" \ No newline at end of file +echo "STARTING - $(date)" diff --git a/docker/etc/s6-overlay/s6-rc.d/startup/type b/docker/etc/s6-overlay/s6-rc.d/startup/type index 3d92b15f..bdd22a18 100644 --- a/docker/etc/s6-overlay/s6-rc.d/startup/type +++ b/docker/etc/s6-overlay/s6-rc.d/startup/type @@ -1 +1 @@ -oneshot \ No newline at end of file +oneshot diff --git a/docker/etc/s6-overlay/s6-rc.d/startup/up b/docker/etc/s6-overlay/s6-rc.d/startup/up index 0c609ec6..06df8350 100644 --- a/docker/etc/s6-overlay/s6-rc.d/startup/up +++ b/docker/etc/s6-overlay/s6-rc.d/startup/up @@ -1 +1 @@ -/etc/s6-overlay/s6-rc.d/startup/script.sh \ No newline at end of file +/etc/s6-overlay/s6-rc.d/startup/script.sh diff --git a/metadata_hub.c b/metadata_hub.c index 4d21de52..b66035a0 100644 --- a/metadata_hub.c +++ b/metadata_hub.c @@ -5,7 +5,7 @@ * then you need a metadata hub, * where everything is stored * This file is part of Shairport Sync. - * Copyright (c) Mike Brady 2017--2020 + * Copyright (c) Mike Brady 2017--2022 * All rights reserved. * * Permission is hereby granted, free of charge, to any person @@ -326,18 +326,21 @@ char *metadata_write_image_file(const char *buf, int len) { return path; } +int metadata_packet_item_changed = 0; // set if any parsed part of a metadata stream changes + void metadata_hub_process_metadata(uint32_t type, uint32_t code, char *data, uint32_t length) { // metadata coming in from the audio source or from Shairport Sync itself passes through here // this has more information about tags, which might be relevant: // https://code.google.com/p/ytrack/wiki/DMAP - // all the following items of metadata are contained in one metadata packet - // they are preceded by an 'ssnc' 'mdst' item and followed by an 'ssnc 'mden' item. - // we don't set "changed" for them individually; instead we set it when the 'mden' token - // comes in if the metadata_packet_item_changed is set. + // Some metadata items are contained in one metadata packet. + // The start of the metadata packet is signalled by an 'ssnc' 'mdst' item and + // the end of it by an 'ssnc 'mden' item. + // We don't set "changed" for them individually; instead we set it when the 'mden' token + // comes in if the metadata_packet_item_changed item is set by parsed items + // within the packet. int changed = 0; - int metadata_packet_item_changed = 0; metadata_hub_modify_prolog(); pthread_cleanup_push(metadata_hub_unlock_hub_mutex_cleanup, NULL); @@ -507,7 +510,10 @@ void metadata_hub_process_metadata(uint32_t type, uint32_t code, char *data, uin metadata_packet_item_changed = 0; break; case 'mden': - debug(2, "MH Metadata stream processing end."); + if (metadata_packet_item_changed != 0) + debug(2, "MH Metadata stream processing end with changes."); + else + debug(2, "MH Metadata stream processing end without changes."); changed = metadata_packet_item_changed; break; case 'PICT': @@ -568,6 +574,7 @@ void metadata_hub_process_metadata(uint32_t type, uint32_t code, char *data, uin changed = (metadata_store.active_state != AM_INACTIVE); metadata_store.active_state = AM_INACTIVE; break; + case 'pres': case 'pbeg': changed = ((metadata_store.player_state != PS_PLAYING) || (metadata_store.player_thread_active == 0)); @@ -580,15 +587,18 @@ void metadata_hub_process_metadata(uint32_t type, uint32_t code, char *data, uin metadata_store.player_state = PS_STOPPED; metadata_store.player_thread_active = 0; break; - case 'pfls': + case 'paus': changed = (metadata_store.player_state != PS_PAUSED); metadata_store.player_state = PS_PAUSED; break; +/* +// not using this anymore. case 'pffr': // this is sent when the first frame has been received case 'prsm': changed = (metadata_store.player_state != PS_PLAYING); metadata_store.player_state = PS_PLAYING; break; +*/ case 'pvol': { // Note: it's assumed that the config.airplay volume has already been correctly set. // int32_t actual_volume; diff --git a/player.c b/player.c index 68a3b5bf..579de7a7 100644 --- a/player.c +++ b/player.c @@ -1157,7 +1157,6 @@ static abuf_t *buffer_get_frame(rtsp_conn_info *conn) { conn->connection_number, conn->first_packet_timestamp, lt * 0.000000001); #ifdef CONFIG_METADATA // say we have started receiving frames here - debug(2, "pffr"); send_ssnc_metadata( 'pffr', NULL, 0, 0); // "first frame received", but don't wait if the queue is locked @@ -1303,7 +1302,6 @@ static abuf_t *buffer_get_frame(rtsp_conn_info *conn) { } #ifdef CONFIG_METADATA if (conn->ab_buffering == 0) { - debug(2, "prsm"); send_ssnc_metadata('prsm', NULL, 0, 0); // "resume", but don't wait if the queue is locked } @@ -3388,7 +3386,6 @@ void player_flush(uint32_t timestamp, rtsp_conn_info *conn) { // only send a flush metadata message if the first packet has been seen -- it's a bogus message // otherwise if (conn->first_packet_timestamp) { - debug(2, "pfls"); char numbuf[32]; snprintf(numbuf, sizeof(numbuf), "%u", timestamp); send_ssnc_metadata('pfls', numbuf, strlen(numbuf), 1); // contains cancellation points @@ -3458,7 +3455,6 @@ int player_play(rtsp_conn_info *conn) { debug(1, "Error creating player_thread: %s", strerror(errno)); #ifdef CONFIG_METADATA - debug(2, "pbeg"); send_ssnc_metadata('pbeg', NULL, 0, 1); // contains cancellation points #endif return 0; @@ -3484,7 +3480,6 @@ int player_stop(rtsp_conn_info *conn) { free(conn->player_thread); conn->player_thread = NULL; #ifdef CONFIG_METADATA - debug(2, "pend"); send_ssnc_metadata('pend', NULL, 0, 1); // contains cancellation points #endif // debuglev = dl; diff --git a/rtsp.c b/rtsp.c index 6c109c18..52add733 100644 --- a/rtsp.c +++ b/rtsp.c @@ -2001,13 +2001,20 @@ void handle_setrateanchori(rtsp_conn_info *conn, rtsp_message *req, rtsp_message debug(2, "Connection %d: Start playing, with anchor clock %" PRIx64 ".", conn->connection_number, conn->networkTimeTimelineID); activity_monitor_signify_activity(1); + +#ifdef CONFIG_METADATA + send_ssnc_metadata('pres', NULL, 0, 1); // resume -- contains cancellation points +#endif conn->ap2_play_enabled = 1; } else { debug(2, "Connection %d: Stop playing.", conn->connection_number); - activity_monitor_signify_activity(0); conn->ap2_play_enabled = 0; + activity_monitor_signify_activity(0); reset_anchor_info(conn); - if (config.output->stop) { +#ifdef CONFIG_METADATA + send_ssnc_metadata('paus', NULL, 0, 1); // pause -- contains cancellation points +#endif + if (config.output->stop) { debug(2, "Connection %d: Stop the output backend.", conn->connection_number); config.output->stop(); } @@ -3615,8 +3622,10 @@ void handle_set_parameter_parameter(rtsp_conn_info *conn, rtsp_message *req, // frame number. It seems that all frames up to but not // including this frame are to be flushed. // -// 'prsm' -- play stream resume. No arguments -// `pffr` -- the first frame of a play session has been received and has been validly +// 'prsm' -- play stream resume. No arguments. (deprecated) +// 'paus' -- buffered audio stream paused. No arguments. +// 'pres' -- buffered audio stream resumed. No arguments. +// 'pffr' -- the first frame of a play session has been received and has been validly // timed. // 'pvol' -- play volume. The volume is sent as a string -- // "airplay_volume,volume,lowest_volume,highest_volume"