树莓派Zero 2W单独录音频正常,音视频同录时无音频
问题:树莓派Zero 2W音视频录制整合后无音频输出
我使用树莓派Zero 2W连接了Adafruit MEMS麦克风和摄像头,单独测试音频录制的Python程序功能完全正常,代码如下:
import subprocess import threading import os audio_process = None stop_recording_flag = False audio_filename = "test.wav" def record_audio(): global audio_process, stop_recording_flag env = os.environ.copy() env["HOME"] = os.path.expanduser("~") print("Recording... Type 'stop' and press Enter to stop.") audio_process = subprocess.Popen([ "arecord", "-D", "dmic_sv", "-c", "2", "-r", "48000", "-f", "S32_LE", "-t", "wav", audio_filename ], env=env) # Wait until user types 'stop' while not stop_recording_flag and audio_process.poll() is None: pass if audio_process.poll() is None: print("Stopping recording...") audio_process.terminate() try: audio_process.wait(timeout=5) except subprocess.TimeoutExpired: audio_process.kill() print(f"Recording saved to {audio_filename}") def monitor_input(): global stop_recording_flag while True: command = input().strip().lower() if command == "stop": stop_recording_flag = True break if __name__ == "__main__": t1 = threading.Thread(target=record_audio) t2 = threading.Thread(target=monitor_input) t1.start() t2.start() t1.join() t2.join()
但将该音频录制逻辑整合到同时录制音视频并混流的主程序后,视频录制正常,但audio.wav文件及最终生成的视频中均无音频输出。已确认麦克风功能正常,混流逻辑也无问题,可以确定问题出在音频录制的线程启动方式上,以下是简化后的主程序代码:
import time import subprocess import threading from picamera2 import Picamera2 from PIL import Image, ImageDraw import RPi.GPIO as GPIO video_selected_index = 0 is_recording = False framerate = 30 video_filename = "/home/pi/video.h264" audio_wav_filename = "/home/pi/audio.wav" final_filename = "" picam = None audio_process = None audio_thread = None video_thread = None font = None # 需根据实际场景初始化字体对象 display = None # 需根据实际场景初始化显示屏对象 video_resolutions = [] # 需提前定义分辨率选项列表,格式为[(标签, 配置), ...] def recording_ui_updater(): # 需补充UI状态更新逻辑 pass def record_video(config): # 需补充视频录制核心逻辑 pass def wait_for_button_release(pin): while GPIO.input(pin) == GPIO.LOW: time.sleep(0.01) def recording_status(status_text): # 需补充录制状态显示逻辑 pass def record_audio(): global audio_process, is_recording try: print(" [record_audio] Starting audio capture, Sir.") env = os.environ.copy() env["HOME"] = os.path.expanduser("~") audio_process = subprocess.Popen([ "arecord", "-D", "dmic_sv", "-c", "2", "-r", "48000", "-f", "S32_LE", "-t", "wav", audio_wav_filename ], env=env) # Wait for is_recording to turn False while is_recording: time.sleep(0.1) if audio_process.poll() is None: print(" [record_audio] Terminating arecord…") audio_process.terminate() try: audio_process.wait(timeout=5) except subprocess.TimeoutExpired: audio_process.kill() print(f" [record_audio] Audio saved to {audio_wav_filename}, Sir.") except Exception as e: print(f" [record_audio] Exception, Sir: {e}") def start_recording(config): """ Launch audio + video threads (non-daemon), with a slight stagger. """ global is_recording, audio_thread, video_thread is_recording = True # Start UI updater thread (could remain daemon) threading.Thread(target=recording_ui_updater, daemon=True).start() # Create *non-daemon* threads for audio & video so they run fully audio_thread = threading.Thread(target=record_audio, daemon=False) video_thread = threading.Thread(target=record_video, args=(config,), daemon=False) # Start audio first, give it time to initialize DMIC audio_thread.start() time.sleep(0.1) # Now start video capture video_thread.start() def stop_recording(): """ Signal both threads to finish, then join. """ global is_recording is_recording = False print(" [stop_recording] Signaled threads to stop.") recording_status("Muxing...") if audio_thread: audio_thread.join() # Give time for OS to flush file buffers time.sleep(0.5) # Crucial if video_thread: print(" [stop_recording] Joining video thread…") video_thread.join() print(" [stop_recording] Threads joined, proceeding to mux.") mux_audio_video() def show_take_video_menu(): global video_selected_index, is_recording, picam try: picam = Picamera2() picam.configure(picam.create_still_configuration()) picam.start() time.sleep(2) # Camera warm-up except Exception as e: print(f"Camera initialization failed: {e}") return while True: if not is_recording: # Draw resolution menu img = Image.new("RGB", (160, 80), "black") draw = ImageDraw.Draw(img) title = "Take Video" title_width = draw.textlength(title, font=font) draw.text(((160 - title_width) // 2, 2), title, font=font, fill="red") for i, (label, _) in enumerate(video_resolutions): prefix = "> " if i == video_selected_index else " " draw.text((10, 18 + i * 14), prefix + label, font=font, fill="red") display.display(img) # Button controls if GPIO.input(21) == GPIO.LOW: # UP wait_for_button_release(21) video_selected_index = (video_selected_index - 1) % len(video_resolutions) elif GPIO.input(12) == GPIO.LOW: # DOWN wait_for_button_release(12) video_selected_index = (video_selected_index + 1) % len(video_resolutions) elif GPIO.input(16) == GPIO.LOW: # SELECT wait_for_button_release(16) label, config = video_resolutions[video_selected_index] if is_recording: stop_recording() continue if label.lower() == "return": if is_recording: stop_recording() print("Exiting video menu.") picam.close() return if config: start_recording(config) time.sleep(0.1) # Input debounce delay def mux_audio_video(): global final_filename, framerate timestamp = time.strftime("%Y%m%d_%H%M%S") final_filename = f"/home/pi/Videos/recording_{timestamp}.mp4" subprocess.run([ "ffmpeg", "-y", "-framerate", str(framerate), "-i", video_filename, "-i", audio_wav_filename, "-metadata:s:v", "rotate=270", "-c:v", "copy", "-c:a", "aac", "-shortest", final_filename ], check=True) print(f"Muxed to {final_filename}")
内容的提问来源于stack exchange,提问作者symmetrical pattern with teal
相关产品推荐
相关产品推荐

