首页 文章

使用php exec和amixer设置音量

提问于
浏览
14

我写了一个小的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]

我有音乐播放,我听到声音越来越大 .

但是,当我尝试通过浏览器调用 http://localhost/volume.php 的apache运行脚本时,它不起作用 .

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

现在我听说音量没有变化,百分比似乎与当前状态无关 . 当它真的仍然是70%时,它说10% - 15% - 20% .

我的apache正在以我的用户身份运行,所以 exec('whoami') 给了我在shell上登录的用户名,一切正常 .

# httpd.conf
User mkt
Group mkt

我在Fedora 22上 .

可能是由于apache2进程环境 . 任何想法如何解决这一问题?

UPDATE

这是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

在命令行上只有默认和脉冲工作:

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

UPDATE

输出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%+

两者都不起作用!

SOLUTION:

感谢您的帮助!答案来自https://superuser.com/questions/1069981/set-volume-using-php-exec-and-amixer

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

4 回答

  • 1

    当从apache运行时, amixer 可能没有解决正确的DBUS . 尝试通过从运行 amixer 之前设置变量的shell脚本调用 amixer 来设置 DBUS_ADDRESS 环境变量 .

    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
    

    (代码从Running command-line application from PHP as specific user复制)

    amixer.php

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

    首先尝试运行 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中有 the wrong path (PATH设置不依赖于用户,他们在用户配置文件中,而Apache可能会加载不同的配置文件) - 尝试放置完整路径到 amixer 进入exec:

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

    此外,出于调试目的,运行 shell_exec2>&1 stderr重定向添加到命令行 . 这可能会产生一些关于究竟是什么失败的线索 .

    您可以运行更复杂的命令来设置环境:

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

    要了解环境变量是什么,您可以以用户身份登录,验证amixer是否正常工作,将环境转储到文件中:

    set> set.txt

    并查看set.txt,了解适用于amixer的任何值 . 您可以在Apache中运行另一个类似的 set ,并比较结果(实际上我认为环境也可以通过 phpinfo() 访问) .

  • 4

    完成这项工作的最佳和更简单的方法是使用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并在ubuntu openbox上配置了rc.xml文件

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

    它就像一个魅力 .

相关问题