Last active
February 2, 2026 12:46
-
-
Save git58/a679486ca253b0032025cc8c74770e9f to your computer and use it in GitHub Desktop.
Fix viper4android on Manjaro KDE Plasma 6 (PipeWire)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/bash | |
| ############################################################################### | |
| # Viper4Linux Auto-Routing Supervisor Script | |
| # ------------------------------------------ | |
| # This script performs three major tasks: | |
| # 1. Creates and initializes the Viper4Linux audio processing pipeline. | |
| # 2. Periodically monitors PipeWire routing and configuration changes. | |
| # 3. Automatically restores correct audio links if PipeWire breaks them. | |
| # | |
| # The script is intended to run from KDE autostart without opening a terminal. | |
| ############################################################################### | |
| # Short initial delay to allow PipeWire and PulseAudio compatibility layer to start. | |
| sleep 2 | |
| ############################################################################### | |
| # 1. Ensure the virtual sink "viper" exists | |
| ############################################################################### | |
| # Check if a sink named "viper" already exists. | |
| # If not, create a null-sink that will act as the input for ViperFX. | |
| if ! pactl list short sinks | grep -q "viper"; then | |
| pactl load-module module-null-sink \ | |
| sink_name=viper \ | |
| sink_properties=device.description="Viper4Linux" | |
| fi | |
| # Set the newly created sink as the default sink and source. | |
| # This reduces the chance of PipeWire auto-routing audio elsewhere. | |
| pactl set-default-sink viper | |
| pactl set-default-source viper.monitor | |
| ############################################################################### | |
| # 2. Wait until the monitor source appears | |
| ############################################################################### | |
| # PipeWire may take some time to register "viper.monitor". | |
| # We wait until it becomes available before launching the processing pipeline. | |
| while ! pactl list short sources | grep -q "viper.monitor"; do | |
| sleep 0.2 | |
| done | |
| ############################################################################### | |
| # 3. Kill any old gst-launch processes to avoid duplicates | |
| ############################################################################### | |
| killall -9 gst-launch-1.0 2>/dev/null | |
| ############################################################################### | |
| # 4. Load ViperFX parameters from config file | |
| ############################################################################### | |
| CONFIG_FILE="$HOME/.config/viper4linux/audio.conf" | |
| # If the config file exists, normalize whitespace and convert it into a single line. | |
| # Example: "vb-gain = 800" → "vb-gain=800" | |
| if [ -f "$CONFIG_FILE" ]; then | |
| VIPER_PARAMS=$(sed -e 's/[[:space:]]*=[[:space:]]*/=/g' "$CONFIG_FILE" | tr '\n' ' ') | |
| else | |
| # Fallback parameters if no config file is found. | |
| VIPER_PARAMS="fx-enable=true vb-enable=true vb-gain=800" | |
| fi | |
| ############################################################################### | |
| # 5. Start the audio processing pipeline | |
| ############################################################################### | |
| # Launch gst-launch in the background: | |
| # - pulsesrc reads from viper.monitor | |
| # - viperfx applies audio effects | |
| # - pulsesink outputs to the real hardware device | |
| gst-launch-1.0 \ | |
| pulsesrc device=viper.monitor ! \ | |
| viperfx $VIPER_PARAMS ! \ | |
| pulsesink device="alsa_output.pci-0000_00_1f.3.analog-stereo" & | |
| # Give gst-launch time to initialize its node in PipeWire. | |
| sleep 1 | |
| ############################################################################### | |
| # 6. Function to restore correct PipeWire links | |
| ############################################################################### | |
| restore_links() { | |
| # This function re-establishes the correct audio routing. | |
| # It is safe to call repeatedly; PipeWire will ignore duplicate links. | |
| pw-link viper.monitor:monitor_FL viperfx:input_FL | |
| pw-link viper.monitor:monitor_FR viperfx:input_FR | |
| pw-link viperfx:output_FL alsa_output.pci-0000_00_1f.3.analog-stereo:playback_FL | |
| pw-link viperfx:output_FR alsa_output.pci-0000_00_1f.3.analog-stereo:playback_FR | |
| } | |
| # Initial link restoration | |
| restore_links | |
| ############################################################################### | |
| # 7. Start the GUI | |
| ############################################################################### | |
| # Launch the Viper4Linux GUI in the background. | |
| viper4linux-gui & | |
| ############################################################################### | |
| # 8. Background monitoring loop | |
| ############################################################################### | |
| # This loop runs forever in the background and periodically checks: | |
| # - Whether gst-launch is still running. | |
| # - Whether the config file has changed. | |
| # - Whether PipeWire links are still correct. | |
| # - Whether viper.monitor still exists. | |
| # | |
| # If anything is wrong, the script automatically repairs it. | |
| ############################################################################### | |
| # Save initial config checksum to detect changes. | |
| LAST_CONF_HASH=$(md5sum "$CONFIG_FILE" 2>/dev/null | awk '{print $1}') | |
| ( | |
| while true; do | |
| ########################################################################### | |
| # Check if gst-launch is still running | |
| ########################################################################### | |
| if ! pgrep -x "gst-launch-1.0" >/dev/null; then | |
| # Restart the pipeline if it crashed or was killed. | |
| gst-launch-1.0 \ | |
| pulsesrc device=viper.monitor ! \ | |
| viperfx $VIPER_PARAMS ! \ | |
| pulsesink device="alsa_output.pci-0000_00_1f.3.analog-stereo" & | |
| sleep 1 | |
| restore_links | |
| fi | |
| ########################################################################### | |
| # Check if the config file has changed | |
| ########################################################################### | |
| CURRENT_HASH=$(md5sum "$CONFIG_FILE" 2>/dev/null | awk '{print $1}') | |
| if [ "$CURRENT_HASH" != "$LAST_CONF_HASH" ]; then | |
| # Reload parameters and restart gst-launch with new settings. | |
| LAST_CONF_HASH="$CURRENT_HASH" | |
| killall -9 gst-launch-1.0 2>/dev/null | |
| VIPER_PARAMS=$(sed -e 's/[[:space:]]*=[[:space:]]*/=/g' "$CONFIG_FILE" | tr '\n' ' ') | |
| gst-launch-1.0 \ | |
| pulsesrc device=viper.monitor ! \ | |
| viperfx $VIPER_PARAMS ! \ | |
| pulsesink device="alsa_output.pci-0000_00_1f.3.analog-stereo" & | |
| sleep 1 | |
| restore_links | |
| fi | |
| ########################################################################### | |
| # Check if PipeWire links are still correct | |
| ########################################################################### | |
| # If any link is missing, restore all links. | |
| if ! pw-link -l | grep -q "viper.monitor:monitor_FL.*viperfx:input_FL"; then restore_links; fi | |
| if ! pw-link -l | grep -q "viperfx:output_FL.*analog-stereo:playback_FL"; then restore_links; fi | |
| ########################################################################### | |
| # Check if viper.monitor still exists | |
| ########################################################################### | |
| if ! pactl list short sources | grep -q "viper.monitor"; then | |
| # Recreate the sink if PipeWire removed it. | |
| pactl load-module module-null-sink \ | |
| sink_name=viper \ | |
| sink_properties=device.description="Viper4Linux" | |
| pactl set-default-sink viper | |
| pactl set-default-source viper.monitor | |
| sleep 1 | |
| restore_links | |
| fi | |
| ########################################################################### | |
| # Sleep before next check | |
| ########################################################################### | |
| sleep 3 | |
| done | |
| ) & | |
| # End of script |
Author
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment




Changelog for v1.2
Viper4Linux Auto‑Routing Supervisor Script — Документация
Общее описание
Этот скрипт является автоматическим надзорным механизмом для аудиопайплайна Viper4Linux, работающего поверх PipeWire. Его задача — обеспечить стабильную работу цепочки:
PipeWire иногда нарушает маршрутизацию, пересоздаёт узлы или сбрасывает соединения. Скрипт предотвращает такие сбои, автоматически восстанавливая корректные связи и перезапуская аудиопроцессинг при необходимости.
Скрипт предназначен для автозапуска в KDE Plasma и работает полностью в фоне, без открытия терминала.
Основные функции скрипта
1. Создание и инициализация виртуального sink
viperСкрипт проверяет, существует ли виртуальный sink с именем
viper.Если нет — создаёт его через
module-null-sink.Этот sink служит входной точкой для ViperFX.
Также скрипт устанавливает:
viperкак default sinkviper.monitorкак default sourceЭто уменьшает вероятность того, что PipeWire переназначит маршруты.
2. Ожидание появления
viper.monitorPipeWire может задерживать регистрацию монитор‑источника.
Скрипт ждёт, пока
viper.monitorне появится, прежде чем запускать обработку звука.3. Удаление старых процессов
gst-launchПеред запуском новой цепочки скрипт убивает все старые экземпляры
gst-launch-1.0, чтобы избежать дублирования потоков.4. Загрузка параметров ViperFX
Скрипт читает конфигурационный файл:
и преобразует строки вида:
в формат:
Если конфиг отсутствует — используются параметры по умолчанию.
5. Запуск аудиопайплайна через
gst-launchСкрипт запускает следующую цепочку:
Запуск выполняется в фоне.
6. Восстановление PipeWire‑соединений
Функция
restore_links()создаёт необходимые соединения:viper.monitor→viperfxviperfx→ ALSA‑sinkPipeWire игнорирует дубликаты, поэтому функция безопасна при повторных вызовах.
7. Запуск графического интерфейса Viper4Linux
GUI запускается в фоне и не влияет на работу пайплайна.
Фоновый мониторинг (основная логика скрипта)
Скрипт запускает бесконечный цикл, который каждые 3 секунды проверяет:
1. Жив ли процесс
gst-launchЕсли он упал:
2. Изменился ли конфигурационный файл
Скрипт вычисляет MD5‑хеш файла.
Если конфиг изменился:
gst-launchперезапускается3. На месте ли PipeWire‑соединения
Если хотя бы одно соединение отсутствует — вызывается
restore_links().4. Существует ли
viper.monitorЕсли PipeWire удалил виртуальный sink:
viperПоведение при сбоях
Скрипт автоматически:
Он работает как самовосстанавливающийся сервис, но без systemd.
Преимущества данного решения
✔ Полностью автономен
Не требует systemd, работает из автозагрузки KDE.
✔ Самовосстанавливающийся
Любой сбой в пайплайне автоматически исправляется.
✔ Устойчив к изменениям PipeWire
PipeWire может пересоздавать узлы — скрипт это компенсирует.
✔ Минимальная задержка реакции
Проверка каждые 3 секунды.
✔ Безопасен
Не ломает существующие соединения, только восстанавливает нужные.
Когда использовать этот скрипт
Он идеально подходит для систем, где: