SIP Audio – James Batchelor https://james-batchelor.com Useful I.T & VoIP Ramblings Sat, 19 Jul 2025 19:01:32 +0000 en-US hourly 1 https://wordpress.org/?v=6.8.5 https://james-batchelor.com/wp-content/uploads/2025/05/cropped-cropped-logo-jb-202505-32x32.png SIP Audio – James Batchelor https://james-batchelor.com 32 32 SIP Radio https://james-batchelor.com/index.php/2025/09/17/sip-radio/ Wed, 17 Sep 2025 19:00:00 +0000 https://james-batchelor.com/?p=1044 Continue reading "SIP Radio"]]> In a previous post, I hinted at the possibility of replacing a “smart” speaker with readily placed VoIP phones as a way to play radio around the house.

This would kind of make sense, phones use the RTP protocol for audio is designed for real-time communication and so, naturally sync with each other in a local network.

As a proof of concept, I wanted to create a service that allowed me to “dial-in” to a radio stream on demand…

Initial thoughts was to just to pipe a continuous radio stream to an extension. However, in addition to the waste of bandwidth, any network disruptions would essentially kill the stream without recovery. Therefore, a play on-demand service would help keep the stream fresh whilst saving bandwidth at idle.

My preferred radio for testing is Kerrang radio, I get the URL’s for radio feed via this site and downloading the playlist .pls file, then opening the file in a text editor to extract the actual stream URL.

Baresip Setup

Similar to the earlier project in piping audio from a Raspberry Pi to SIP, a minimal install of Baresip will be used to handle the SIP element and added as a system service in a mostly similar way.

To give the script some context on when to play on demand, we need a log of baresip’s output.

In the service configuration file, under [service] change the following line:

ExecStart=/usr/bin/baresip

to:

ExecStart=/bin/bash -c "/usr/bin/baresip > /path/to/sipaudio.log 2>&1"

This will now run the application and send all output to a sipaudio.log file for processing by the script.

Script

The script will read the log file for any newly established calls and add them to a counter to establish how many calls are active, while the call count is greater than zero, trigger the radio stream.

Similarly, call terminations are also registered and affect the active_calls variable.

The goal is to ensure the stream is only triggered when the first active call is dectected, and only stop the stream when the last remaining call is cleared down.

For example, if Phone A calls in, the stream is triggered and starts playing. Then, phone B also calls in and hears the established stream. If Phone A was to hangup, we’ll need to continue the stream for phone B (i.e not latching to the phone that triggered the stream), but if phone B also hangs up, the stream is stopped as there’s nothing there to listen.

Create the script file and add the following:

#!/bin/bash

# Path to Baresip log file
LOG_FILE="/path/to/sipaudio.log"
STREAM_URL="http://edge-bauerall-01-gos2.sharp-stream.com/kerrang.mp3?aw_0_1st.skey=1736072895"

# Track active calls
active_calls=0
mpv_pid=""

start_stream() {
    if [[ -z $mpv_pid ]]; then
        echo "Starting stream..."
        mpv "$STREAM_URL" &
        mpv_pid=$!
    else
        echo "Stream is already running."
    fi
}

stop_stream() {
    if [[ -n $mpv_pid ]]; then
        echo "Stopping stream..."
        kill $mpv_pid
        wait $mpv_pid 2>/dev/null
        mpv_pid=""
    else
        echo "Stream is not running."
    fi
}

monitor_calls() {
    echo "Monitoring Baresip log for call events..."
    tail -Fn0 "$LOG_FILE" | while read -r line; do
        if [[ "$line" == *"Call established"* ]]; then
            ((active_calls++))
            echo "Call incoming. Active calls: $active_calls"
            if [[ $active_calls -eq 1 ]]; then
                start_stream
            fi
        elif [[ "$line" == *"session closed"* ]]; then
            ((active_calls--))
            echo "Call ended. Active calls: $active_calls"
            if [[ $active_calls -le 0 ]]; then
                active_calls=0
                stop_stream
            fi
        fi
    done
}

# Start monitoring calls
monitor_calls

Make the file executatble with:

chmod +x /path/to/filename.sh

Service

This can be ran via the terminal/SSH, but for ease of use and reboot survival, lets create a service for the script.

Create and edit a service file:

sudo nano /etc/systemd/system/sip.radio.service

Add the following to the new service file:

[Unit]
Description=Kerrang Radio Stream
After=sound.target network.target

[Service]
ExecStart=/path/to/filename.sh
Restart=always
RestartSec=10
User=pi
WorkingDirectory=/home/pi
StandardOutput=journal
StandardError=journal
Environment=HOME=/home/pi
Environment=XDG_RUNTIME_DIR=/run/user/1000

[Install]
WantedBy=multi-user.target

When saved, reload services:

sudo systemctl daemon-reload

Start the service and enable it to start at boot:

sudo systemctl enable --now sipradio

Now a test call can be made to the baresip extension, and hopefully the radio will be though in a second or two.

Summary

Since originally starting this in March, the script and SIP endpoint has been idle for a few months, but seeing if it still works while writing this, the stream fired right up on first asking.

I would like to significantly reduce my “smart” speaker density, as they are almost exclusivley music players at this point due to the frustration in using them for anything else (even playing music is a challenge at times), but are always listening in.

To put this theory into production will require both opus capable phone hardware and decent wired/bluetooth speakers with connectivity inbetween.

I wonder if a Pi Zero W2 could come to a cheap option rescue?

]]>
SIP device as Pi Audio Output https://james-batchelor.com/index.php/2025/02/16/sip-device-as-pi-audio-output/ Sun, 16 Feb 2025 16:55:45 +0000 https://james-batchelor.com/?p=992 Continue reading "SIP device as Pi Audio Output"]]> In my Development Den (the spare room) I have a Raspberry Pi 4 setup with a monitor for use as a quick reference station when working on nearby devices.

With no speakers connected this can sometimes pose an issue when trying to follw a tutorial video, and when I do need audio, a Bluetooth speaker is never around.

There is a SIP phone next to the Pi on my desk, and so I thought; that has a decent network connected speaker, why not use that?

This is what ensued…

The idea is to have a SIP endpoint running as a service on the Pi in auto-answer mode. This will allow a desk phone to dial the Pi extension and receive the Pi’s audio through the loudspeaker.

The Pi is running stock Raspbian Bullseye with the desktop environment.

SIP Endpoint

Baresip looks a good choice for this project due to its modularity.

As this will be a service running in the background, only the core module of Baresip needs to be installed:

sudo apt install --no-install-recommends baresip-core

When installed, run the program briefly to have it create its default configuration files:

baresip

This will create the default template files in a .baresip directory within the home folder. We’ll need to edit the accounts and config files to get it to a call answering state.

Starting with the accounts file:

nano .baresip/accounts

Add the following line to the bottom of the file:

<sip:{endpoint}@{sip_server}>;auth_pass={sip_secret};answermode=auto

Where:
{endpoint} – SIP extension number
{sip_server} – IP/hostname of the PBX
{sip_secret} – Extension password

Answermode flag has been added to allow calls to this extension to be answered automatically.

After the accounts file, move onto the config:

nano .baresip/config

This file can be left as default, however a few quality-of-life improvements will be made…

Uncomment the following lines:

module                  opus.so
module                  g722.so

These allow the use of the higher quality codecs commonly in use; g722 is the elder and while it offers higher quality from a phone call audio point of view, may fall short for music. Opus is the newer and can be configured for excellent quality overall, but being newer may not be an available choice on older phones.

If Opus is available, the bitrate can be increased via this line further down the config file (higher bitrate, higher audio quality):

opus_bitrate            28000 # 6000-510000

Make sure both you SIP devices and PBX are capable and configured to offer these codecs at the highest priority.

Testing

Good time for a sanity check, for this an audio file or stream playing through VLC, or any source of audio will do.

Run the application in the terminal

baresip

And make a call to its extension, you should see output in the terminal, and hear the audio through the phone.

If it’s successful, a service can be created to have this running in the background on startup…

Create Service

To allow baresip to start at boot, its best to create a service for it and restart it if it ever stops.

Create and edit a service file:

sudo nano /etc/systemd/system/sipaudio.service

Add the following to this file:

[Unit]
Description=SIP endpoint for Pi audio
After=sound.target network.target

[Service]
ExecStart=/usr/bin/baresip
Restart=always
User=pi
WorkingDirectory=/home/{username}
StandardOutput=journal
StandardError=journal
Environment=HOME=/home/{username}
Environment=XDG_RUNTIME_DIR=/run/user/1000

[Install]
WantedBy=multi-user.target

When saved, reload services:

sudo systemctl daemon-reload

Start the service and enable it to start at boot:

sudo systemctl enable --now sipaudio

With some audio playing, try another call to make sure its answering and picking up audio from the desktop environment.

Conclusion

It’s a niche solution for those who have an audio-less Pi and a SIP phone next to it, but the results are plesently convenient for those rare times when audio is needed.

My accompanying desk phone (Yealink T46S) only offers g722 has the higher codec, but still is perfectly fine for speech output and fine (not great) for audio. I’m sure using Opus at the higher bitrate will put it on par with some of the streaming services. Afterall, YouTube uses opus as audio for its videos, as noted by the “stats for nerds” section:

]]>