Fórum Root.cz
Hlavní témata => Vývoj => Téma založeno: exkalibr 14. 12. 2025, 09:50:46
-
Dobrý den,
snažil jsem se včera, a dnes ráno rozjet skript, protože chci v audacity zaznamenat svůj rozhovor s GPT. Ale marně, nepodařilo se mi to. Včera se mi akorád povedlo slyšet svůj hlas ve sluchátkách a donutit GPT, aby dal příkaz jak to zeslabit na cca 42%. Nahrával se zvuk z přehrávané písničky ve vlc ale písničku jsem neslyšel během toho aktuálního přehrávání přes vlc. Myslím nefungovaly nahlas ty systémové zvuky abych to slyšel ve sluchátkách. A můj hlas se nepovedlo nahrát.
Mám Mint 21.3 xFce.
Skript co jsem od něho dostal:
#!/usr/bin/env bash
set -euo pipefail
# ====== CONFIG ======
MIC_PATTERN='input' # pattern (lowercase) který hledá v 2. sloupci sources
NULL_SINK_NAME='MixSink' # null-sink pro nahrávání (mix)
VIRTUAL_SRC_NAME='MixSource' # virtuální zdroj pro Audacity (monitor null-sinku)
MONITOR_ATTEN='42%' # poslechová hlasitost mikrofonu pro sluchátka
ACTIVATE_TRIES=60 # kolikrát čekat na vznik sink-input (0.1s krok)
SLEEP_STEP=0.1
# ====== helper ======
cmd_exists() { command -v "$1" >/dev/null 2>&1; }
# ====== najdi fyzický sink (prefer RUNNING, jinak první) ======
DEFAULT_SINK=$(pactl list short sinks \
| sed -E 's/[[:space:]]+/ /g' \
| awk '{
if($4=="RUNNING" && !found){ print $2; found=1; next }
if(!first) first=$2
}
END{ if(!found) print first }' \
|| true)
if [ -z "$DEFAULT_SINK" ]; then
echo "Nelze zjistit fyzický sink." >&2
exit 1
fi
# ====== najdi mikrofon (preferuj sources, 2. sloupec obsahuje 'input') ======
MIC_SRC=$(pactl list short sources \
| sed -E 's/[[:space:]]+/ /g' \
| awk -v pat="$MIC_PATTERN" 'BEGIN{lc_pat=tolower(pat)}
{
s=tolower($2)
if(s ~ lc_pat){ print $2; exit }
if(!first) first=$2
}
END{ if(NR>0 && !found) print first }' \
|| true)
if [ -z "$MIC_SRC" ]; then
echo "Nenalezen source mikrofonu (pattern: $MIC_PATTERN)." >&2
exit 1
fi
echo "Fyzický výstup (selected): $DEFAULT_SINK"
echo "Mikrofon (selected): $MIC_SRC"
# ====== cleanup předchozích modulů vztahujících se k našim jménům / mic ======
echo "Odstraňuji předchozí modul-loopback / MixSink / MixSource (pokud existují)..."
pactl list short modules | while read -r id name rest; do
if [ "$name" = "module-loopback" ] && echo "$rest" | grep -q -F "$MIC_SRC"; then
echo " unload-module $id (loopback referející mic)"
pactl unload-module "$id" || true
elif echo "$rest" | grep -q -F "$NULL_SINK_NAME"; then
echo " unload-module $id (referuje $NULL_SINK_NAME)"
pactl unload-module "$id" || true
elif echo "$rest" | grep -q -F "$VIRTUAL_SRC_NAME"; then
echo " unload-module $id (referuje $VIRTUAL_SRC_NAME)"
pactl unload-module "$id" || true
fi
done
# také pro jistotu odpojit moduly přes přesný řetězec jména
pactl list short modules | awk -v n1="$NULL_SINK_NAME" -v n2="$VIRTUAL_SRC_NAME" '$0 ~ n1 || $0 ~ n2 {print $1}' \
| xargs -r -n1 -I{} pactl unload-module {} >/dev/null 2>&1 || true
# ====== vytvoř null-sink MixSink pokud neexistuje ======
if pactl list short sinks | sed -E 's/[[:space:]]+/ /g' | awk -v n="$NULL_SINK_NAME" '$2==n{print; exit}' >/dev/null 2>&1; then
echo "Null-sink $NULL_SINK_NAME existuje (nebudu znovu vytvářet)."
else
echo "Vytvářím null-sink $NULL_SINK_NAME..."
pactl load-module module-null-sink sink_name="$NULL_SINK_NAME" sink_properties=device.description="$NULL_SINK_NAME"
fi
NULL_SINK_IDX=$(pactl list short sinks | sed -E 's/[[:space:]]+/ /g' | awk -v n="$NULL_SINK_NAME" '$2==n{print $1; exit}' || true)
echo "MixSink index: ${NULL_SINK_IDX:-<unknown>}"
# ====== vytvoř loopback mikrofon -> MixSink (pro nahrávání Audacity) ======
echo "Vytvářím loopback: $MIC_SRC -> $NULL_SINK_NAME ..."
RECORD_LOOP_MOD=$(pactl load-module module-loopback source="$MIC_SRC" sink="$NULL_SINK_NAME" latency_msec=1 || true)
if [ -z "$RECORD_LOOP_MOD" ]; then
echo "Chyba: nelze vytvořit record-loop." >&2
exit 1
fi
echo "Record loop module id: $RECORD_LOOP_MOD"
# ====== probuď mic dočasným čtením (pokud dostupné) ======
ACT_PID=""
if cmd_exists parec; then
parec -d "$MIC_SRC" >/dev/null 2>&1 &
ACT_PID=$!
echo "Spuštěn temporary parec pid=$ACT_PID"
elif cmd_exists pw-cat; then
pw-cat -d "$MIC_SRC" >/dev/null 2>&1 &
ACT_PID=$!
echo "Spuštěn temporary pw-cat pid=$ACT_PID"
else
echo "parec/pw-cat nenalezeny — pokud bude MIC SUSPENDED, nahrávání ho probudí."
fi
# ====== počkej na sink-input pro record loop (nezbytné pro případné nastavení) ======
REC_SINK_INPUT=""
for i in $(seq 1 $ACTIVATE_TRIES); do
REC_SINK_INPUT=$(pactl list short sink-inputs | sed -E 's/[[:space:]]+/ /g' | awk -v m="$RECORD_LOOP_MOD" '$3==m{print $1; exit}' || true)
if [ -n "$REC_SINK_INPUT" ]; then break; fi
sleep "$SLEEP_STEP"
done
if [ -n "$REC_SINK_INPUT" ]; then
echo "Record sink-input id: $REC_SINK_INPUT"
else
echo "Poznámka: record sink-input zatím nevznikl (Audacity při spuštění nahrávání ho probudí)."
fi
# ====== vytvoř monitorovací loopback: mic -> fyzický sink (pro poslech), a ztlum jej ======
echo "Vytvářím monitor loopback: $MIC_SRC -> $DEFAULT_SINK (attenuated monitoring)..."
MON_LOOP_MOD=$(pactl load-module module-loopback source="$MIC_SRC" sink="$DEFAULT_SINK" latency_msec=1 || true)
if [ -n "$MON_LOOP_MOD" ]; then
echo "Monitor loop module id: $MON_LOOP_MOD"
MON_SINK_INPUT=""
for i in $(seq 1 $ACTIVATE_TRIES); do
MON_SINK_INPUT=$(pactl list short sink-inputs | sed -E 's/[[:space:]]+/ /g' | awk -v m="$MON_LOOP_MOD" '$3==m{print $1; exit}' || true)
if [ -n "$MON_SINK_INPUT" ]; then
pactl set-sink-input-volume "$MON_SINK_INPUT" "$MONITOR_ATTEN"
echo "Monitor sink-input $MON_SINK_INPUT nastavena na $MONITOR_ATTEN"
break
fi
sleep "$SLEEP_STEP"
done
if [ -z "$MON_SINK_INPUT" ]; then
echo "Poznámka: monitor sink-input nevznikl — probuď mic nahráváním v Audacity a pak spusť 'pactl list short sink-inputs' pro nastavení."
fi
else
echo "Nepodařilo se vytvořit monitor loopback." >&2
fi
# ====== vytvoř virtuální zdroj (monitor MixSink) pro Audacity ======
if pactl list short sources | sed -E 's/[[:space:]]+/ /g' | awk -v n="$VIRTUAL_SRC_NAME" '$2==n{print $2; exit}'; then
echo "Virtual source $VIRTUAL_SRC_NAME již existuje."
else
echo "Vytvářím virtual source $VIRTUAL_SRC_NAME z $NULL_SINK_NAME.monitor..."
pactl load-module module-virtual-source source_name="$VIRTUAL_SRC_NAME" source_properties=device.description="$VIRTUAL_SRC_NAME" master="$NULL_SINK_NAME.monitor"
fi
VIRT_SRC_IDX=$(pactl list short sources | sed -E 's/[[:space:]]+/ /g' | awk -v n="$VIRTUAL_SRC_NAME" '$2==n{print $1; exit}' || true)
echo "Virtual source index: ${VIRT_SRC_IDX:-<unknown>}"
# ====== cleanup activator ======
if [ -n "${ACT_PID:-}" ]; then
sleep 0.1
kill "$ACT_PID" >/dev/null 2>&1 || true
fi
echo
echo "HOTOVO: Audacity vyber zdroj '$VIRTUAL_SRC_NAME' (Mix of system apps + mic at full volume)."
echo "Pro zahrnutí VLC do záznamu: přesuň jeho sink-input do $NULL_SINK_NAME nebo duplikuj fyzický monitor do MixSink."
Skript pro unload
#!/usr/bin/env bash
set -euo pipefail
# ===== Nastavení =====
VIRTUAL_SRC_NAME='MixSource' # virtuální zdroj pro Audacity
NULL_SINK_NAME='MixSink' # null-sink pro smíchání zvuků
# ===== Odpojit všechny loopback moduly =====
echo "Odpojuji všechny loopbacky..."
while IFS= read -r id; do
if pactl unload-module "$id"; then
echo "Odpojen loopback modul $id"
else
echo "Chyba při odpojování loopback modulu $id" >&2
fi
done < <(pactl list short modules | awk '/module-loopback/ {print $1}')
# ===== Odstranit virtuální zdroj =====
if pactl list short sources | awk '{print $2}' | grep -Fxq "$VIRTUAL_SRC_NAME"; then
echo "Odstraňuji virtuální zdroj '$VIRTUAL_SRC_NAME'..."
MODULE_ID=$(pactl list short modules | awk -v src="$VIRTUAL_SRC_NAME" '$0 ~ src {print $1; exit}')
if [ -n "$MODULE_ID" ]; then
pactl unload-module "$MODULE_ID" && echo "Odpojen virtuální zdroj '$VIRTUAL_SRC_NAME'"
fi
fi
# ===== Odstranit null-sink =====
if pactl list short sinks | awk '{print $2}' | grep -Fxq "$NULL_SINK_NAME"; then
echo "Odstraňuji null-sink '$NULL_SINK_NAME'..."
MODULE_ID=$(pactl list short modules | awk -v sink="$NULL_SINK_NAME" '$0 ~ sink {print $1; exit}')
if [ -n "$MODULE_ID" ]; then
pactl unload-module "$MODULE_ID" && echo "Odpojen null-sink '$NULL_SINK_NAME'"
fi
fi
echo "Hotovo. Všechny loopbacky, virtuální zdroje a null-sinky odstraněny."
A protože přestaly fungovat zvuky - přehrávání, tak je ještě třeba to opravit
systemctl --user restart pipewire pipewire-pulse wireplumber || systemctl --user restart pipewire pipewire-pulse pulseaudio || true
Pomůžete mi s tím prosím?
-
Nelze očekávat, že AI dá na první dobrou skript, který složitě parsuje textové výstupy nějakých utilitek. Např. tohle peklo:
pactl list short modules | awk -v n1="$NULL_SINK_NAME" -v n2="$VIRTUAL_SRC_NAME" '$0 ~ n1 || $0 ~ n2 {print $1}' \
| xargs -r -n1 -I{} pactl unload-module {} >/dev/null 2>&1 || true
Opravdu myslíš, že tu budou lidi ručně kontrolovat, zda je taková pipeline vygenerovaná správně?
Pokud to po AI chceš, pak jí musíš dodat kvalitní podklady, ze kterých může vycházet se svými znalostmi. Minimálně konkrétní texty výstupů těch volání pactl. Samozřejmě záleží na LLM modelu, zda to vůbec umí.
Rovněž bych po AI chtěl, aby napsala skript tak, aby když přidáš parametr bashe -x a nakopíruješ do ní výsledný debug výstup skriptu, aby z toho dokázala po sobě zkontrolovat správnou funkci, příp. najít chybu.
Věřím, že dobrý LLM model s dobrým vedením takový skript napíše bez problémů, ale musí se držet pod kontrolou a musí mít k dispozici vhodné vstupní podklady.
A nebo po AI chtěj jen jednotlivé bloky/klíčové řádky a skládej si to do skriptu sám, samozřejmě po ručním otestování každého bloku.
-
Dodal jsem to GPT po krokách:
$ pactl list short sources
133 alsa_output.pci-0000_00_1b.0.pro-output-0.monitor PipeWire s32le 2 ch 48000 Hz SUSPENDED
134 alsa_output.pci-0000_00_1b.0.pro-output-3.monitor PipeWire s32le 8 ch 48000 Hz SUSPENDED
135 alsa_input.pci-0000_00_1b.0.pro-input-0 PipeWire s32le 2 ch 48000 Hz RUNNING
user@Toshi:~/Bash$ pactl list short sinks
133 alsa_output.pci-0000_00_1b.0.pro-output-0 PipeWire s32le 2 ch 48000 Hz SUSPENDED
134 alsa_output.pci-0000_00_1b.0.pro-output-3 PipeWire s32le 8 ch 48000 Hz SUSPENDED
plus případné chybové hlášky.
Když se to spustí:
$ ./pulse-zeslab.sh
Fyzický výstup (selected): alsa_output.pci-0000_00_1b.0.pro-output-0
Mikrofon (selected): alsa_input.pci-0000_00_1b.0.pro-input-0
alsa_output.pci-0000_00_1b.0.pro-output-0.monitor
Odstraňuji předchozí modul-loopback / MixSink / MixSource (pokud existují)...
Null-sink MixSink existuje (nebudu znovu vytvářet).
MixSink index: <unknown>
Vytvářím loopback: alsa_input.pci-0000_00_1b.0.pro-input-0
alsa_output.pci-0000_00_1b.0.pro-output-0.monitor -> MixSink ...
Record loop module id: 536870913
Spuštěn temporary parec pid=2150404
Poznámka: record sink-input zatím nevznikl (Audacity při spuštění nahrávání ho probudí).
Vytvářím monitor loopback: alsa_input.pci-0000_00_1b.0.pro-input-0
alsa_output.pci-0000_00_1b.0.pro-output-0.monitor -> alsa_output.pci-0000_00_1b.0.pro-output-0 (attenuated monitoring)...
Monitor loop module id: 536870914
Poznámka: monitor sink-input nevznikl — probuď mic nahráváním v Audacity a pak spusť 'pactl list short sink-inputs' pro nastavení.
Virtual source MixSource již existuje.
Virtual source index: <unknown>
HOTOVO: Audacity vyber zdroj 'MixSource' (Mix of system apps + mic at full volume).
Pro zahrnutí VLC do záznamu: přesuň jeho sink-input do MixSink nebo duplikuj fyzický monitor do MixSink.
V Pavucntrol nahrávání vidím že tam vznikly dva loopbacky pro vstup.
Na vstupní kartě vidím Build in Audio pro jak kdyby tam běžel nějaký šum nebo co. Mám sice zapojený mic ale tento indikátor "Ticho" nereaguje pokud mluvím, takže asi šum - ale toto tam vlastně vidím defaultně i po restartu pulse.
Ale nejde to audacity spustit nebo to krachuje, musím opravit zvuk, vše vrátit jinak audacity ani nespustím.
-
Zkusil jsem copilot, aby dal něco jednoduchého. Netestoval jsem, protože na starším mintu nemám ještě wireplumber. IMO na tom by se dalo stavět https://github.com/copilot/share/403a52b0-0a84-8046-a813-240a6413209a . Je to celkem jednoduché, pár příkazů a generátor konfigurace pro wireplumber, žádné komplikované pipeliny.
Samozřejmě to používá sémantiku PW, ne outdated PA.
-
Chápu to dobře že se snažíš nahrát mikrofon namíchaný s interníma zvukama počítače? Audacity neumí zachytávat vícero nezávislých vstupů současně. Použij ffmpeg! Jestli si jako výstup představuješ jeden stereo wav, můžeš zkusit něco takového:
ffmpeg -f pulse -i $(pactl get-default-source) -f pulse -i $(pactl get-default-sink).monitor -filter_complex "[0:a][1:a]amerge=inputs=2[a]" -map "[a]" -ac 2 /tmp/nahrávka.wav