在 Python 应用程序中使用 Raspberry Pi 4B 终端命令

问题描述

我目前正在开发一个小型 Python 应用程序,它将 RaspBerry Pi 4B 变成 48 通道录音机。基本工作,但在录制期间,我需要一个日志文件来告诉我录制何时开始、发生了哪些 ALSA 警告以及录制何时停止。

可以用这个终端命令启动记录器:

pi@raspBerrypi:~ $ rec -q -t caf --endian little --buffer 96000 -c 48 -b 24 /home/pi/myssd-one/Aufnahmen/test.caf 2>&1 | tee /home/pi/myssd-one/Aufnahmen/logging.log

这会在 test.caf 文件中记录音频并将 ALSA 警告写入 logging.log 到目前为止一切顺利。

Python 程序(应在带有 GUI 的触摸屏上运行,以便可以轻松开始和停止录制)负责处理可变音频文件名(日期时间戳)并控制 LED 以显示正在录制。>

这部分代码负责打开和关闭

#!/usr/bin/env python

from tkinter import *
import shlex
import os
import subprocess
import tkinter.font
import datetime
from gpiozero import LED
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BCM)
GPIO.setup(11,GPIO.OUT)

def ledToggle():
    if led.is_lit:
        led.off()
        my_env = os.environ.copy()
        my_env['AUdioDRIVER'] = 'alsa'
        my_env['AUdioDEV'] = 'hw:KTUSB,0'
        ledButton["text"] = "Turn Recorder on"
        print ("recorder stops")
        subprocess.Popen(['sudo','pkill','-SIGINT','rec'],env = my_env,shell = FALSE,stdout=subprocess.PIPE)
    else:
        led.on()
        my_env = os.environ.copy()
        my_env['AUdioDRIVER'] = 'alsa'
        my_env['AUdioDEV'] = 'hw:KTUSB,0'
        ledButton["text"] = "Turn Recorder off"
        print ("recorder starts")
        ##reference statement command line: "rec -q -t caf --endian little --buffer 96000 -c 48 -b 24 /home/pi/myssd-one/Aufnahmen/test.caf 2>&1 | tee /home/pi/myssd-one/Aufnahmen/logging.log"
        command_line = shlex.split("rec '-q' '-t' 'caf' '--buffer' '96000' '-c 48' '-b 24' '/home/pi/myssd-one/Aufnahmen/test.caf' '"2>&1 | tee"' '/home/pi/myssd-one/Aufnahmen/logging.log'")
        p1 = subprocess.Popen(command_line,shell = False,stdout=subprocess.PIPE)

我正在尝试将原始命令行语句移动到 subprocess.Popen 命令中,但尚未成功。路由到日志文件的部分失败了。看起来,启动的 sox 应用程序“rec”试图将其解释为自己的参数列表的一部分,而不是将其解释为将 stdout 和 stderr 重定向到日志文件。我感谢在这个问题上的一些指导。 音频文件的可变文件名已经完成,但为了简单起见,从这个代码片段中取出。

解决方法

谢谢 Mark,我按照你的提示深入研究了这个命令行,它只能用 shell=True 运行,这意味着它必须写成一个完整的语句,而不用分隔逗号和转义引号。现在它起作用了。实际上,shlex.split() 已经过时了。