英文:
How do I capture currently playing audio from another application in Rust?
问题
我想在我的Rust项目中捕获另一个应用程序(例如Chrome)中播放的音频,以构建音频可视化。
我尝试过cpal
库,可以录制来自麦克风的音频并保存它,但我找不到任何方法来录制来自另一个源(例如Chrome)的音频。
平台:Linux,Pipewire和Alsa。
英文:
I want to capture the audio playing in another application e.g Chrome in my Rust project - to build an audio visualizer.
I have tried the cpal
crate and I could record audio from the microphone and save it but I can't find any way to record audio from another source like Chrome.
Platform: Linux, Pipewire and Alsa
答案1
得分: 1
我发现您可以使用alsa
Rust库和hound
crate来保存WAV文件。
另外,在pavucontrol
- 一个用于控制Pulseaudio的GUI应用程序中,当您运行以下程序时,请确保在录音选项卡中更改应用程序的设备为扬声器。
捕获并保存10秒音频的示例:
// 改编自alsa-rs的GitHub示例
use alsa::pcm::*;
use alsa::{Direction, Error, ValueOr};
use hound::{SampleFormat, WavWriter};
fn start_capture(device: &str) -> Result<PCM, Error> {
let pcm = PCM::new(device, Direction::Capture, false)?;
{
// 对于此示例,我们假设为44100Hz,一个通道,16位音频。
let hwp = HwParams::any(&pcm)?;
hwp.set_channels(1)?;
hwp.set_rate(44100, ValueOr::Nearest)?;
hwp.set_format(Format::s16())?;
hwp.set_access(Access::RWInterleaved)?;
pcm.hw_params(&hwp)?;
}
pcm.start()?;
Ok(pcm)
}
fn read(pcm: &PCM) {
let io = pcm.io_i16().unwrap();
let num_samples = 44100 * 10;
let mut buffer = vec![0i16; num_samples];
for i in 0..num_samples {
let sample = io.readi(&mut buffer[i..i + 1]).unwrap();
if sample == 0 {
break;
}
}
let spec = hound::WavSpec {
channels: 1,
sample_rate: 44100,
bits_per_sample: 16,
sample_format: SampleFormat::Int,
};
let mut writer = WavWriter::create("output3.wav", spec).unwrap();
for sample in buffer {
writer.write_sample(sample).unwrap();
}
}
fn main() {
let capture = start_capture("default").unwrap();
read(&capture);
}
英文:
I found that you can use the alsa
rust libray and hound
crate to save the wav file.
Also, in pavucontrol
- a gui application to control Pulseaudio, when you run the following program, make sure to change the device in the recording tab for your application to the speaker.
An example to capture 10 seconds of audio and save it:
// Adapted from alsa-rs github examples
use alsa::pcm::*;
use alsa::{Direction, Error, ValueOr};
use hound::{SampleFormat, WavWriter};
fn start_capture(device: &str) -> Result<PCM, Error> {
let pcm = PCM::new(device, Direction::Capture, false)?;
{
// For this example, we assume 44100Hz, one channel, 16 bit audio.
let hwp = HwParams::any(&pcm)?;
hwp.set_channels(1)?;
hwp.set_rate(44100, ValueOr::Nearest)?;
hwp.set_format(Format::s16())?;
hwp.set_access(Access::RWInterleaved)?;
pcm.hw_params(&hwp)?;
}
pcm.start()?;
Ok(pcm)
}
fn read(pcm: &PCM) {
let io = pcm.io_i16().unwrap();
let num_samples = 44100 * 10;
let mut buffer = vec![0i16; num_samples];
for i in 0..num_samples {
let sample = io.readi(&mut buffer[i..i + 1]).unwrap();
if sample == 0 {
break;
}
}
let spec = hound::WavSpec {
channels: 1,
sample_rate: 44100,
bits_per_sample: 16,
sample_format: SampleFormat::Int,
};
let mut writer = WavWriter::create("output3.wav", spec).unwrap();
for sample in buffer {
writer.write_sample(sample).unwrap();
}
}
fn main() {
let capture = start_capture("default").unwrap();
read(&capture);
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论