Почему мой скрипт PHP cron не воспроизводит звук?

Я работаю над небольшим приложением, чтобы звонить в школьные звонки по расписанию, которое можно обновить с веб-сайта. Все работает отлично, за исключением того, что сценарий, запланированный как задание cron, не будет воспроизводить звук при запуске сценария. Я добавил к сценарию команды вывода piping и echo, чтобы убедиться, что cron запускает его, но роль, которая играет звук, не работает. Скрипт работает как положено при запуске вручную из CLI.

Сценарий извлекает время и звуковой файл для каждого периода дня в расписании, затем сравнивает время, связанное со звуковым файлом, с текущим временем — если это совпадение, оно будет

exec("/usr/bin/aplay /var/www/site/".$soundfile);

Затем Крон должен запускать этот скрипт каждую минуту в течение учебного дня:

* 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. До сих пор не могу понять, почему эта маленькая функция, которая, к сожалению, так важна для успешной работы программы, не будет работать.

Любые советы высоко ценится.

7

Решение

Вероятно, разрешения на /dev/snd/pcmC0D0p проблема (Это устройство для карты ALSA 0: устройство 0: воспроизведение.) Если на сервере запущен сеанс рабочего стола, возможно, у него есть Pulseaudio-демон, удерживающий устройство открытым.

Настраивать одновременное воспроизведение звука несколькими пользователями — это беспорядок, и для этого требуется настройка pulseaudio в низкоэффективном режиме, не являющемся копируемым, так что не делайте этого. Просто убедитесь, что сервер может открывать только звуковое устройство, когда это необходимо.

Чтобы увидеть, открыто ли звуковое устройство ALSA (независимо от состояния паузы или ж / д):

$ 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 воспроизведения на моей первой звуковой карте открыт, но 2-й PCM (выход S / PDIF аудио моей материнской платы) закрыт. Дальнейшие открытия звукового устройства работают только потому, что настройка ALSA по умолчанию делает устройство «по умолчанию» оболочкой pulseaudio. hw:0 потерпит неудачу, потому что он занят, и у этой звуковой карты нет аппаратного микшера.

(Забавный факт: некоторые старые звуковые карты, например, некоторые карты PCI Soundblaster, поддерживали многократное открытие аппаратного устройства. Несколько потоков данных PCM могут быть переданы на карту DMA, где они будут микшироваться ее DSP. Если я не полностью неправ драйвер ядра перемешивался>.< Но в любом случае, вам не нужно Pulseaudio, если у вас есть.)

1

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

Вместо установки в качестве cron используйте интервал php или же Javascript (асинхронный — ajax), чтобы вызвать намеченный файл php. Я думаю, что это решит вашу проблему.

Задание cron, выполняемое на сервере, не выдаст никакого вывода в ваш браузер.

Cron Job хорош для отправки уведомлений / писем, обновления / вставки в БД через определенные промежутки времени.

Для ваших требований вы должны запустить скрипт через браузер.

0

Как уже упоминали другие в комментариях, вы действительно должны сохранить журналы, а затем проверить их на наличие подсказок.

Из того, что я помню из моего опыта, может быть полезным использование специального скрипта, который выполняется PHP. Вы должны передать bash-скрипту имя звукового файла в качестве параметра. Например:

exec("/path/to/script.sh $SOUNDFILEPATH");

В скрипте вы можете настроить свой рабочий каталог, переменные окружения и т. Д.

Конечно, вы должны избегать переменных, если вы хотите, чтобы студенты не получали вредных идей.

Одна из техник, к которой я всегда прибегал, когда дела идут непросто, — это запуск одного скрипта под cron, который управляется файлом, хранящимся в скажем / tmp /, в который вы можете писать через веб-сервер и PHP.

Так что просто попросите PHP записать управляющие данные в файл в / tmp (или любом другом доступном для записи каталоге) и заставить ваш протестированный пользовательский скрипт bash регулярно отслеживать его через cron. Это может быть так же просто, как иметь одну строку, которая указывает на звуковой файл в вашем случае.

Это всегда работало для меня без сюрпризов.

0

Как я понимаю, cron | crontab работает в собственной среде; например, см. принятый ответ в:

https://serverfault.com/questions/337631/crontab-execution-doesnt-have-the-same-environment-variables-as-executing-user

Таким образом, хотя aplay будет играть звук (WAV) файл при вызове как обычный пользователь или как пользователь root (su | sudo), он не будет воспроизводить этот файл при вызове из cron — например, выполнение сценария bash (.sh), который содержит ваши aplay заявление).

Это работает в моей системе 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

Я оставил комментарии на месте, для справок и ясности.

alert.jpg

уведомление

Вы можете скачать PHASER.WAV Звуковой файл с моего сайта, здесь:

http://persagen.com/files/PHASER.WAV

0