'Java Sound API unable to stop recording on a button click from UI of a web Application

I am using Java Sound API for creating a Web Application .User Interface(UI) has a button which on click starts recording the speech ,the recorded audio is saved in an audio file (.wav ext) .UI also has a play button which accesses the same audio file and plays the recording back. Currently I am recording the audio for a specified duration which is hardcoded in my application or getting passed from UI as a parameter while the recording starts.But now the requirement is to stop the recording on click of a button on UI.

Now the issue is while capturing the audio I am opening a targetline using below code :


public void capture(int record_time) {

        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.out.println("Line not supported");}

         final TargetDataLine targetDataLine =        (TargetDataLine)AudioSystem.getLine(info);

         targetDataLine.open();
          targetDataLine.start();
         Thread thread = new Thread()
         {
             @Override public void run() 

             {
                 AudioInputStream audioStream = new AudioInputStream(targetDataLine);
                 File audioFile = new File(fileName);

                System.out.println("Recording is going to get saved in path :::: "+ audioFile.getAbsolutePath());
                 try{
                     AudioSystem.write(audioStream, AudioFileFormat.Type.WAVE, audioFile);
                 }
                 catch (IOException e){
                     e.printStackTrace();
                 }
                 System.out.println("Stopped Recording");
             }
         };
         thread.start();
         Thread.sleep(record_time*1000); 
         targetDataLine.stop();
         targetDataLine.close();
        System.out.println("Ended recording test");
        } catch (LineUnavailableException e) {
          System.err.println("Line unavailable: " + e);
          System.exit(-2);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

}


Above code will stop recording once the record time is elapsed.

But I want another method like below which when invoked from jsp (stop button click) should be able to get the same targetline object which is responsible for current recording and stop the current recording.

Below code does not work for me and recording goes on


public void stop(){
    try{
        System.out.println("stop :: in stop");
         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.out.println("Line not supported");}

         final TargetDataLine targetDataLine = (TargetDataLine)AudioSystem.getLine(info);
         System.out.println("stop Recording....");

         System.out.println("targetDataLine.getLineInfo() in stop:::::::"+targetDataLine.getLineInfo());
         System.out.println("targetDataLine.isActive() in stop:::::::"+targetDataLine.isActive());
         System.out.println("targetDataLine.isOpen() in stop:::::::"+targetDataLine.isOpen());

         targetDataLine.stop();
         targetDataLine.close();
    }
     catch (Exception e) {
          System.err.println("Line unavailable: " + e);
     }
}

Please suggest some resolution.

One more thing that might ..not sure but might has some role to play is the way I am calling these methods from my servlet ..below is the code....

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    String action = request.getParameter("buttonName");
    String record_time = request.getParameter("time");
    System.out.println("action:::"+action +"time in minutes:::"+ record_time);
    int record_time_int =(Integer.parseInt(record_time));
    String fileName = "studentXYZ.wav";

    System.out.println("action:::"+action +"----wavfile:::"+fileName+"time in minutes:::"+ record_time);

    Recorder01 record = new Recorder01();


    if (action != null && (action.equalsIgnoreCase("Capture")) ){

        record.capture(fileName, action,record_time_int);
                request.setAttribute("fileName", fileName);
                request.getRequestDispatcher("/recordAudio.jsp").forward(request, response);

    }

    else if (action != null && action.equalsIgnoreCase("play")) {
        Recorder01 playsound = new Recorder01();
        playsound.play(fileName);
        System.out.println("finished playing recording");
        request.setAttribute("fileName", fileName);
            request.getRequestDispatcher("/recordAudio.jsp").forward(request, response);

    }

    else if(action!=null && action.equalsIgnoreCase("Stop")){
        System.out.println("stop recording called");
        record.stop();
            request.getRequestDispatcher("/recordAudio.jsp").forward(request, response);

    }
}


Solution 1:[1]

private TargetDataLine targetDataLine;

public void capture() {

    if (targetDataLine == null) {

        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.out.println("Line not supported");
            }

            targetDataLine = (TargetDataLine) AudioSystem.getLine(info);

            targetDataLine.open();
            targetDataLine.start();
            Thread thread = new Thread() {
                @Override
                public void run() {
                    AudioInputStream audioStream = new AudioInputStream(targetDataLine);
                    File audioFile = new File(fileName);

                    System.out.println("Recording is going to get saved in path :::: " + audioFile.getAbsolutePath());
                    try {
                        AudioSystem.write(audioStream, AudioFileFormat.Type.WAVE, audioFile);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    System.out.println("Stopped Recording");
                }
            };
            thread.start();
        } catch (LineUnavailableException e) {
            System.err.println("Line unavailable: " + e);
            System.exit(-2);
        }
    }
}

public void stop() {
    if (targetDataLine != null) {
        System.out.println("stop :: in stop");
        targetDataLine.stop();
        targetDataLine.close();
        targetDataLine = null;
    }
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Hasen