问题
I am trying to implement a pause/resume functionality for my audio recording module in Java. So far all I have found on SO is this, which does not give a definitive answer - I have tried the answerer's suggestion of calling start()
and stop()
on the TargetDataLine
to achieve this, and am aware that stop()
(from Oracle):
"Stops the line. A stopped line should cease I/O activity. If the line is open and running, however, it should retain the resources required to resume activity. A stopped line should retain any audio data in its buffer instead of discarding it, so that upon resumption the I/O can continue where it left off, if possible."
However I am finding that when I call stop on my TargetDataLine
, then sleep for five seconds and call start()
to reopen it, the recording never resumes. Here is the code:
import java.io.*;
import java.util.Timer;
import java.util.TimerTask;
import javax.sound.sampled.*;
import javax.sound.sampled.AudioFileFormat.Type;
public class AudioRecorder
{
static TargetDataLine targetLine = null;
static final long maxRecordingTime = 3600000; // One hour in milliseconds
static Thread recordThread;
public static void main(String[] args)
{
try
{
// Initialise audio format settings and setup data line matching format specification
initialiseAudioSettings();
}
catch (LineUnavailableException e)
{
e.printStackTrace();
}
// TEST
startRecording();
try
{
System.out.println("Sleeping for 5s...");
Thread.sleep(5000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
System.out.println("About to pause recording...");
pauseRecording();
try
{
System.out.println("Sleeping for 5s...");
Thread.sleep(5000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
System.out.println("About to resume recording...");
resumeRecording();
try
{
System.out.println("Sleeping for 5s...");
Thread.sleep(5000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
System.out.println("About to stop recording...");
stopRecording();
System.out.println("Recording stopped...(in theory)");
// /TEST
}
private static void initialiseAudioSettings() throws LineUnavailableException
{
// Define audio format as:
// Encoding: Linear PCM
// Sample Rate: 44.1 kHz
// Bit Depth: 16-bit
// Channel Format: Stereo
// Data Storage: Signed & Big-Endian
final AudioFormat audioFormat = new AudioFormat(44100, 16, 2, true, true);
// Store format metadata in an Info variable
final DataLine.Info audioFormatInfo = new DataLine.Info(TargetDataLine.class, audioFormat);
if (!AudioSystem.isLineSupported(Port.Info.MICROPHONE))
{
throw new LineUnavailableException("No microphone has been detected. Please reconnect the microphone and try again.");
} else
{
System.out.println("Microphone detected. Querying target data line...");
}
// Use metadata to ascertain whether audio format is supported by default input device
if (AudioSystem.isLineSupported(audioFormatInfo) == false)
{
throw new LineUnavailableException("The default input device does not support the specified audio output format");
}
// Get a line matching the specified audio format
targetLine = (TargetDataLine)AudioSystem.getLine(audioFormatInfo);
// Instruct the system to allocate resources to the targetLine and switch it on
targetLine.open();
// Prepare line for audio input
targetLine.start();
}
private static void startRecording()
{
TimerTask scheduleRecordingEnd = new TimerTask()
{
public void run()
{
stopRecording();
}
};
Timer recordingTimer = new Timer("Recording Timer");
recordingTimer.schedule(scheduleRecordingEnd, maxRecordingTime);
// Setup recording thread
recordThread = new Thread(new Runnable()
{
@Override
public void run()
{
{
// Route audio input stream to target data line
AudioInputStream audioInputStream = new AudioInputStream(targetLine);
// Instantiate output filepath & filename
File outputFile = new File("C:/temp/test.wav");
// Write input audio to output .wav file
try
{
AudioSystem.write(audioInputStream, AudioFileFormat.Type.WAVE, outputFile);
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
});
// Start recording
recordThread.start();
}
private static void pauseRecording()
{
targetLine.stop();
}
private static void resumeRecording()
{
targetLine.start();
}
private static void stopRecording()
{
// Cease all I/O functions of the line
targetLine.stop();
// Close the line, deallocating system resources and deleting metadata
targetLine.close();
System.out.println("Stopping recording...");
recordThread.stop();
}
}
The parts of this code that should be of interest are the tests in main()
and the startRecording()
, pauseRecording()
and resumeRecording()
functions, although I have included the code in its entirety for completeness.
Could anyone point me in the right direction as to why this might be happening? Any help would be much appreciated.
来源:https://stackoverflow.com/questions/55024401/pausing-audio-recording-in-java