Working streaming audio

This commit is contained in:
Mahesh Kommareddi 2024-07-23 23:25:47 -04:00
parent e9e246a0cf
commit 849a2551e1
8 changed files with 153 additions and 15 deletions

View File

@ -7,8 +7,16 @@ RUN apt-get update && apt-get install -y \
xfce4 \
xfce4-goodies \
sudo \
pulseaudio \
gstreamer1.0-tools gstreamer1.0-plugins-good \
gstreamer1.0-plugins-bad \
gstreamer1.0-plugins-ugly \
tigervnc-standalone-server tigervnc-common \
alsa dbus \
nano vim \
&& apt-get clean
RUN mkdir /var/run/sshd
RUN sed -i 's/#PermitRootLogin prohibit-password/PermitRootLogin prohibit-password/' /etc/ssh/sshd_config
@ -27,5 +35,7 @@ RUN echo "export VISIBLE=now" >> /etc/profile
COPY create_ubuntu_user.sh /usr/local/bin/create_ubuntu_user.sh
RUN chmod +x /usr/local/bin/create_ubuntu_user.sh
COPY start_services.sh /usr/local/bin/start_services.sh
EXPOSE 22 5901
CMD ["/usr/sbin/sshd", "-D"]

View File

@ -0,0 +1,28 @@
PRE-REQUISTE:
./setup.sh
This will basically run:
docker network create frontend
docker network create backend
Create and bring up an Ubuntu instance with the following:
./create_user.sh john_doe 1001 2201 5901 your_secure_password
./connect_and_stream.sh
The ~ (home) directory is saved on the local disk in the ./data directory.
If you need to bring up a specific user:
docker-compose -f docker-compose.user_1001.yml build
docker-compose -f docker-compose.user_1001.yml up -d
OR MANUALLY:
Locally, type:
pulseaudio --load=module-native-protocol-tcp --exit-idle-time=-1 --daemon
export DISPLAY=:0
ssh -Y -C -p 2201 -L 4713:localhost:4713 -L 5000:localhost:5000 john_doe@localhost
On the remote container:
paplay /usr/share/sounds/alsa/Front_Center.wav
PULSE_SERVER=unix:/tmp/pulseaudio.socket firefox

55
connect_and_stream.sh Executable file
View File

@ -0,0 +1,55 @@
#!/bin/bash
# connect_and_stream.sh
SERVER_IP="localhost"
SSH_PORT="2201" # or whatever SSH port you're using
USERNAME="john_doe" # or the appropriate username
REMOTE_AUDIO_PORT="5000"
LOCAL_AUDIO_PORT="5000"
PULSE_PORT="4713"
# Function to find an available port
find_available_port() {
local port=$1
while ! nc -z localhost $port &>/dev/null; do
((port++))
done
echo $port
}
# Function to clean up background processes on script exit
cleanup() {
echo "Cleaning up..."
if [ ! -z "$SSH_PID" ]; then
kill $SSH_PID
fi
exit
}
# Set up the cleanup function to run on script exit
trap cleanup EXIT
# Find available ports
LOCAL_AUDIO_PORT=$(find_available_port $LOCAL_AUDIO_PORT)
PULSE_PORT=$(find_available_port $PULSE_PORT)
echo "Using local audio port: $LOCAL_AUDIO_PORT"
echo "Using PulseAudio port: $PULSE_PORT"
# Start SSH tunnel in the background
ssh -f -N -L ${LOCAL_AUDIO_PORT}:localhost:${REMOTE_AUDIO_PORT} -L ${PULSE_PORT}:localhost:4713 -p ${SSH_PORT} ${USERNAME}@${SERVER_IP}
SSH_PID=$!
# Wait a moment for the tunnel to establish
sleep 2
# Set PULSE_SERVER to use the forwarded port
export PULSE_SERVER=tcp:localhost:${PULSE_PORT}
# Start GStreamer client
#gst-launch-1.0 udpsrc uri=udp://localhost:${LOCAL_AUDIO_PORT} caps="application/x-rtp,media=audio,clock-rate=48000,encoding-name=OPUS" ! rtpopusdepay ! opusdec ! audioconvert ! autoaudiosink
gst-launch-1.0 udpsrc port=${LOCAL_AUDIO_PORT} caps="application/x-rtp,media=audio,clock-rate=48000,encoding-name=OPUS" ! rtpopusdepay ! opusdec ! audioconvert ! autoaudiosink
# The script will keep running until you stop it (Ctrl+C)
# When stopped, the cleanup function will kill the SSH tunnel

View File

@ -18,4 +18,19 @@ su - $USERNAME -c "mkdir -p ~/.vnc && x11vnc -storepasswd $PASSWORD ~/.vnc/passw
# Set up X11 forwarding for the user
echo "export DISPLAY=host.docker.internal:0" >> /home/$USERNAME/.bashrc
echo "User $USERNAME created with the provided password."
# Set up PulseAudio
su - $USERNAME -c "mkdir -p ~/.config/pulse"
su - $USERNAME -c "echo 'autospawn = yes' > ~/.config/pulse/client.conf"
su - $USERNAME -c "echo 'daemon-binary = /usr/bin/pulseaudio' >> ~/.config/pulse/client.conf"
su - $USERNAME -c "echo 'enable-shm = false' >> ~/.config/pulse/client.conf"
su - $USERNAME -c "echo 'enable-memfd = yes' >> ~/.config/pulse/client.conf"
su - $USERNAME -c "echo 'load-module module-native-protocol-unix' > ~/.config/pulse/default.pa"
su - $USERNAME -c "echo 'load-module module-native-protocol-tcp auth-anonymous=1' >> ~/.config/pulse/default.pa"
su - $USERNAME -c "echo 'load-module module-always-sink' >> ~/.config/pulse/default.pa"
# su - $USERNAME -c "echo 'load-module module-null-sink' >> ~/.config/pulse/default.pa"
# su - $USERNAME -c "echo 'load-module module-pipe-sink' >> ~/.config/pulse/default.pa"
su - $USERNAME -c "echo 'load-module module-virtual-sink sink_name=virtual_output' >> ~/.config/pulse/default.pa"
su - $USERNAME -c "echo 'set-default-sink virtual_output' >> ~/.config/pulse/default.pa"
echo "User $USERNAME created with the provided password and PulseAudio configured."

View File

@ -33,7 +33,7 @@ services:
- SYS_ADMIN
security_opt:
- seccomp:unconfined
command: ["/bin/bash", "-c", "/usr/local/bin/create_ubuntu_user.sh ${USER_NAME} ${PASSWORD} && /usr/sbin/sshd -D"]
command: ["/bin/bash", "-c", "/usr/local/bin/create_ubuntu_user.sh ${USER_NAME} ${PASSWORD} && /usr/local/bin/start_services.sh"]
networks:
frontend:

11
setup.sh Executable file
View File

@ -0,0 +1,11 @@
#!/bin/bash
# setup.sh
# Build the base image
docker build -t ubuntu_dev_env .
# Create networks
docker network create frontend
docker network create backend

View File

@ -1,13 +0,0 @@
#!/bin/bash
# Start SSH
/usr/sbin/sshd
# Start Xvfb
Xvfb :1 -screen 0 1024x768x16 &
# Start VNC server
vncserver :1 -geometry 1024x768 -depth 16 -SecurityTypes None
# Keep the container running
tail -f /dev/null

32
start_services.sh Executable file
View File

@ -0,0 +1,32 @@
#!/bin/bash
# Start D-Bus
mkdir -p /var/run/dbus
dbus-daemon --system --fork
# Start SSH
/usr/sbin/sshd
# Start Xvfb
Xvfb :1 -screen 0 1024x768x16 &
# Start VNC server
vncserver :1 -geometry 1024x768 -depth 16 -SecurityTypes None
# Start PulseAudio
su - $USER_NAME -c "pulseaudio --start -D --verbose"
# Set up virtual audio output
su - $USER_NAME -c "pactl unload-module module-null-sink || true"
su - $USER_NAME -c "pactl unload-module module-pipe-sink || true"
su - $USER_NAME -c "pactl load-module module-virtual-sink sink_name=virtual_output"
su - $USER_NAME -c "pactl set-default-sink virtual_output"
# Ensure all audio streams are moved to the virtual_output
su - $USER_NAME -c "pactl list short sink-inputs | cut -f1 | while read stream; do pactl move-sink-input \$stream virtual_output; done"
# Start audio streaming
su - $USER_NAME -c "gst-launch-1.0 pulsesrc device=virtual_output.monitor ! audioconvert ! opusenc ! rtpopuspay ! udpsink host=host.docker.internal port=5000 &"
# Keep the container running
tail -f /dev/null