Linux (ubuntu) 下如何通过 c++代码录制系统声音(不是 Mic 输入)

2023-03-17 14:48:32 +08:00
 daijinming

最近有个在 Linux 下录音的功能需要开发,通过 C++代码调用可以实现对系统声音的录制,也就是输出声音的录制,不是 Mic 的输入声音,请教下各位

2026 次点击
所在节点    程序员
12 条回复
kokutou
2023-03-17 14:59:07 +08:00
看看 obs 怎么做的
cogear
2023-03-17 15:06:24 +08:00
您好,您可以使用 ALSA 库来实现 Linux 下的录音功能。ALSA 是 Linux 下的音频驱动程序,它提供了一组 API ,可以用于录制和播放音频。您可以使用 ALSA 库来实现对系统声音的录制,也就是输出声音的录制,不是 Mic 的输入声音。这里有一篇关于使用 ALSA 库实现 Linux 下录音的文章,您可以参考一下:1 。

如果您想要更加深入地了解 ALSA 库,您可以参考 ALSA 官方文档:2 。

希望这可以帮到您。如果您有任何其他问题,请随时问我。

---

来自 new bing
cogear
2023-03-17 15:08:45 +08:00
lieyan
2023-03-17 15:21:50 +08:00
自己写一个虚拟声卡驱动或者是麦克风驱动
AlynxZhou
2023-03-17 16:29:21 +08:00
你查一下 pulseaudio 或者 pipewire 的接口,现在比较新的系统都用 pipewire 混音,老的用 pulseaudio ,这个足够录 session 级别的声音了。
Jokeoo
2023-03-17 17:46:43 +08:00
在 Linux ( Ubuntu )下,可以使用 PulseAudio 库来捕获系统声音。以下是一个简单的示例代码片段,可以通过 g++编译:

```
#include <pulse/simple.h>
#include <pulse/error.h>
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;

#define BUFSIZE 1024

int main(int argc, char const *argv[]) {
pa_sample_spec ss;
ss.format = PA_SAMPLE_S16LE;
ss.channels = 2;
ss.rate = 44100;
int error;
pa_simple *s = pa_simple_new(NULL, argv[0], PA_STREAM_RECORD, NULL, "record", &ss, NULL, NULL, &error);
if (!s) {
cerr << "pa_simple_new() failed: " << pa_strerror(error) << endl;
return 1;
}

char buf[BUFSIZE];
int cnt = 0;
while (cnt++ < 100) {
int ret = pa_simple_read(s, buf, BUFSIZE, &error);
if (ret < 0) {
cerr << "pa_simple_read() failed: " << pa_strerror(error) << endl;
break;
}
fwrite(buf, 1, ret, stdout);
}

pa_simple_free(s);
return 0;
}

```

该代码将捕获系统声音,并将其输出到标准输出( stdout )。您可以将其修改为将音频写入文件或进行其他处理。

notion AI
L4Linux
2023-03-17 19:02:16 +08:00
@AlynxZhou 就是你们这种人多了,害得我这个只用 ALSA 的人遇到各种问题。除了蓝牙,我想不出 ALSA 哪里不能用了。
AlynxZhou
2023-03-17 20:52:42 +08:00
@L4Linux 楼主问问题,我按照我的理解给他线索,哪里惹着你了?你自己觉得自己有能耐非要和大众用不一样的东西,那你就应该能自己解决,别来这里怪别人需求和你不一样。我不但要用蓝牙,还要一边放音乐一边看视频,我还要用 JACK 录音,我还要用插件加特效混音,只有 ALSA 怎么用?
L4Linux
2023-03-17 22:17:13 +08:00
@AlynxZhou 1 、你没有惹着我,但是本来直接用 ALSA 本来很好,在 xxx 新框架出来之后越来越糟,以及造成这种现状的社区惹着我了。
2 、ALSA 是 kernel module ,你以为你只用了 pipewire ,实际上还是在用 ALSA 。
3 、我不可能今天 ALSA 没声音了去改 ALSA 的代码,明天 UHD 630 卡出屎了又去改显卡驱动等等。
4 、都用 linux 了还谈大众也比较可笑。
5 、只有 ALSA 没法用是社区的问题,社区今天推出了 PulseAudio ,明天又搞了 pipewire 。

最后回到 po 的问题,直接用 ALSA 就行了
万一别人没用 pipewire ,用 pipewire 录了个寂寞。
dw2693734d
2023-03-17 23:01:15 +08:00
#include <iostream>
#include <pulse/simple.h>
#include <pulse/error.h>
#include <fstream>

int main() {
const char* fileName = "output.raw";
std::ofstream outFile(fileName, std::ios::binary);

pa_sample_spec sampleSpec;
sampleSpec.format = PA_SAMPLE_S16LE;
sampleSpec.rate = 44100;
sampleSpec.channels = 2;

pa_simple *pulseAudioSimple = nullptr;
int error;

pulseAudioSimple = pa_simple_new(NULL, "record_system_audio", PA_STREAM_RECORD, NULL, "record", &sampleSpec, NULL, NULL, &error);
if (!pulseAudioSimple) {
std::cerr << "Error: Could not create PulseAudio simple:" << pa_strerror(error) << std::endl;
return 1;
}

const size_t numSamples = 44100 * 10; // Record for 10 seconds
int16_t buffer[numSamples];

if (pa_simple_read(pulseAudioSimple, buffer, sizeof(buffer), &error) < 0) {
std::cerr << "Error: Could not read from PulseAudio: " << pa_strerror(error) << std::endl;
pa_simple_free(pulseAudioSimple);
return 1;
}

outFile.write(reinterpret_cast<char*>(buffer), sizeof(buffer));

pa_simple_free(pulseAudioSimple);
outFile.close();

std::cout << "System audio has been recorded successfully. Output saved to " << fileName << std::endl;
return 0;
}
flyqie
2023-03-18 03:01:23 +08:00
@L4Linux #9

看了你的回复,不太理解,pulseaudio 及 pipewire 是怎么导致 alsa 越来越糟?

alsa 分 kernel 和 user 两部分,正常开发基本都用 user 这边的东西吧,怎么会越来越糟,这部分应该是无感的呀,pulseaudio 和 pipewire 不都会对 libalsa 做配置修改来保证所有操作全走他俩吗。

况且,pulseaudio 和 pipewire 作用难道不是使得 linux 音频这边的架构更加解耦了吗?能够更方便的通过统一体系去处理不同场景中不同的音频设备。
L4Linux
2023-03-18 11:22:47 +08:00
@flyqie 你不用当然没感觉,一是 alsa 渐渐没人维护了啊。有些东西是发现 alsa 实现得不好的,但没人改进,都去维护 pulseaudio 、pipewire 或 jack 去了。还有一个是上层软件。比如 firefox 用 alsa 时 mic 没声音,但以前没有这个问题。用 apulse 假装在用 pulseaudio 的话也没问题。alsa 真的干不好这些事情吗?最后,你以为是用同一体系去处理音频,实际上有 5 个体系去处理。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/924865

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX