Java Sound API 是否可以访问其他(非 Java)应用程序正在播放的声音?

Wil*_*rne 5 java audio javasound audio-recording

过去几周我一直在阅读 Java Sound API,但我仍然不知道这是否可行。我之所以这么问是因为我想编写一个程序,该程序将通过系统的声音数据传送到输出线路,例如计算机的扬声器或耳机插孔,并将该数据写入音频文件。

从我读迄今约javax.sound.sampled,好像我可以从数据只读Mixer通过TargetDataLine; 然而,在编写了一个测试程序(下面提供)来查询我的系统以获取可用的混合器,然后查询这些混合器以获取可用的目标和源数据线;我意识到我所有的输出混音器除了我的默认混音器只支持SourceDataLines。此外,我无法判断TargetDataLine计算机的默认混音器(我有一台 Macbook pro)是否可以读取从其他应用程序发送到混音器的音频数据。所以在我深入研究这个项目之前,我想弄清楚是否有可能访问其他应用程序通过混音器发送的声音。

测试程序

import javax.sound.sampled.*;
import java.util.Scanner;

public class Capture {
    public static final String ANSI_RED = "\u001B[31m";
    public static final String ANSI_GREEN = "\u001B[32m";
    public static final String ANSI_RESET = "\u001B[m";

    private Mixer mixer;

    public Capture() {
        Mixer.Info[] installedMixers = AudioSystem.getMixerInfo();
        for(int n = 0; n < installedMixers.length; n++) {
            System.out.println(ANSI_GREEN + "[" + n + "] " + ANSI_RESET + installedMixers[n].toString());
        }
        while(mixer == null) {
            int choice;
            try {
                System.out.print("Choose a mixer: ");
                Scanner s = new Scanner(System.in);
                choice = s.nextInt();
                if(choice >= 0 && choice < installedMixers.length)
                    mixer = AudioSystem.getMixer(installedMixers[choice]);
                else
                    System.out.println(ANSI_RED + "Invalid Choice!" + ANSI_RESET);
            } catch(RuntimeException e) {
                System.out.println(ANSI_RED + "Please input an integer corresponding to your mixer choice." + ANSI_RESET);
            }
        }
        System.out.println(ANSI_RED + "Source Lines:" + ANSI_RESET);
        Line.Info[] sourceLines = mixer.getSourceLineInfo();
        if(sourceLines.length == 0) {
            System.out.println("None");
        }
        for(int n = 0; n < sourceLines.length; n++) {
            System.out.println(ANSI_GREEN + "[" + n + "] " + ANSI_RESET + sourceLines[n].toString());
        }
        System.out.println(ANSI_RED + "Target Lines:" + ANSI_RESET);
        Line.Info[] targetLines = mixer.getTargetLineInfo();
        if(targetLines.length == 0) {
            System.out.println("None");
        }
        for(int n = 0; n < targetLines.length; n++) {
            System.out.println(ANSI_GREEN + "[" + n + "] " + ANSI_RESET + targetLines[n].toString());
        }

    }

    public static void main(String[] args) {
        Capture recording = new Capture();
    }
}
Run Code Online (Sandbox Code Playgroud)

PS我发现了与这个确切主题相关的另外两个问题,这些问题似乎根本没有提供解决方案。一个从未得到回答,另一个有一个对提问者不起作用的解决方案,而且我无法重现。