JavaFX - Während AudioRecording keine Text eingabe TextField möglich

Goekhan

Mitglied
Ich versuche über Audio aufnehmen, was auch klappt, jedoch während der Aufnahme friert alles ein und erst nach der Beendigung der Aufnahme kann ich wieder Text eingeben. Wo Genau muss ich den Thread einbauen, damit mir das nicht passiert?

Java:
public class Main extends Application {
      Boolean isRecording = false;

       @Override
       public void start(Stage primaryStage) throws Exception  {
           try {

               VBox root = new VBox();
               root.setPadding(new Insets(20));
               root.setSpacing(20);

               Button btn = new Button("RECORD");
               btn.setOnAction(e->{
                   if(!isRecording){
                       isRecording = true;
                       AudioRecorder audioRecorder = new AudioRecorder(10000);
                   }
               });

               TextField tf = new TextField();

               root.getChildren().addAll(btn,tf);
               Scene scene = new Scene(root, 400, 400);
               primaryStage.setScene(scene);
               primaryStage.show();
           } catch(Exception e) {
               e.printStackTrace();
           }
       }

       public static void main(String[] args) {
           launch(args);
       }
   }

Die AudioRecorder Klasse sieht so aus. Ich habe hier ein Thread schon eingebaut. Trotzdem friert es ein:

Java:
package audioRecording_1;

import java.io.File;
import java.io.IOException;

import javax.sound.sampled.AudioFileFormat;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.TargetDataLine;

public class AudioRecorder {

    final long recordTime;
    private AudioInputStream targetLine;

    public AudioRecorder(long recordTime)
    {
        this.recordTime = recordTime;
        System.out.println("AUDIO RECORDING START:");

        try {
            AudioFormat format = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, 44100, 16, 2, 4, 44100, false);
            DataLine.Info info = new DataLine.Info(TargetDataLine.class, format);
            if(!AudioSystem.isLineSupported(info)){
                System.err.println("Line not supported");
            }
            final TargetDataLine targetLine = (TargetDataLine)AudioSystem.getLine(info);
            targetLine.open();

            System.out.println("Start Recording: ");
            targetLine.start();

             File desktopDir = new File(System.getProperty("user.home"), "Desktop");
             System.out.println(desktopDir.getPath() + " " + desktopDir.exists());


            Thread thread = new Thread(){
                @Override public void run()
                {
                    AudioInputStream audioStream = new AudioInputStream(targetLine);
                    File audioFile = new File(desktopDir.getPath(),"record.wav");
                    try {
                        AudioSystem.write(audioStream, AudioFileFormat.Type.WAVE, audioFile);
                    } catch (IOException io) {
                        io.printStackTrace();
                    }
                    System.out.println("Stopped Recording: ");
                }
            };

            thread.start();
            Thread.sleep(recordTime);
            targetLine.stop();
            targetLine.close();

            System.out.println("Ended  Recording: ");
        }
        catch (LineUnavailableException lue) { lue.printStackTrace(); }
        catch (InterruptedException ie) { ie.printStackTrace(); }
    }

    public static void main(String[] args) {}
}
 
Das Problem ist nicht wirklich die Stelle wo du den Thread eingebaut hast.
Das Problem ist folgende Zeile Thread.sleep(recordTime), damit frierst du natürlich deine GUI ein.
 
ich habe die zeile gelöscht und eine Methode angelegt die ich nach ablauf der Aufnahme Zeit aufrufe um die beiden Zeilen auszuführen. es friert nicht mehr wie du gesagt hast jedoch bekomme ich nun eine Fehlermeldung. Wie würdest du es lösen?
targetLine.stop();
targetLine.close();

ganz Konkret sieht das jetzt so aus:

Java:
package audioRecording_1;

import java.io.File;
import java.io.IOException;

import javax.sound.sampled.AudioFileFormat;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.TargetDataLine;

import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.util.Duration;

public class AudioRecorder {
   
     // 60000 = 1 minute
    final long recordTime;
    private AudioInputStream targetLine;
   
    public AudioRecorder(long recordTime)
    {
        this.recordTime = recordTime;
        System.out.println("AUDIO RECORDING START:");
       
        try {
            AudioFormat format = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, 44100, 16, 2, 4, 44100, false);
            DataLine.Info info = new DataLine.Info(TargetDataLine.class, format);
            if(!AudioSystem.isLineSupported(info)){
                System.err.println("Line not supported");
            }
            final TargetDataLine targetLine = (TargetDataLine)AudioSystem.getLine(info);
            // öffnet den kanal es zu lesen
            targetLine.open();
           
            System.out.println("Start Recording: ");
            // ließt die audio infos schreibt sie aber noch nicht in eine datei
            targetLine.start();
           
             //String userHomeFolder = System.getProperty("user.home");
           
             File desktopDir = new File(System.getProperty("user.home"), "Desktop");
             System.out.println(desktopDir.getPath() + " " + desktopDir.exists());


            Thread thread = new Thread(){
                @Override public void run()
                {
                    AudioInputStream audioStream = new AudioInputStream(targetLine);
                    File audioFile = new File(desktopDir.getPath(),"record1.wav");
                    try {
                        AudioSystem.write(audioStream, AudioFileFormat.Type.WAVE, audioFile);
                    } catch (IOException io) {
                        io.printStackTrace();
                    }
                    System.out.println("Stopped Recording: ");
                }
            };
           
            thread.start();
           
           
            Timeline timeline = new Timeline(new KeyFrame(Duration.millis(recordTime),ae -> { stopRecording(); }));
            timeline.play();
           
           
           
        }
        catch (LineUnavailableException lue) { lue.printStackTrace(); }
        //catch (InterruptedException ie) { ie.printStackTrace(); }
    }
   
    public void stopRecording(){
        System.out.println("STOP");
        try {
            ((DataLine) targetLine).stop();
            targetLine.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
   
    public static void main(String[] args) {}
}
 
Java:
java.lang.NullPointerException
    at audioRecording_1.AudioRecorder.stopRecording(AudioRecorder.java:79)
    at audioRecording_1.AudioRecorder.lambda$0(AudioRecorder.java:66)
    at audioRecording_1.AudioRecorder$$Lambda$136/1994241163.handle(Unknown Source)
    at com.sun.scenario.animation.shared.TimelineClipCore.visitKeyFrame(TimelineClipCore.java:226)
    at com.sun.scenario.animation.shared.TimelineClipCore.playTo(TimelineClipCore.java:167)
    at javafx.animation.Timeline.impl_playTo(Timeline.java:176)
    at javafx.animation.AnimationAccessorImpl.playTo(AnimationAccessorImpl.java:39)
    at com.sun.scenario.animation.shared.SingleLoopClipEnvelope.timePulse(SingleLoopClipEnvelope.java:99)
    at javafx.animation.Animation.impl_timePulse(Animation.java:1102)
    at javafx.animation.Animation$1.lambda$timePulse$25(Animation.java:186)
    at javafx.animation.Animation$1$$Lambda$134/408740998.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at javafx.animation.Animation$1.timePulse(Animation.java:185)
    at com.sun.scenario.animation.AbstractMasterTimer.timePulseImpl(AbstractMasterTimer.java:344)
    at com.sun.scenario.animation.AbstractMasterTimer$MainLoop.run(AbstractMasterTimer.java:267)
    at com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:447)
    at com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:431)
    at com.sun.javafx.tk.quantum.QuantumToolkit.lambda$runToolkit$363(QuantumToolkit.java:298)
    at com.sun.javafx.tk.quantum.QuantumToolkit$$Lambda$41/158492595.run(Unknown Source)
    at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
    at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at com.sun.glass.ui.win.WinApplication.lambda$null$141(WinApplication.java:102)
    at com.sun.glass.ui.win.WinApplication$$Lambda$37/1109371569.run(Unknown Source)
    at java.lang.Thread.run(Thread.java:745)
 
Die Zeile: private AudioInputStream targetLine;
Diese Variable wird nirgens gesetzt, daher passier hier: ((DataLine) targetLine).stop(); die NullPointerException...
 
Man bist du schnell, beim Fehler finden. Alle Achtung.
Ich habe es jetzt so gelöst, es funktioniert jetzt. Yippiiiiii

Java:
package audioRecording_1;

import java.io.File;
import java.io.IOException;

import javax.sound.sampled.AudioFileFormat;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.TargetDataLine;

import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.util.Duration;

public class AudioRecorder {
   
     // 60000 = 1 minute
    final long recordTime;
    public TargetDataLine targetLine = null;
   
    public AudioRecorder(long recordTime)
    {
        this.recordTime = recordTime;
        System.out.println("AUDIO RECORDING START:");
       
        try {
            AudioFormat format = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, 44100, 16, 2, 4, 44100, false);
            DataLine.Info info = new DataLine.Info(TargetDataLine.class, format);
            if(!AudioSystem.isLineSupported(info)){
                System.err.println("Line not supported");
            }
            targetLine = (TargetDataLine)AudioSystem.getLine(info);
            // öffnet den kanal es zu lesen
            targetLine.open();
           
            System.out.println("Start Recording: ");
            // ließt die audio infos schreibt sie aber noch nicht in eine datei
            targetLine.start();
           
       
           
             //String userHomeFolder = System.getProperty("user.home");
             File desktopDir = new File(System.getProperty("user.home"), "Desktop");
             System.out.println(desktopDir.getPath() + " " + desktopDir.exists());


            Thread thread = new Thread(){
                @Override public void run()
                {
                    AudioInputStream audioStream = new AudioInputStream(targetLine);
                    File audioFile = new File(desktopDir.getPath(),"record1.wav");
                    try {
                        AudioSystem.write(audioStream, AudioFileFormat.Type.WAVE, audioFile);
                    } catch (IOException io) {
                        io.printStackTrace();
                    }
   
                }
            };
           
            thread.start();
           
            Timeline timeline = new Timeline(new KeyFrame(Duration.millis(recordTime),ae -> { stopRecording(); }));
            timeline.play();
           
           
           
        }
        catch (LineUnavailableException lue) { lue.printStackTrace(); }
        //catch (InterruptedException ie) { ie.printStackTrace(); }
    }
   
    public void stopRecording(){
        System.out.println("STOP");
        targetLine.stop();
        targetLine.close();
    }
   
    public static void main(String[] args) {}
}
 

Zurück
Oben