我正在制作一个小型应用程序,按计划响铃校园,可以从网站更新。一切都运行良好,除了作为cron作业安排的脚本在脚本运行时不会播放声音。我已经向脚本添加了输出管道和echo命令,以验证cron是否正在运行它,但播放声音的部分不起作用。从CLI手动运行时,脚本按预期工作。
脚本根据时间表提取一天中每个时段的时间和声音文件,然后将与声音文件关联的时间与当前时间进行比较 - 如果匹配,则
exec("/usr/bin/aplay /var/www/site/".$soundfile);
然后,Cron计划在上学期间每分钟运行一次脚本:
* 8-16 * 1-6,9-12 1-5 root /usr/bin/php -f /var/www/site/scripts/playsound.php > /dev/null
同样,如果我在安排声音时手动运行脚本,声音将通过连接的扬声器播放。当我有测试代码回显到屏幕或输出到输入的文件时,cron会将输出转储到文件中,确认它按计划运行脚本。它只是不会播放剧本中的声音部分。
我已经检查了所有权限,因为其他一切正常,它们似乎是准确的。我甚至可以编写一个简单的BASH脚本来让Cron按计划播放声音,因此系统似乎有正确的组成员资格来访问脚本和声音文件。我已为exec()
切换shell_exec()
,尝试仅使用命令以及命令的绝对路径,并且计划将cron作业作为root运行。仍然无法弄清楚为什么这一小功能不幸对这个程序的成功至关重要将不起作用。
非常感谢任何建议。
答案 0 :(得分:1)
可能是/dev/snd/pcmC0D0p
的权限问题。 (这是ALSA卡0的设备:设备0:播放。)如果服务器上正在运行桌面会话,则可能有一个pulseaudio守护程序保持设备打开。
为多个用户设置能够同时播放声音是一团糟,并且需要在非零复制的低性能模式下配置pulseaudio,所以不要这样做。只需确保服务器可以在需要时专门打开声音设备。
查看ALSA声音设备是否打开(无论暂停状态还是w / e):
$ cat /proc/asound/card0/pcm0p/sub0/hw_params
access: MMAP_INTERLEAVED
format: S16_LE
subformat: STD
channels: 2
rate: 44100 (44100/1)
period_size: 8192
buffer_size: 16384
$ cat /proc/asound/card0/pcm1p/sub0/hw_params
closed
因此我的第一张声卡上的第一个播放PCM已打开,但第二张PCM(我的主板音频的S / PDIF输出)已关闭。声音设备的进一步打开仅起作用,因为默认的ALSA设置使“默认”设备成为pulseaudio包装器。 hw:0
会失败,因为它很忙,而且这张声卡没有硬件混音器。
(有趣的事实:一些旧的声卡,例如一些PCI Soundblaster卡,支持硬件设备的多个打开。多个PCM数据流可以被DMA到卡,它们将由DSP混合。除非我是完全错了,内核驱动程序正在混合>。<但无论如何,如果有的话,你不需要使用pulseaudio。)
答案 1 :(得分:0)
使用 php interval 或 javascript (异步 - ajax)来调用预期的php文件,而不是设置为cron。我认为这将解决您的问题。
在服务器中执行的cron作业,它不会向浏览器抛出任何输出。
Cron Job最好发送通知/邮件,以特定的间隔更新/插入db。
根据您的要求,您必须通过浏览器运行脚本。
答案 2 :(得分:0)
正如其他人在评论中提到的那样,你真的必须保存日志,然后检查它们的线索。
从我的回忆中,我使用由PHP执行的专用脚本的经验可能是有益的。您可以将声音文件的名称作为参数提供给bash脚本。例如:
exec("/path/to/script.sh $SOUNDFILEPATH");
在脚本中,您可以设置工作目录,环境变量等。
当然,如果你想避免学生恶作剧,你必须逃避变量。
当一切变得艰难时,我总是畏缩的一种技巧是在cron下运行一个脚本,该脚本由存储在/ tmp /中的文件控制,您可以通过Web服务器写入该文件PHP。
因此,只需让PHP将控制数据写入/ tmp(或任何其他可写目录)中的文件,并获取经过测试的用户bash脚本,以便通过cron定期监视它。它可能就像在你的情况下有一条指向声音文件的行一样简单。
这对我来说总是很有意义。
答案 3 :(得分:0)
据我了解,cron | crontab
在其自身环境中运行;例如,请参阅:
因此,即使aplay
在以普通用户或root用户(WAV
| su
)的形式调用时会播放声音(sudo
),但它赢了&# 39;从cron
调用该文件时播放该文件 - 例如,执行包含aplay
语句的bash(.sh)脚本。
这适用于我的Arch Linux系统。
这是我的cron_notification.sh
脚本:
#!/usr/bin/bash
# /mnt/Vancouver/Programming/scripts/cron_notification.sh
# For use with crontab [ sudo gedit /etc/crontab ]
# cron (Arch Linux: cronie) requires full paths:
# /usr/bin/aplay
# /usr/bin/notify-send
for i in 1 2 3 4 5
do
#aplay alarm.mp3 ## << aplay cannot play MP3 files; use WAV
# ----------------------------------------
# NEEDED TO RUN 'aplay' FROM crontab:
# https://unix.stackexchange.com/questions/231941/cant-run-aplay-as-root
# https://www.reddit.com/r/linuxquestions/comments/37vcbo/playing_audio_from_a_cronjob/
# PulseAudio needs XDG_RUNTIME_DIR, so:
XDG_RUNTIME_DIR=/run/user/`id -u` /usr/bin/aplay /mnt/Vancouver/Programming/scripts/PHASER.WAV
# ----------------------------------------
sleep 0.25
done
# ----------------------------------------------------------------------------
# "Critical" alerts persist until clicked (i.e., do not appear, then fade after ~20"):
# notify-send -u critical 'Hello Victoria!' 'Countdown has ended!' --icon=dialog-information
/usr/bin/notify-send -u critical 'Hello Victoria!' "It's 3 pm!" -i /mnt/Vancouver/Programming/scripts/alert.jpg
而且,这是我的/etc/crontab
文件的相关部分:
# /etc/crontab
# system-wide crontab
# edit: sudo {your favorite text editor: gedit; geany; ...} /etc/crontab
# https://crontab.guru ## online crontab values checker, planner
# =====================================================================
# SHELL
# =====================================================================
# cron (crontab) requires full paths:
SHELL=/usr/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
# =====================================================================
# ARCH LINUX-RELATED [Arch Linux x86_64]
# =====================================================================
# cron | https://wiki.archlinux.org/index.php/Cron
# Will install, use "cronie" cron (crontab):
# Install cronie: sudo pacman -Syu cronie
# Enable cron: sudo systemctl enable --now cronie.service
# Start cron: sudo systemctl start cronie.service
# Restart cron: sudo systemctl restart cronie.service
# =====================================================================
# APLAY NOTIFICATION (3:00pm M-F)
# =====================================================================
# Two issues when running
# /mnt/Vancouver/Programming/scripts/cron_notification.sh
# from cron:
# ----------------------------------------
# 1. "notify-send":
# https://bbs.archlinux.org/viewtopic.php?id=216912
# notify-send also needs access to your DBUS_SESSION_BUS_ADDRESS. Assuming that your UID is 1000:
DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/1000/bus"
# More here: https://wiki.archlinux.org/index.php/Desktop_notifications#Usage_in_programming
# ----------------------------------------
# 2. "aplay":
# TO RUN 'aplay' FROM crontab:
# https://www.reddit.com/r/linuxquestions/comments/37vcbo/playing_audio_from_a_cronjob/
# PulseAudio needs XDG_RUNTIME_DIR, so:
# XDG_RUNTIME_DIR=/run/user/`id -u` /usr/bin/aplay /mnt/Vancouver/Programming/scripts/PHASER.WAV
# Line above added to "/mnt/Vancouver/Programming/scripts/cron_notification.sh" script.
# ----------------------------------------
# m h dom mon dow user nice command
# "At 15:00 on every day-of-week from Monday through Friday”
# [https://crontab.guru/#0_15_*_*_1-5]:
0 15 * * 1-5 victoria nice -n 19 /usr/bin/bash /mnt/Vancouver/Programming/scripts/cron_notification.sh
# NOTE -- running as user ("victoria"), not "root".
# Test - every minute:
#* * * * 1-5 victoria nice -n 19 /usr/bin/bash /mnt/Vancouver/Programming/scripts/cron_notification.sh
我留下了评论,以供参考和澄清。
您可以从我的网站下载PHASER.WAV
声音文件: