You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

嵌入式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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 13:03:16