apache — установить громкость используя php exec и amixer

Я написал небольшой скрипт php для управления громкостью моей локальной машины с помощью alsa:

<?php
# for simplicity and testing it really just executes the command:
echo exec('amixer set Master 5%+') . " \n";

Теперь, когда я запускаю этот скрипт в командной строке, он работает нормально:

$ 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]

У меня играет музыка, и я слышу, как она становится громче.

Но когда я пытаюсь запустить скрипт через apache из браузера, вызывая http://localhost/volume.php это не работает

# http://localhost/volume.php
Front Right: Playback 55709 [10%] [on]
# F5
Front Right: Playback 55709 [15%] [on]
# F5
Front Right: Playback 55709 [20%] [on]

Теперь я не слышу никаких изменений в объеме, и проценты, кажется, не связаны с текущим состоянием. Это говорит 10% — 15% — 20%, когда это действительно все еще на 70%.

Мой Apache работает как мой пользователь, так exec('whoami') дает мне имя пользователя, с которым я вошел в систему на моей оболочке, где все работает нормально.

# httpd.conf
User mkt
Group mkt

Я на Fedora 22.

Вероятно, это связано с процессной средой apache2.
Любые идеи, как это исправить?

ОБНОВИТЬ:

Это вывод 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

В командной строке работают только default и pulse:

amixer -D pulse set Master 5%+
amixer -D default set Master 5%+

С PHP даже эти два не работают.
Во всяком случае … мой звук исходит из динамиков моих мониторов, который подключен через HDMI. Я думаю, последние 4 устройства — мои кандидаты. Но ни один из них не работает.

$ 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%+

Во всех четырех случаях говорится:
(с DEV = [0-3] конечно)

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

ОБНОВИТЬ

Вывод 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%+

Оба не работают!

РЕШЕНИЕ:

Спасибо за помощь!
Ответ пришел https://superuser.com/questions/1069981/set-volume-using-php-exec-and-amixer

putenv("PULSE_SERVER=/run/user/".getmyuid()."/pulse/native");

14

Решение

возможно amixer не обращается к правильному DBUS когда бегут из апача. Попробуйте установить DBUS_ADDRESS переменная окружения путем вызова amixer из сценария оболочки, который устанавливает переменную перед запуском 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

(Код скопирован с Запуск приложения командной строки из PHP от имени конкретного пользователя)

amixer.php

<?php
echo exec('dbus_amixer.sh') . " \n";
4

Другие решения

Попробуйте сначала запустить aplay -L и вы должны получить что-то вроде этого:

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
...

Определите, какое из них является вашим устройством, затем измените amixer ... командовать amixer -D device ..., например amixer -D surround21:CARD=MID,DEV=0 set Master 5%+,

Это может сработать. Если нет, попробуйте aplay -l (строчные буквы) и получите номер карты. Тогда, например, если номер карты 1, пытаться amixer -c 1 set Master 5%+,

2

Вы говорите, что ваш пользователь Apache работает как пользователь командной строки. Насколько простирается сходство? Я заметил, что вы используете короткий путь:

echo exec('amixer set Master 5%+')

…учитывая, что пользователь то же самое, вы могли бы иметь неправильный путь в Apache (настройки PATH не зависят от пользователя, они находятся в профиле пользователя, и Apache может загрузить совсем другой профиль) — попробуйте указать полный путь к amixer в exec:

echo exec('/usr/local/bin/or/whatever/amixer set Master 5%+') . " \n";

Также для отладки запустите shell_exec добавление 2>&1 stderr перенаправить в командную строку. Это может дать некоторое представление о том, что именно терпит неудачу.

Вы можете выполнить более сложную команду для настройки среды:

exec(`HOME=whatever FLAGS=somethingelse PATH=/usr/local/... /usr/local/bin/amixer... 2>&1`);

Чтобы узнать, что переменные среды являются, Вы можете войти в систему как пользователь, убедиться, что amixer работает, выгрузить среду в файл:

set> set.txt

и проверьте set.txt для любых значений, которые могут применяться к amixer. Вы можете запустить другой похожий set из Apache, и сравнить результаты (на самом деле я думаю, что среда доступна также через phpinfo()).

1

Лучший и более простой способ сделать это — использовать 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");
?>

Я установил xdotool и настроил файл rc.xml в openbox ubuntu с помощью

 <!-- 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>

Отлично работает.

0
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector