我无法在 java

如何解决我无法在 java

我知道这个问题与 StackOverflow 上的另一个问题重复,我尽我所能理解捕获混音器音频背后的概念,但直到现在我才能录制我的电脑系统音频。

>

我访问过的网站以了解该概念:

1-https://docs.oracle.com/javase/tutorial/sound/capturing.html

2-https://www.developer.com/java/other/article.php/1579071/Java-Sound-Getting-Started-Part-2-Capture-Using-Specified-Mixer.htm

3-https://www.youtube.com/watch?v=GVtl19L9GxU

我访问过的 StackOverFlow 问题:

1-Recording speakers Ouput using Java

2-How to get TargetDataLine from Speakers?

3-Recording System Audio via Java

4-Capture audio going to speakers

我已尽力理解使用 API 的概念,但在遇到这个问题之前我仍然无法捕获任何音频:

Java: Processing audio in real time from speakers

此人试图迭代混音器并找到合适的混音器“扬声器”并将其用于他的代码。他的代码如下所示:


package audio;
import javax.sound.sampled.*;

public class App1 {
    public static String getWord(String arr) {
        int i = 0;
        for(; i < arr.length(); i++) {
            if (arr.charat(i) == ' ')
                break;
        }
        return arr.substring(0,i);
    }

    public static void wait(int ms) {
        try{
            Thread.sleep(ms);
        }
        catch(InterruptedException ex){
            Thread.currentThread().interrupt();
        }
    }

    public static AudioFormat getAudioFormat(){
        float sampleRate = 44100;
        //8000,11025,16000,22050,44100
        int sampleSizeInBits = 16;
        //8,16
        int channels = 1;
        //1,2
        boolean signed = true;
        //true,false
        boolean bigEndian = false;
        //true,false
        //return new AudioFormat(Encoding.PCM_SIGNED,sampleRate,16,1,2,false);
        return new AudioFormat(sampleRate,sampleSizeInBits,channels,signed,bigEndian);
    }

    public static void main(String [] args) {
        try {
            //-----DECLaraTIONS-----
            TargetDataLine targetDataLine = null;
            mixer.Info[] mixers = AudioSystem.getmixerInfo();
            mixer.Info m = null;
            String expectedmixer = "Speakers";      

            //-----mixer FINDER-----
            System.out.println("Number of mixers: " + mixers.length);
            for(int i = 0; i < mixers.length; i++) {
                System.out.println(getWord(mixers[i].getName()));
                if(getWord(mixers[i].getName()).compareto(expectedmixer) == 0){
                    m = mixers[i];
                }
            }
            if(m==null) throw new Exception("No such mixer found: " + expectedmixer);
            else System.out.println('\n'+"Device choosen: "+m.getName());

            //-----LINE TESTER-----
            boolean v = false,showError = true; // show error or keep trying several times
            int tries = 3,i = 0;
            while(v==false && i++ < tries){
                try {
                    //sourceDataLine = AudioSystem.getTargetDataLine(getAudioFormat(),m);
                    targetDataLine = AudioSystem.getTargetDataLine(getAudioFormat(),m);
                    targetDataLine.open(getAudioFormat());
                    v=true;
                    //System.out.println("Success!");
                } catch (IllegalArgumentException e){
                    if (showError) {
                        v = true;
                        e.printstacktrace();
                    }
                    else {
                        System.out.println("Error! retrying...  "+i+'/'+tries);
                        v = false;
                    }
                    wait(2000);
                }
            }
            if(i-1==tries)
                //System.out.println("No success :(");
                throw new Exception("No success :(");
            else
                if(v==false)
                    System.out.println("SourceData line found and accepted !");

            //-----SIGNAL PROCESSING-----
            //nothing here because the rest isn't working

        } catch(Exception e) { e.printstacktrace();} 
    }
}

我注意到在第 67 行 targetDataLine = AudioSystem.getTargetDataLine(getAudioFormat(),m); 他正在使用带有 2 个参数的 getTargetDataLine,如果您删除了第二个参数 (m) 代码继续执行并且没有出现错误......(“我的错误可能来自这里”)

我重新修改代码删除了 (m) 参数并将 data-target-line 设为静态和全局并添加了我自己的其他修改以开始录制系统音频 10 秒(我确定我做到了这样做时犯了一个错误,但我真的不知道),:



import java.io.File;
import java.io.IOException;
import java.util.Arrays;

import javax.sound.sampled.*;

public class App1 {

    static TargetDataLine targetDataLine = null;
    AudioFileFormat.Type fileType = AudioFileFormat.Type.WAVE;

    static DataLine.Info info = new DataLine.Info(SourceDataLine.class,getAudioFormat());

    public static String getWord(String arr) {
        int i = 0;
        for (; i < arr.length(); i++) {
            if (arr.charat(i) == ' ')
                break;
        }
        return arr.substring(0,i);
    }

    public static void wait(int ms) {
        try {
            Thread.sleep(ms);
        } catch (InterruptedException ex) {
            Thread.currentThread().interrupt();
        }
    }

    public static AudioFormat getAudioFormat() {
        float sampleRate = 48000;
        // 8000,44100
        int sampleSizeInBits = 16;
        // 8,16
        int channels = 2;
        // 1,2
        boolean signed = true;
        // true,false
        boolean bigEndian = false;
        // true,false
        // return new AudioFormat(Encoding.PCM_SIGNED,// false);
        return new AudioFormat(sampleRate,bigEndian);
    }

    static void showLineInfoFormats(final Line.Info lineInfo) {
        if (lineInfo instanceof DataLine.Info) {
            final DataLine.Info dataLineInfo = (DataLine.Info) lineInfo;

            Arrays.stream(dataLineInfo.getFormats()).forEach(format -> System.out.println("    " + format.toString()));
        }
    }

    public static void main(String[] args) throws LineUnavailableException,IOException,InterruptedException {
        try {
            // -----DECLaraTIONS-----

            mixer.Info[] mixers = AudioSystem.getmixerInfo();
            mixer.Info m = null;
            String expectedmixer = "Speakers";

            // -----mixer FINDER-----
            System.out.println("Number of mixers: " + mixers.length);
            for (int i = 0; i < mixers.length; i++) {
                System.out.println(getWord(mixers[i].getName()));
                if (getWord(mixers[i].getName()).compareto(expectedmixer) == 0) {
                    m = mixers[i];
                }
            }
            if (m == null)
                throw new Exception("No such mixer found: " + expectedmixer);
            else
                System.out.println('\n' + "Device choosen: " + m.getName());

            // showLineInfoFormats(info);

            // -----LINE TESTER-----
            boolean v = false,i = 0;
            while (v == false && i++ < tries) {
                try {
                    // sourceDataLine = AudioSystem.getTargetDataLine(getAudioFormat(),m);
                    targetDataLine = AudioSystem.getTargetDataLine(getAudioFormat());

                    targetDataLine = (TargetDataLine) ((mixer) m).getLine(info);

                    targetDataLine.open(getAudioFormat());

                    v = true;
                    // System.out.println("Success!");
                } catch (IllegalArgumentException e) {
                    if (showError) {
                        v = true;
                        e.printstacktrace();
                    } else {
                        System.out.println("Error! retrying...  " + i + '/' + tries);
                        v = false;
                    }
                    wait(2000);
                }
            }
            if (i - 1 == tries)
                // System.out.println("No success :(");
                throw new Exception("No success :(");
            else if (v == false)
                System.out.println("SourceData line found and accepted !");

            // -----SIGNAL PROCESSING-----
            // nothing here because the rest isn't working

        } catch (Exception e) {
            e.printstacktrace();
        }
        System.out.println("We are here");

        // targetDataLine.open();
        System.out.println("Starting REcord");
        targetDataLine.start();
        System.out.println("targetDataLine.start() finished");
        Thread thread = new Thread();
        {
            run();
            System.out.println("run() finished");
        }

        thread.start();
        System.out.println("thread.start() finished");
        Thread.sleep(10000);
        System.out.println("Thread.sleep(5000) finished");
        targetDataLine.stop();
        System.out.println("targetDataLine.stop() finished");
        targetDataLine.close();
        System.out.println("NO WAAAAAAAAAAY!!!");

    }

    private static void run() throws IOException {
        AudioInputStream audioStream = new AudioInputStream(targetDataLine);// issue maybe?
        File wavFile = new File("E:/Test/RecordAudio.wav");

        AudioSystem.write(audioStream,AudioFileFormat.Type.WAVE,wavFile);

    }

}

您可以看到我添加了一些 System.out.println() 语句来指示代码的结束位置。

现在我收到此错误消息的问题:

Error 1

java.lang.classCastException:类 com.sun.media.sound.DirectAudioDeviceProvider$DirectAudioDeviceInfo 不能转换为类 javax.sound.sampled.mixer(com.sun.media.sound.DirectAudioDeviceProvider$DirectAudioDeviceInfo 和 javax.sound.sound.sampled.mixer。 sampled.mixer 在 loader 'bootstrap' 的模块 java.desktop 中) 在 Test2.App1.main(App1.java:88)

输出“RecordAudio.wav”不播放任何内容,甚至不到 10 秒。

所以我认为我对 TargetDataLine 的声明是错误的,因为这个答案指出 How to get TargetDataLine from Speakers?

所以我将 static TargetDataLine targetDataLine = null; 更改为 static SourceDataLine targetDataLine = null; 并对其进行了其他相关更改,最后使代码看起来像这样...



import java.io.File;
import java.io.IOException;
import java.util.Arrays;

import javax.sound.sampled.*;

public class App1 {

    static SourceDataLine targetDataLine = null;
    AudioFileFormat.Type fileType = AudioFileFormat.Type.WAVE;

    static DataLine.Info info = new DataLine.Info(SourceDataLine.class,m);
                    targetDataLine = (SourceDataLine) AudioSystem.getTargetDataLine(getAudioFormat());

                    targetDataLine = (SourceDataLine) ((mixer) m).getLine(info);

                    targetDataLine.open(getAudioFormat());

                    v = true;
                    // System.out.println("Success!");
                } catch (IllegalArgumentException e) {
                    if (showError) {
                        v = true;
                        e.printstacktrace();
                    } else {
                        System.out.println("Error! retrying...  " + i + '/' + tries);
                        v = false;
                    }
                    wait(2000);
                }
            }
            if (i - 1 == tries)
                // System.out.println("No success :(");
                throw new Exception("No success :(");
            else if (v == false)
                System.out.println("SourceData line found and accepted !");

            // -----SIGNAL PROCESSING-----
            // nothing here because the rest isn't working

        } catch (Exception e) {
            e.printstacktrace();
        }
        System.out.println("We are here");

        // targetDataLine.open();
        System.out.println("Starting REcord");
        targetDataLine.start();
        System.out.println("targetDataLine.start() finished");
        Thread thread = new Thread();
        {
            run();
            System.out.println("run() finished");
        }

        thread.start();
        System.out.println("thread.start() finished");
        Thread.sleep(10000);
        System.out.println("Thread.sleep(5000) finished");
        targetDataLine.stop();
        System.out.println("targetDataLine.stop() finished");
        targetDataLine.close();
        System.out.println("NO WAAAAAAAAAAY!!!");

    }

    private static void run() throws IOException {
        AudioInputStream audioStream = new AudioInputStream((TargetDataLine) targetDataLine);// issue maybe?
        File wavFile = new File("E:/Test/RecordAudio.wav");

        AudioSystem.write(audioStream,wavFile);

    }

}

现在我收到此错误

Error2

java.lang.classCastException:类 com.sun.media.sound.DirectAudioDevice$DirectTDL 不能转换为类 javax.sound.sampled.sourceDataLine(com.sun.media.sound.DirectAudioDevice$DirectTDL 和 javax.sound.sampled.sourceDataLine位于加载程序“引导程序”的模块 java.desktop 中) 在 Test2.App1.main(App1.java:86)

线程“main”中的异常java.lang.NullPointerException:无法调用“javax.sound.sampled.sourceDataLine.start()”,因为“Test2.App1.targetDataLine”为空 在 Test2.App1.main(App1.java:121)

我想到并尝试过的其他事情: 我认为我的问题可能来自音频格式,所以我使用此代码查看我的认扬声器音频格式

import javax.sound.sampled.*;

public class AudioFormatChecker {

    public static void main(String[] args) throws LineUnavailableException {
        mixer mixer = AudioSystem.getmixer(null); // default mixer
        mixer.open();

        System.out.printf("Supported SourceDataLines of default mixer (%s):\n\n",mixer.getmixerInfo().getName());
        for (Line.Info info : mixer.getSourceLineInfo()) {
            if (SourceDataLine.class.isAssignableFrom(info.getLineClass())) {
                SourceDataLine.Info info2 = (SourceDataLine.Info) info;
                System.out.println(info2);
                System.out.printf("  max buffer size: \t%d\n",info2.getMaxBufferSize());
                System.out.printf("  min buffer size: \t%d\n",info2.getMinBufferSize());
                AudioFormat[] formats = info2.getFormats();
                System.out.println("  Supported Audio formats: ");
                for (AudioFormat format : formats) {
                    System.out.println("    " + format);
                }
                System.out.println();
            } else {
                System.out.println(info.toString());
            }
            System.out.println();
        }

        mixer.close();
    }
}

我尽我最大的努力去理解和实现声音 API 的概念,但我做不到。我使用声音 API 的主要目的是从系统中捕获音频,然后将其用于其他目的。我尝试录制系统,以便我可以测试我在程序中管理的内容是否确实有效,并且我的程序是否正在录制音频。

我也不明白,为什么互联网上的任何地方都没有针对此类常见问题的有效样本???

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?