Establecer el volumen utilizando php exec y amixer
apache alsa (3)
Escribí un pequeño script php para controlar el volumen de mi máquina local con alsa:
<?php
# for simplicity and testing it really just executes the command:
echo exec(''amixer set Master 5%+'') . " /n";
Ahora cuando ejecuto este script en línea de comandos, funciona bien:
$ php volume.php
Front Right: Playback 39226 [60%] [on]
$ php volume.php
Front Right: Playback 42503 [65%] [on]
$ php volume.php
Front Right: Playback 45780 [70%] [on]
Tengo música y la escucho cada vez más fuerte.
Pero cuando intento ejecutar el script a través de apache desde el navegador que llama a http://localhost/volume.php
, no funciona.
# http://localhost/volume.php
Front Right: Playback 55709 [10%] [on]
# F5
Front Right: Playback 55709 [15%] [on]
# F5
Front Right: Playback 55709 [20%] [on]
Ahora no escucho ningún cambio en el volumen y los porcentajes parecen no estar relacionados con el estado actual. Dice 10% - 15% - 20% cuando realmente todavía está en 70%.
Mi apache se ejecuta como mi usuario, por lo que exec(''whoami'')
me da el nombre de usuario con el que estoy conectado en mi caparazón, donde todo funciona bien.
# httpd.conf
User mkt
Group mkt
Estoy en Fedora 22.
Probablemente se deba al entorno de proceso de apache2. Alguna idea de cómo solucionar este problema?
ACTUALIZAR :
Esta es la salida de aplay -L:
[mkt@localhost ~]$ aplay -L
null
Discard all samples (playback) or generate zero samples (capture)
pulse
PulseAudio Sound Server
default
Default ALSA Output (currently PulseAudio Sound Server)
sysdefault:CARD=Intel
HDA Intel, ALC888 Analog
Default Audio Device
front:CARD=Intel,DEV=0
HDA Intel, ALC888 Analog
Front speakers
surround21:CARD=Intel,DEV=0
HDA Intel, ALC888 Analog
2.1 Surround output to Front and Subwoofer speakers
surround40:CARD=Intel,DEV=0
HDA Intel, ALC888 Analog
4.0 Surround output to Front and Rear speakers
surround41:CARD=Intel,DEV=0
HDA Intel, ALC888 Analog
4.1 Surround output to Front, Rear and Subwoofer speakers
surround50:CARD=Intel,DEV=0
HDA Intel, ALC888 Analog
5.0 Surround output to Front, Center and Rear speakers
surround51:CARD=Intel,DEV=0
HDA Intel, ALC888 Analog
5.1 Surround output to Front, Center, Rear and Subwoofer speakers
surround71:CARD=Intel,DEV=0
HDA Intel, ALC888 Analog
7.1 Surround output to Front, Center, Side, Rear and Woofer speakers
iec958:CARD=Intel,DEV=0
HDA Intel, ALC888 Digital
IEC958 (S/PDIF) Digital Audio Output
hdmi:CARD=NVidia,DEV=0
HDA NVidia, HDMI 0
HDMI Audio Output
hdmi:CARD=NVidia,DEV=1
HDA NVidia, HDMI 1
HDMI Audio Output
hdmi:CARD=NVidia,DEV=2
HDA NVidia, HDMI 2
HDMI Audio Output
hdmi:CARD=NVidia,DEV=3
HDA NVidia, HDMI 3
HDMI Audio Output
En la línea de comandos, solo el valor predeterminado y el pulso funcionan:
amixer -D pulse set Master 5%+
amixer -D default set Master 5%+
Con PHP, incluso esos dos no funcionan. De todos modos ... mi sonido proviene de los altavoces de mis monitores que está enchufado a través de hdmi. Así que supongo que los últimos 4 dispositivos son mis candidatos. Pero ninguno de ellos funciona.
$ amixer -D hdmi:CARD=NVidia,DEV=0 set Master 5%+
$ amixer -D hdmi:CARD=NVidia,DEV=1 set Master 5%+
$ amixer -D hdmi:CARD=NVidia,DEV=2 set Master 5%+
$ amixer -D hdmi:CARD=NVidia,DEV=3 set Master 5%+
En los cuatro casos dice: (con DEV = [0-3] por supuesto)
ALSA lib control.c:954:(snd_ctl_open_noupdate) Invalid CTL hdmi:CARD=NVidia,DEV=3
amixer: Mixer attach hdmi:CARD=NVidia,DEV=3 error: No such file or directory
ACTUALIZAR
Salida de aplay -l:
$ aplay -l
**** List of Hardware-Devices (PLAYBACK) ****
Card 0: Intel [HDA Intel], Device 0: ALC888 Analog [ALC888 Analog]
Sub-Devices: 1/1
Sub-Device #0: subdevice #0
Card 0: Intel [HDA Intel], Device 1: ALC888 Digital [ALC888 Digital]
Sub-Devices: 1/1
Sub-Device #0: subdevice #0
Card 1: NVidia [HDA NVidia], Device 3: HDMI 0 [HDMI 0]
Sub-Devices: 1/1
Sub-Device #0: subdevice #0
Card 1: NVidia [HDA NVidia], Device 7: HDMI 1 [HDMI 1]
Sub-Devices: 0/1
Sub-Device #0: subdevice #0
Card 1: NVidia [HDA NVidia], Device 8: HDMI 2 [HDMI 2]
Sub-Devices: 1/1
Sub-Device #0: subdevice #0
Card 1: NVidia [HDA NVidia], Device 9: HDMI 3 [HDMI 3]
Sub-Devices: 1/1
Sub-Device #0: subdevice #0
$ amixer -c0 set Master 5%+
$ amixer -c1 set Master 5%+
¡Ambos no funcionan!
SOLUCIÓN:
¡Gracias por toda la ayuda! La respuesta, sin embargo, provino de https://superuser.com/questions/1069981/set-volume-using-php-exec-and-amixer
putenv("PULSE_SERVER=/run/user/".getmyuid()."/pulse/native");
Primero intente ejecutar aplay -L
y debería obtener un resultado como este:
pulse
PulseAudio Sound Server
sysdefault:CARD=MID
HDA Intel MID, ALC889 Analog
Default Audio Device
front:CARD=MID,DEV=0
HDA Intel MID, ALC889 Analog
Front speakers
surround21:CARD=MID,DEV=0
HDA Intel MID, ALC889 Analog
2.1 Surround output to Front and Subwoofer speakers
...
Identifique cuál de estos es su dispositivo, luego modifique su amixer ...
comando a amixer -D device ...
, por ejemplo amixer -D surround21:CARD=MID,DEV=0 set Master 5%+
.
Esto puede funcionar Si no, intente aplay -l
(minúscula), y obtenga el número de tarjeta. Entonces, por ejemplo, si el número de tarjeta es 1
, pruebe amixer -c 1 set Master 5%+
.
Tal vez amixer
no está abordando el DBUS correcto cuando se ejecuta desde apache. Intente establecer la variable de entorno DBUS_ADDRESS
invocando amixer
desde un script de shell que establece la variable antes de ejecutar amixer
.
dbus_amixer.sh
#! /bin/bash
DBUS_ADDRESS=`grep -z DBUS_SESSION_BUS_ADDRESS /proc/*/environ 2> /dev/null| sed ''s/DBUS//nDBUS/g'' | tail -n 1`
if [ "x$DBUS_ADDRESS" != "x" ]; then
export $DBUS_ADDRESS
/usr/bin/amixer set Master 5%+
fi
(Código copiado de la ejecución de la aplicación de línea de comandos de PHP como usuario específico )
amixer.php
<?php
echo exec(''dbus_amixer.sh'') . " /n";
Usted dice que su usuario Apache se ejecuta como su usuario de línea de comando. ¿Hasta dónde se extiende la similitud? Noté que usa una ruta corta:
echo exec(''amixer set Master 5%+'')
... dado que el usuario es el mismo, es posible que tenga una ruta incorrecta en Apache (la configuración de PATH no depende del usuario, están en el perfil del usuario y Apache puede cargar un perfil diferente por completo) - intente colocar el camino completo a amixer
en el ejecutivo:
echo exec(''/usr/local/bin/or/whatever/amixer set Master 5%+'') . " /n";
Además, para fines de depuración, ejecute shell_exec
agregando 2>&1
stderr redirigir a la línea de comandos. Esto podría arrojar alguna pista sobre qué es exactamente lo que está fallando.
Puede ejecutar un comando más complejo para configurar el entorno:
exec(`HOME=whatever FLAGS=somethingelse PATH=/usr/local/... /usr/local/bin/amixer... 2>&1`);
Para saber cuáles son las variables de entorno, puede iniciar sesión como usuario, verificar que el amixer funcione, volcar el entorno en un archivo:
set> set.txt
y revisa set.txt para ver los valores que podrían aplicarse a amixer. Puede ejecutar otro set
similar desde Apache y comparar los resultados (de hecho, creo que también se puede acceder al entorno a través de phpinfo()
).