diff --git a/Dockerfile b/Dockerfile index 93d22e1..88c9e92 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,10 +1,10 @@ -FROM python:3.11-slim-bookworm +FROM python:3.11-bookworm ENV LANG C.UTF-8 ENV DEBIAN_FRONTEND=noninteractive RUN apt-get update && \ - apt-get install --yes --no-install-recommends alsa-utils + apt-get install --yes --no-install-recommends alsa-utils pulseaudio WORKDIR /app @@ -13,6 +13,7 @@ COPY setup.py requirements.txt MANIFEST.in ./ COPY wyoming_snd_external/ ./wyoming_snd_external/ RUN script/setup +RUN echo load-module module-role-ducking trigger_roles=phone ducking_roles=music volume=0.0 >> /etc/pulse/default.pa COPY script/run ./script/ COPY docker/run ./ diff --git a/docker/run b/docker/run index 3f79e84..2059d9e 100755 --- a/docker/run +++ b/docker/run @@ -11,14 +11,19 @@ while [ -n "$1" ]; do shift done -if [ -z "${device}" ]; then - echo "--device is required. Run 'aplay -L' for a list (prefer plughw: devices)." - exit 1 +if [ -z "${program}" ]; then + if [ -z "${device}" ]; then + echo "--device is required. Run 'aplay -L' for a list (prefer plughw: devices)." + exit 1 + fi + program="aplay -D ${device} -r 22050 -c 1 -f S16_LE -t raw" fi +# pulseaudio --system --disallow-exit --disallow-module-loading=1 --daemonize=yes -F /etc/pulse/system.pa + /app/script/run \ --uri tcp://0.0.0.0:10601 \ - --program "aplay -D ${device} -r 22050 -c 1 -f S16_LE -t raw" \ + --program "${program}" \ --rate 22050 \ --width 2 \ --channels 1 "${args[@]}" diff --git a/wyoming_snd_external/__main__.py b/wyoming_snd_external/__main__.py index 80bdc8a..c8d1e33 100644 --- a/wyoming_snd_external/__main__.py +++ b/wyoming_snd_external/__main__.py @@ -94,6 +94,7 @@ async def handle_event(self, event: Event) -> bool: elif AudioStop.is_type(event.type): await self.write_event(Played().event()) elif AudioChunk.is_type(event.type): + _LOGGER.debug("Handling Chunk %s", self.command) await self._start_proc() chunk = AudioChunk.from_event(event) @@ -113,15 +114,19 @@ async def _start_proc(self) -> None: return _LOGGER.debug("Running %s", self.command) - self._proc = await asyncio.create_subprocess_exec( - self.command[0], *self.command[1:], stdin=asyncio.subprocess.PIPE - ) + try: + self._proc = await asyncio.create_subprocess_exec( + self.command[0], *self.command[1:], stdin=asyncio.subprocess.PIPE + ) + except Exception as e: + _LOGGER.error("Unable to create subprocess. %s", e) assert self._proc.stdin is not None async def _stop_proc(self) -> None: if self._proc is None: return + _LOGGER.debug("Stopping %s", self.command) try: self._proc.stdin.write_eof() await self._proc.stdin.wait_closed()