我有一个 Python 脚本,使用“subprocess”模块执行 ffmpeg 命令来录制音频/视频,如下所示:
def kill_ffmpeg_process(args):
for proc in psutil.process_iter(['pid', 'name', 'cmdline']):
if proc.info['name'] == 'ffmpeg' and args in proc.info['cmdline']:
print("found: " + str(proc))
proc.kill()
kill_ffmpeg_process("ffmpeg")
rand_num = str(random.randint(0,99))
record_internal_cmd = f"ffmpeg -f pulse -ac 2 -i 'alsa_input.pci-0000_00_05.0.analog-stereo' -f v4l2 -i /dev/video4 -vcodec libx264 -crf 28 Desktop/recordings/{get_today_timestamp()}_{str(rand_num)}_internal_feed.mkv"
record_external_cmd = f"ffmpeg -f v4l2 -i /dev/video5 Desktop/recordings/{get_today_timestamp()}_{str(rand_num)}_external_feed.mkv"
print("Recording /dev/video4 with audio")
subprocess.Popen(record_internal_cmd,shell=True,stderr=subprocess.PIPE,stdout=subprocess.PIPE)
time.sleep(1)
print("Recording /dev/video5")
subprocess.Popen(record_external_cmd,shell=True,stderr=subprocess.PIPE,stdout=subprocess.PIPE)
time.sleep(3)
我想使用 crontab 安排此脚本每 1 小时(自动)执行一次,因此我创建了一个调用 Python 脚本的 .sh 文件#!/bin/bash python3 script.py
。在终端中手动执行时,./shell_script.sh
它可以正常工作,但将其添加到 crontab 时,它不起作用,因为它找不到音频源“个人想法”,因为当我从中删除录音时,它可以工作。但脉冲录音不起作用;它只执行第二条命令并创建包含视频录制的文件。
答案1
为什么会发生这种情况?
您的脚本显然需要运行 Pulse Audio...Pulse Audio 正在运行(自动地)作为用户服务...您可以使用以下命令查看服务的状态:
$ systemctl --user status pulseaudio
● pulseaudio.service - Sound Service
Loaded: loaded (/usr/lib/systemd/user/pulseaudio.service; enabled; vendor preset: enabled)
Active: active (running) since Tue 2023-04-25 14:26:50 +03; 13min ago
TriggeredBy: ● pulseaudio.socket
Main PID: 120691 (pulseaudio)
Tasks: 4 (limit: 23594)
Memory: 7.3M
CPU: 389ms
CGroup: /user.slice/user-1000.slice/[email protected]/session.slice/pulseaudio.service
└─120691 /usr/bin/pulseaudio --daemonize=no --log-target=journal
Apr 25 14:26:50 Lenovo systemd[5211]: Starting Sound Service...
Apr 25 14:26:50 Lenovo systemd[5211]: Started Sound Service.
服务单元本身可以通过以下方式检查:
$ cat /usr/lib/systemd/user/pulseaudio.service
[Unit]
Description=Sound Service
# We require pulseaudio.socket to be active before starting the daemon, because
# while it is possible to use the service without the socket, it is not clear
# why it would be desirable.
#
# A user installing pulseaudio and doing `systemctl --user start pulseaudio`
# will not get the socket started, which might be confusing and problematic if
# the server is to be restarted later on, as the client autospawn feature
# might kick in. Also, a start of the socket unit will fail, adding to the
# confusion.
#
# After=pulseaudio.socket is not needed, as it is already implicit in the
# socket-service relationship, see systemd.socket(5).
Requires=pulseaudio.socket
ConditionUser=!root
[Service]
ExecStart=/usr/bin/pulseaudio --daemonize=no --log-target=journal
LockPersonality=yes
MemoryDenyWriteExecute=yes
NoNewPrivileges=yes
Restart=on-failure
RestrictNamespaces=yes
SystemCallArchitectures=native
SystemCallFilter=@system-service
# Note that notify will only work if --daemonize=no
Type=notify
UMask=0077
Slice=session.slice
[Install]
Also=pulseaudio.socket
WantedBy=default.target
查看三个重要的设置:
WantedBy=default.target
这意味着该服务不一定能一直使用到default.target
(启动过程中最后一个启用多用户的界面)。Requires=pulseaudio.socket
仅在用户会话启动后可用(即登录后)ConditionUser=!root
也就是说,用户不能root
。
以上两者1和2在启动期间和登录之前,条件会影响正在运行的 Pulse Audio 守护程序是否可用于 crontab 作业。
健康)状况3root
但是,即使登录后也不允许运行 Pulse Audio 守护程序。
该怎么办呢?
您可以在用户的 crontab 中添加 cron 作业(Not
root
的 crontab) 并确保您的用户在 cron 作业运行时已登录。您可以在脚本中手动运行 Pulse Audio 守护程序,以您明确指定的特定用户身份运行脚本,在这种情况下,甚至
root
可以使用...例如比较:$ sudo su root -c 'pacmd list-sources' No PulseAudio daemon running, or not running as session daemon.
相对:
$ sudo su root -c 'pulseaudio --start; pacmd list-sources' W: [pulseaudio] main.c: This program is not intended to be run as root (unless --system is specified). 2 source(s) available. index: 0 name: <alsa_output.pci-0000_00_1f.3.analog-stereo.monitor> driver: <module-alsa-card.c> flags: DECIBEL_VOLUME LATENCY DYNAMIC_LATENCY state: IDLE suspend cause: (none) priority: 1030 volume: front-left: 65536 / 100% / 0.00 dB, front-right: 65536 / 100% / 0.00 dB balance 0.00 base volume: 65536 / 100% / 0.00 dB volume steps: 65537 muted: no current latency: 0.00 ms max rewind: 344 KiB sample spec: s16le 2ch 44100Hz channel map: front-left,front-right Stereo used by: 0 linked by: 0 configured latency: 2000.00 ms; range is 0.50 .. 2000.00 ms monitor_of: 0 card: 0 <alsa_card.pci-0000_00_1f.3> module: 7 properties: device.description = "Monitor of Built-in Audio Analogue Stereo" device.class = "monitor" alsa.card = "0" alsa.card_name = "HDA Intel PCH" alsa.long_card_name = "HDA Intel PCH at 0xa12a8000 irq 136" alsa.driver_name = "snd_hda_intel" device.bus_path = "pci-0000:00:1f.3" sysfs.path = "/devices/pci0000:00/0000:00:1f.3/sound/card0" device.bus = "pci" device.vendor.id = "8086" device.vendor.name = "Intel Corporation" device.product.id = "9d71" device.product.name = "Sunrise Point-LP HD Audio" device.form_factor = "internal" device.string = "0" module-udev-detect.discovered = "1" device.icon_name = "audio-card-pci" * index: 1 name: <alsa_input.pci-0000_00_1f.3.analog-stereo> driver: <module-alsa-card.c> flags: HARDWARE HW_MUTE_CTRL HW_VOLUME_CTRL DECIBEL_VOLUME LATENCY DYNAMIC_LATENCY state: IDLE suspend cause: (none) priority: 9039 volume: front-left: 3381 / 5% / -77.25 dB, front-right: 3381 / 5% / -77.25 dB balance 0.00 base volume: 6554 / 10% / -60.00 dB volume steps: 65537 muted: yes current latency: 353.71 ms max rewind: 0 KiB sample spec: s16le 2ch 44100Hz channel map: front-left,front-right Stereo used by: 0 linked by: 0 configured latency: 2000.00 ms; range is 0.50 .. 2000.00 ms card: 0 <alsa_card.pci-0000_00_1f.3> module: 7 properties: alsa.resolution_bits = "16" device.api = "alsa" device.class = "sound" alsa.class = "generic" alsa.subclass = "generic-mix" alsa.name = "ALC236 Analog" alsa.id = "ALC236 Analog" alsa.subdevice = "0" alsa.subdevice_name = "subdevice #0" alsa.device = "0" alsa.card = "0" alsa.card_name = "HDA Intel PCH" alsa.long_card_name = "HDA Intel PCH at 0xa12a8000 irq 136" alsa.driver_name = "snd_hda_intel" device.bus_path = "pci-0000:00:1f.3" sysfs.path = "/devices/pci0000:00/0000:00:1f.3/sound/card0" device.bus = "pci" device.vendor.id = "8086" device.vendor.name = "Intel Corporation" device.product.id = "9d71" device.product.name = "Sunrise Point-LP HD Audio" device.form_factor = "internal" device.string = "front:0" device.buffering.buffer_size = "352800" device.buffering.fragment_size = "176400" device.access_mode = "mmap+timer" device.profile.name = "analog-stereo" device.profile.description = "Analogue Stereo" device.description = "Built-in Audio Analogue Stereo" module-udev-detect.discovered = "1" device.icon_name = "audio-card-pci" ports: analog-input-internal-mic: Internal Microphone (priority 8900, latency offset 0 usec, available: unknown) properties: device.icon_name = "audio-input-microphone" analog-input-mic: Microphone (priority 8700, latency offset 0 usec, available: no) properties: device.icon_name = "audio-input-microphone" active port: <analog-input-internal-mic>