如何在Rust中捕获另一个应用程序当前播放的音频?

huangapple go评论126阅读模式
英文:

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: &amp;str) -&gt; Result&lt;PCM, Error&gt; {
    let pcm = PCM::new(device, Direction::Capture, false)?;
    {
        // For this example, we assume 44100Hz, one channel, 16 bit audio.
        let hwp = HwParams::any(&amp;pcm)?;
        hwp.set_channels(1)?;
        hwp.set_rate(44100, ValueOr::Nearest)?;
        hwp.set_format(Format::s16())?;
        hwp.set_access(Access::RWInterleaved)?;
        pcm.hw_params(&amp;hwp)?;
    }
    pcm.start()?;
    Ok(pcm)
}

fn read(pcm: &amp;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(&amp;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(&quot;output3.wav&quot;, spec).unwrap();
    for sample in buffer {
        writer.write_sample(sample).unwrap();
    }
}

fn main() {

    let capture = start_capture(&quot;default&quot;).unwrap();
    read(&amp;capture);
}

huangapple
  • 本文由 发表于 2023年2月27日 12:42:19
  • 转载请务必保留本文链接:https://go.coder-hub.com/75576834.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定