I wrote a little php script to control the volume of my local machine with alsa:
<?php
# for simplicity and testing it really just executes the command:
echo exec('amixer set Master 5%+') . " \n";
Now when I run this script on command line it works fine:
$ 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]
I have music playing and I hear it getting louder.
But when I try to run the script via apache from the browser calling http://localhost/volume.php
it doesn't work.
# http://localhost/volume.php
Front Right: Playback 55709 [10%] [on]
# F5
Front Right: Playback 55709 [15%] [on]
# F5
Front Right: Playback 55709 [20%] [on]
Now I hear no change in volume and the percentages seem to be unrelated to the current state. It says 10% - 15% - 20% when it really is still at 70%.
My apache is running as my user so exec('whoami')
gives me the username I am logged in with on my shell where everything works fine.
# httpd.conf
User mkt
Group mkt
I'm on Fedora 22.
Probably it's due to the apache2 process environment. Any ideas how to fix this?
UPDATE:
This is the output of 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
On command line only default and pulse are working:
amixer -D pulse set Master 5%+
amixer -D default set Master 5%+
With PHP even those two don't work. Anyway... my sound comes from my monitors speakers which is plugged in via hdmi. So I guess the last 4 devices are my candidates. But non of them work.
$ 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%+
In all four cases it says: (with DEV=[0-3] of course)
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
UPDATE
Output of 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%+
Both don't work!
SOLUTION:
Thanks for all the help! The answer though came from https://superuser.com/questions/1069981/set-volume-using-php-exec-and-amixer
putenv("PULSE_SERVER=/run/user/".getmyuid()."/pulse/native");
Perhaps amixer
isn't addressing the correct DBUS when run from apache. Try setting the DBUS_ADDRESS
environment variable by invoking amixer
from a shell script that sets the variable before running 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
(Code copied from Running command-line application from PHP as specific user)
amixer.php
<?php
echo exec('dbus_amixer.sh') . " \n";
Try first running aplay -L
and you should get output something like this:
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
...
Identify which of these is your device, then modify your amixer ...
command to amixer -D device ...
, for example amixer -D surround21:CARD=MID,DEV=0 set Master 5%+
.
This may work. If not, try aplay -l
(lowercase), and get the card number. Then, for example, if the card number is 1
, try amixer -c 1 set Master 5%+
.
You say that your Apache user runs as your command line user. How far does the similarity extend? I notice that you use short path:
echo exec('amixer set Master 5%+')
...given that the user is the same, you might have the wrong path in Apache (PATH settings are not dependent on the user, they're in the user profile, and Apache might load a different profile altogether) - try placing the full path to amixer
into the exec:
echo exec('/usr/local/bin/or/whatever/amixer set Master 5%+') . " \n";
Also, for debugging purposes, run shell_exec
adding 2>&1
stderr redirect to the command line. This might yield some clue as to what exactly is failing.
You can run a more complex command to set up environment:
exec(`HOME=whatever FLAGS=somethingelse PATH=/usr/local/... /usr/local/bin/amixer... 2>&1`);
To know what the environment variables are, you can log as the user, verify that amixer works, dump the environment into a file:
set > set.txt
and check out set.txt for whatever values could apply to amixer. You can run another similar set
from within Apache, and compare the results (actually I think that the environment is accessible also via phpinfo()
).
The best and more easy way to get this done is by using xdotool.
<?php
shell_exec("DISPLAY=:0 xdotool key XF86AudioMute");
?>
<?php
shell_exec("DISPLAY=:0 xdotool key XF86AudioRaiseVolume");
?>
<?php
shell_exec("DISPLAY=:0 xdotool key XF86AudioLowerVolume");
?>
I installed xdotool and configured the rc.xml file on ubuntu openbox with
<!-- Keybinding for Volume management -->
<keybind key="XF86AudioRaiseVolume">
<action name="Execute">
<command>amixer -D pulse set Master 10%+</command>
</action>
</keybind>
<keybind key="XF86AudioLowerVolume">
<action name="Execute">
<command>amixer -D pulse set Master 10%-</command>
</action>
</keybind>
<keybind key="XF86AudioMute">
<action name="Execute">
<command>amixer -D pulse set Master 100%-</command>
</action>
</keybind>
It works like a charm.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With