-
name: belora-connect
-
description: CONNECT is a real-time AI interpreter for video calls (Zoom, Google Meet, etc). Its core mechanism requires bidirectional audio rerouting of the conferencing app: - INCOMING: the conferencing app’s playback stream (the remote speaker) is moved away from the hardware speakers into a virtual sink created by CONNECT. CONNECT captures this audio, translates it, and the user hears only the translated output. - OUTGOING: the user’s real microphone is captured and translated. The translated speech is played into a virtual source, and CONNECT then forces the conferencing app to use that virtual source as its microphone input, so the remote party hears the translation instead of (or alongside) the original speech. This two-way stream redirection IS the product: there is no fallback mode, as live interpretation is impossible without it.
-
snapcraft: PRIVATE
-
upstream: PRIVATE
-
upstream-relation: I am the sole developer and owner of this project.
-
supported-category: This snap does not fit cleanly into one of the pre-approved categories. It falls under the general criteria of “access to resources not yet supported by snapd” (audio server administration), as detailed in the technical reasoning below.
-
reasoning: CONNECT’s core function requires administering the system audio server and manipulating the streams of OTHER running applications: - It loads PulseAudio/PipeWire modules at runtime (pactl load-module module-null-sink / module-remap-source) to create virtual routing devices. - It moves the conferencing app’s incoming playback stream away from the hardware speakers into a virtual sink (pactl move-sink-input), so it can intercept and translate it before the user hears it. - It moves/forces the conferencing app’s microphone input to a virtual source (pactl move-source-output / setting the virtual device as default source), so the translated speech reaches the remote party instead of the user’s raw voice. - It lists which applications are currently using audio devices, to identify the correct conferencing app stream to redirect. I have reviewed the existing interfaces (audio-playback, audio-record, pulseaudio, pipewire). These interfaces allow an app to play or record its own audio, but they do not grant the ability to administer the audio server (loading/unloading modules) or to inspect/redirect the streams of other confined or unconfined applications. This is a deliberate sandboxing restriction, not a missing permission I can request — there is no existing interface that exposes this functionality under strict confinement. I understand strict confinement is preferred. I tested the snap under strict confinement with the audio-playback/audio-record interfaces connected: basic microphone capture works, but module loading and the bidirectional stream redirection described above fail as expected, since both require full audio server control. Without this redirection, the app’s sole purpose — real-time call interpretation — cannot function at all.
This request has been added to the queue for review by the @reviewers team.
This would be a hard blocker then …
But using pactl from inside a snap to manipulate pluseaudio/pipewire via the socket is exactly what the pipewire and pulseaudio interfaces are designed for, there are plenty of apps using this method to redirect streams, remapping sources etc
There should be no need to have any further permissions as long ass your snap ships the correct tools and libs and has one of these interfaces connected. You might want to take a look at snaps like pulsemixer to see how they achieve this without classic confinement.
Hello @belora-connect ![]()
As @ogra mentioned, falling under one of the supported categories is a hard requirement for classic confinement. Therefore, we are not able to grant it at the moment.
Feel free to ping us if you need further assistance!
Update: solved it, and you were right — strict confinement works fine.
With base: core24, the pipewire and audio-record interfaces connected, and pulseaudio-utils/pipewire-bin bundled inside the snap, the only remaining issue was the PipeWire/Pulse client looking for the socket in the snap’s XDG_RUNTIME_DIR (/run/user/<uid>/snap.<name>) instead of /run/user/<uid>. Setting PIPEWIRE_RUNTIME_DIR and PULSE_RUNTIME_PATH to the real runtime dir fixed it — pactl load-module module-null-sink and the bidirectional stream redirection now succeed under strict confinement, with no AppArmor denials at all.
So I’m withdrawing the classic confinement request. Thanks for pushing back on this.
One follow-up before I publish: the app’s core function depends on both pipewire and audio-record, but neither auto-connects by default (only audio-playback and the desktop/x11/wayland/opengl plugs do). As it stands, users would have to run snap connect belora-connect:pipewire and :audio-record manually for the app to work at all. Could auto-connect be granted for these two interfaces on this snap, or is there a preferred approach? Happy to provide any details you need.