PipeWire Media Session: Disable auto port switching on device connect

Intro

My 10 years old laptop has basically touch and look sensitive connectors, audio jack included. This means that the headphones plugged status is changed at random and with default settings in PulseAudio and PipeWire it will cause constant switching to speakers and I will be unable to enjoy my music (the soundcard is not great but the USB hub is also out of question since USB ports are also often touch sensitive).

PulseAudio

With PA there is a module module-switch-on-port-available in default.pa which can be commented to disable this functionality.

The comment around this module is not perfect, but the module name speaks for itself and on top of that, it is easy to find help online.

### Should be after module-*-restore but before module-*-detect
#load-module module-switch-on-port-available

PipeWire

With PipeWire the only thing I found is a mention in the Migration Guide was the mention that this feature is manager by Session manager.

Name Supported Alternative Notes
module-switch-on-port-available No Yes Session manager

Session manager

From my quick investigation there are two available session managers:

  • WirePlumber
  • Media Session

WirePlumber

This is their newer and recommended implementation, I am not using this thing yet. Maybe I will write something here after I will be forced to switch to it.

Media Session

This is an example implementation and it looks to be very basic but does the job for me.

To disable this unwanted behavior, edit pipewire/media-session.d/media-session.conf. This file is located at the install directory of PipeWire eg.

/usr/share/pipewire/media-session.d/media-session.conf

Read the header in this file to know where to copy it.

Than search for default-routes and comment all occurences of it. (You are free to experiment, this is how I have done it after some trial and error debugging).

The comment near this option in the default list also tells me nothing.

#default-routes         # restore default route

My resulting media-session.conf looks like this:

# Media session config file for PipeWire version "0.3.33" #
#
# Copy and edit this file in /etc/pipewire/media-session.d/
# for systemwide changes or in
# ~/.config/pipewire/media-session.d/ for local changes.

context.properties = {
    # Properties to configure the session and some
    # modules.
    #mem.mlock-all = false
    #support.dbus  = true
    #log.level     = 2
    #alsa.seq.name  = Midi-Bridge
}

context.spa-libs = {
    # Mapping from factory name to library.
    api.bluez5.*    = bluez5/libspa-bluez5
    api.alsa.*      = alsa/libspa-alsa
    api.v4l2.*      = v4l2/libspa-v4l2
    api.libcamera.* = libcamera/libspa-libcamera
}

context.modules = [
    #{   name = <module-name>
    #    [ args = { <key> = <value> ... } ]
    #    [ flags = [ [ ifexists ] [ nofail ] ]
    #}
    #
    # Loads a module with the given parameters.
    # If ifexists is given, the module is ignored when it is not found.
    # If nofail is given, module initialization failures are ignored.
    #
    # Uses RTKit to boost the data thread priority.
    {   name = libpipewire-module-rtkit
        args = {
            #nice.level   = -11
            #rt.prio      = 88
            #rt.time.soft = 2000000
            #rt.time.hard = 2000000
        }
        flags = [ ifexists nofail ]
    }

    # The native communication protocol.
    {   name = libpipewire-module-protocol-native }

    # Allows creating nodes that run in the context of the
    # client. Is used by all clients that want to provide
    # data to PipeWire.
    {   name = libpipewire-module-client-node }

    # Allows creating devices that run in the context of the
    # client. Is used by the session manager.
    {   name = libpipewire-module-client-device }

    # Makes a factory for wrapping nodes in an adapter with a
    # converter and resampler.
    {   name = libpipewire-module-adapter }

    # Allows applications to create metadata objects. It creates
    # a factory for Metadata objects.
    {   name = libpipewire-module-metadata }

    # Provides factories to make session manager objects.
    {   name = libpipewire-module-session-manager }
]

session.modules = {
    # These are the modules that are enabled when a file with
    # the key name is found in the media-session.d config directory.
    # the default bundle is always enabled.

    default = [
        flatpak                 # manages flatpak access
        portal                  # manage portal permissions
        v4l2                    # video for linux udev detection
        #libcamera              # libcamera udev detection
        suspend-node            # suspend inactive nodes
        policy-node             # configure and link nodes
        #metadata               # export metadata API
        #default-nodes          # restore default nodes
        #default-profile        # restore default profiles
        #default-routes         # restore default route
        #streams-follow-default # move streams when default changes
        #alsa-seq               # alsa seq midi support
        #alsa-monitor           # alsa udev detection
        #bluez5                 # bluetooth support
        #bluez5-autoswitch      # automatic bluetooth HSP/HFP profile switch
        #restore-stream         # restore stream settings
        #logind                 # systemd-logind seat support
    ]
    with-audio = [
        metadata
        default-nodes
        default-profile
#        default-routes
        alsa-seq
        alsa-monitor
    ]
    with-alsa = [
        with-audio
    ]
    with-jack = [
        with-audio
    ]
    with-pulseaudio = [
        with-audio
        bluez5
        bluez5-autoswitch
        logind
        restore-stream
        streams-follow-default
    ]
}

Conclusion

While I am still using deprecated / example session manager I somehow forced it to do what I want. This solution could also affect some other features of which I have no knowledge of. So proceed at you own risk.

Articles from blogs I follow:

Richard Stallman's political discourse on sex

Richard Stallman, the founder of the Free Software Foundation, has been subject to numerous allegations of misconduct. He stepped down in 2019, and following his re-instatement in 2021, a famous open letter was published in which numerous organizations and i…

via Drew DeVault's blog November 25, 2023

Upgrading to FreeBSD 14 - how to fix a broken BIOS bootcode

A lot of people running ZFS zroot have managed to break their FreeBSD systems upgrading from 13.2 to the new 14.0 release because of a broken BIOS bootcode. In this tutorial I'll show you how you can fix that without having to reinstall.

via unixsheikh.com November 22, 2023

C++ Guidelines

C++ is definitely a language that has Lots of Ways to do It – kind of like Perl’s TIMTOWTSAC. A consequence is that when writing code, you need to think about which way to do things. When context-switching between projects, employers, or what-have-you, yo…

via [bobulate] November 21, 2023

Generated by openring