Grabar la salida de un programa con PulseAudio

49

Me gustaría grabar una salida de un programa con PulseAudio usando la línea de comandos / script bash. Es importante no registrar toda la salida, sino solo la salida de un programa específico.

Pensé que tendría que crear un nuevo sumidero nulo y luego mover la salida del programa a este nuevo sumidero. Luego dígale a parec que use este monitor específico para grabar.

El primer paso sería algo como esto:

pactl load-module module-null-sink sink_name=steam

Pero, ¿cómo mover la salida del programa ahora a este sumidero?
¿Y cómo grabar el sumidero específico con un script bash?

usuario5950
fuente

Respuestas:

52

Intenta algo como esto:

En una terminal ingrese

pacmd

(esta es la CLI del PulseAudio-Server) luego use

list-sink-inputs

(donde obtiene los índices de las entradas en ejecución) Ahora encuentre el índice de su entrada. Ahora se conoce como $ INDEX

la parte programable es:

pactl load-module module-null-sink sink_name=steam
pactl move-sink-input $INDEX steam
parec -d steam.monitor | oggenc -b 192 -o steam.ogg --raw -

Explicaciones:

  • El primer comando agregará un sumidero nulo como ya sabía.
  • El segundo comando mueve la entrada del sumidero de su sumidero de audio estándar a steam
  • El tercer comando registra el monitor del dispositivo steam (-d) y coloca la salida (flujo de onda sin procesar) en oggenc, que codifica este flujo de onda en un archivo oga. (para mp3 use cojo)
Waschtl
fuente
¡Genial, muchas gracias por esta gran respuesta! :)
Fuerza
2
¿podría explicar cómo deshacer esta operación? mis sumideros nulos todavía están asignados a varias aplicaciones, ¡y ahora no tengo sonido!
ixtmixilix
@ixtmixilix: la forma más fácil de restaurar todas las configuraciones a las predeterminadas es simplemente matar y reiniciar el servidor pulseaudio. Si se establece en autopawn (este es el valor predeterminado) simplemente emite pulseaudio -ken un terminal.
Takkat
1
@ixtmixilix Cuando ejecute, list-sink-inputstome nota del sinkvalor. Para cambiar de nuevo solo corre pactl move-sink-input $INDEX $SINK. Algo así comopactl move-sink-input 4719 1
Ciaran
27

Mejorando la respuesta de Waschtl de este hilo para que pueda AMBOS ESCUCHAR Y GRABAR el sonido de la aplicación:

Primero, buscamos nuestra salida predeterminada y ponemos su nombre de sumidero en $DEFAULT_OUTPUT:

$ pacmd list-sinks | grep -A1 "* index"
  * index: 1
    name: <alsa_output.pci-0000_00_1b.0.analog-stereo>
$ DEFAULT_OUTPUT=$(pacmd list-sinks | grep -A1 "* index" | grep -oP "<\K[^ >]+")
$ echo $DEFAULT_OUTPUT
alsa_output.pci-0000_00_1b.0.analog-stereo

Luego, creamos un sumidero combinado que solo tiene un esclavo: $ DEFAULT_OUTPUT . El sonido generado por la aplicación (fuente) se reenviará al receptor esclavo (es decir, salida real), y también lo grabaremos. Es diferente a un sumidero nulo donde el sonido de origen no se reenvía.

$ pactl load-module module-combine-sink \
  sink_name=record-n-play slaves=$DEFAULT_OUTPUT \
  sink_properties=device.description="Record-and-Play"

sink_properties es opcional y puede generar errores si usa espacios en el nombre de la descripción.

Entonces, podríamos usar el pactl move-sink-input ...comando de respuesta Waschtl (con record-n-play en lugar de steam ) pero la GUI pavucontroles más simple (y excelente para verificar / solucionar problemas):

$ sudo apt-get install pavucontrol
$ pavucontrol &

Luego, reproducimos algo de sonido en la aplicación que queremos grabar. En la pavucontrol Playbackpestaña, seleccionamos en la lista desplegable de la aplicación: "Grabar y reproducir" .

Finalmente, ¡estamos bien para grabar y escuchar al mismo tiempo! ( ejemplo mp3 cojo , ejecuta en primer plano)

$ parec --format=s16le -d record-n-play.monitor | \
  lame -r --quiet -q 3 --lowpass 17 --abr 192 - "temp.mp3"

O podemos grabar en segundo plano y detenernos en cualquier momento:

$ parec --format=s16le -d record-n-play.monitor | \
  lame -r --quiet -q 3 --lowpass 17 --abr 192 - "temp.mp3" \
   > /dev/null &1>/dev/null
$ killall -q parec lame

NÓTESE BIEN:

  • Para deshacer todo o volver a intentar el procedimiento: elimine o restablezca los sumideros con esta respuesta . pulseaudio -kfunciona muy bien para restablecer todo a los valores predeterminados de la sesión.
  • Si cambiamos la salida predeterminada en la Configuración de sonido del sistema, se sobrescribirá la configuración de reproducción de la aplicación personalizada y tendremos que volver a pavucontrol para volver a configurar la interfaz combinada.
  • Para poder escuchar el sonido desde varias interfaces "reales" (por ejemplo, auriculares, salida HDMI, etc.), debemos incluir todas las salidas "reales" que podamos usar para escuchar, como esclavos slink de grabación y reproducción , tales como: pactl load-module module-combine-sink sink_name=record-n-play slaves=real-output-1,real-output-2.

EDITAR: Cuidado, ya que Ubuntu 18 (quizás también 17), el sumidero combinado tiende a convertirse en el dispositivo de salida del sistema predeterminado, en lugar del dispositivo de salida real. Entonces, cuando cambia el volumen usando el icono de sonido en la bandeja del sistema, afecta el sonido de su grabación. Solución alternativa: después de crear el sumidero combinado, ábralo pavucontrolen la pestaña Salida. Seleccione "Ver: dispositivos de salida virtual" y restablezca el volumen de sonido del receptor combinado al 100%. Luego seleccione "Ver: Dispositivos de salida de hardware" y presione el icono verde "Definir como alternativa" en el dispositivo de salida real.

KrisWebDev
fuente
9

La respuesta de @ Waschtl es fantástica. @ixtmixilix preguntó sobre la restauración del audio normal después de que la grabación haya finalizado. Esta es la forma más fácil que conozco:

Instala y ejecuta la pavucontrolGUI. Debería ver su aplicación de salida de audio y su medidor de volumen debajo de la Playbackpestaña allí. Habrá un botón al lado que muestra que se está reproduciendo en Salida nula . Haga clic en eso y cámbielo a su salida de audio normal, audio estéreo analógico incorporado en mi caso.

Aquí hay una captura de pantalla de lo que estás buscando:

captura de pantalla

También puede usar este enfoque para configurar su grabación en el futuro, después de ejecutar el load-modulecomando en la respuesta de @ Waschtl para crear el sumidero.

Jack O'Connor
fuente
Si puede, cargue una captura de pantalla en Imgur y vincúlela a su respuesta.
Lucio
No sé si es factible, pero creo que la mejor manera es descargar el módulo de salida nulo, para que las nuevas reproducciones no lo capten de forma predeterminada
Jack
6

Mejorando aún más la respuesta de KrisWebDev , si desea que record-n-play esté siempre disponible, primero descubra la salida predeterminada:

pacmd list-sinks | grep -A1 "* index" | grep -oP "<\K[^ >]+"

que generará algo como:

alsa_output.pci-0000_00_1b.0.analog-stereo

A continuación, cree un archivo ~/.config/pulse/default.pa:

.include /etc/pulse/default.pa

load-module module-combine-sink sink_name=record-n-play slaves=alsa_output.pci-0000_00_1b.0.analog-stereo sink_properties=device.description="Record-and-Play"

Reemplace alsa_output.pci-0000_00_1b.0.analog-stereocon cualquier salida que obtuvo del pacmdcomando. Pulse no lee el archivo de configuración predeterminado cuando existe un archivo de configuración personalizado; es por eso que la primera línea anterior incluye el archivo de configuración predeterminado. De esa forma, pulseaudio todavía carga primero la configuración predeterminada.

Ejecute pulseaudio -kpara matar la instancia actual de pulseaudio para que se inicie una nueva con la nueva configuración.

Si en algún momento desea deshacer los cambios aquí, simplemente elimine el ~/.config/pulse/default.paarchivo y ejecútelo pulseaudio -k.

Si desea que record-n-play sea el sumidero predeterminado para todas las salidas, puede hacerlo agregando otra línea al final de ~/.config/pulse/default.pa:

set-default-sink record-n-play

Para los programas en los que pulseaudio ya ha almacenado información, recuerda el dispositivo de salida que utilizaron por última vez, por lo que deberá volver a configurarlos manualmente mediante uno de los métodos descritos en la respuesta de KrisWebDev.

Jonas Berlin
fuente
2

He creado este script bash en base a las respuestas proporcionadas por @Waschtl y @KrisWebDev.

Disponible aquí: https://gist.github.com/ramast/4be3314bc73f28f55e3604497188b007

¿Cómo utilizar?

$ ./pulse-recorder.bash 
    index: 225
                application.name = "ALSA plug-in [mplayer]"
                module-stream-restore.id = "sink-input-by-application-name:ALSA plug-in [mplayer]"
Choose recording index: 225
temp.mp3 file already exist, replace (y/n)? y

Nueva versión

He creado un script de Python que ofrece algunas mejoras sobre el anterior. https://gist.github.com/ramast/c47bd5e57586e9c2deb74975e27089f0

¿Cómo utilizar?

$ ./pulse-recorder.py 

1 - ALSA plug-in [mplayer]
2 - AudioIPC Server

Please enter a number: 1

Your selection was: ALSA plug-in [mplayer]
Please press enter when you are ready to start

Cuando presione enter, la grabación comenzará de inmediato. si en el momento en que presiona enter, la aplicación ya estaba detenida (es decir, cerró mplayer, por ejemplo), el script esperará hasta que la aplicación vuelva a aparecer y comience a grabar.

El único inconveniente de ese script (frente al original) es que si la lista contiene dos entradas con el mismo nombre, el script no se comportará correctamente. Por ejemplo

$ ./pulse-recorder.py                                                                                                      

1 - ALSA plug-in [mplayer]
2 - ALSA plug-in [mplayer]
Ramast
fuente
En el caso de que tenga múltiples salidas (por ejemplo, altavoces, varios auriculares, monitor de audio), puede reemplazar en la línea 21 con, por ejemplo: default_output = alsa_output.pci-0000_00_1b.0.analog-stereo donde esto es de la salida de la lista de pacmd -sinks
smaudet