嵌入式Linux C中LVGL触摸应用的音频播放切换优化方案咨询
解决方案
方案1:自行维护音频进程PID(优化你的初步想法)
直接用fork()+exec()替代system(),这样能直接获取并保存aplay的进程ID,切换音频时精准终止旧进程,避免误杀或查找进程的麻烦:
#include <stdio.h> #include <stdlib.h> #include <signal.h> #include <unistd.h> #include <sys/wait.h> pid_t active_audio_pid = 0; void play_new_audio(const char* audio_path) { // 终止正在运行的音频进程 if (active_audio_pid != 0) { kill(active_audio_pid, SIGTERM); // 非阻塞等待进程退出,清理僵尸进程 waitpid(active_audio_pid, NULL, WNOHANG); active_audio_pid = 0; } // 启动新的音频播放进程 pid_t pid = fork(); if (pid == 0) { // 子进程执行aplay execlp("aplay", "aplay", audio_path, NULL); // 执行失败则退出子进程 perror("Failed to start aplay"); exit(EXIT_FAILURE); } else if (pid > 0) { // 父进程保存新的PID active_audio_pid = pid; } else { perror("Fork failed"); } }
调用play_new_audio("bear/animalnoise.wav")即可切换音频,这个方式比用system()+查PID可靠得多,不会误杀其他无关的aplay进程。
方案2:使用音频库替代外部aplay进程
这是更优的长期方案,直接在程序内调用音频库(比如ALSA、SDL2_mixer或GStreamer)播放音频,完全避免外部进程的管理问题:
- ALSA是Linux系统原生音频库,适合底层控制,能直接停止当前播放流并启动新的音频播放
- SDL2_mixer封装更友好,支持多种音频格式,上手更快
- 这类库可以和LVGL并行运行,互不干扰,稳定性和可控性远高于调用外部进程
比如用ALSA的核心API,你可以实现音频的启停、切换逻辑,完全在进程内部完成,不会出现多进程冲突的报错。
方案3:不推荐的临时 workaround
如果暂时不想改代码结构,也可以用pkill aplay强制终止所有aplay进程后再启动新的,但这个方式风险高——如果系统内有其他程序在运行aplay,会被误杀,只适合测试或单一用途的设备。
内容的提问来源于stack exchange,提问作者Liamm36
相关产品推荐
相关产品推荐

