Редактировать: Я нашел решение, изменив всего несколько строк, проблема была только частично из-за плохих циклов. Это было основной частью проблемы:
'' '
public void recordStop(){
System.out.println("stop recording");
recordingRunning = false;
if (dataLine != null) {
dataLine.flush();
dataLine.close();
System.out.println("close and drain line");
}
}
' ''
использование .drain () убивает поток, поэтому просто использовал .flu sh () вместо этого и мы пугаем.
(TLDR - когда я нажимаю кнопку, чтобы опустошить целевую строку данных, вызываемая функция будет пытаться опустошить линию, но GUI создаст sh и файл не будет выведен)
Я делаю аудиозапись с JavaF XML, используя java класс сэмплированных звуков . Я использую отдельный поток для запуска рекордера во время работы GUI, но проблема возникает при попытке остановить запись и сохранить запись. Мне удалось заставить поток начаться хорошо и запустить при нажатии кнопки. Активируется этим кодом:
Обработчик события F XML при нажатии кнопки:
'' '
@FXML
private void recordingButtonAction(ActionEvent event) throws LineUnavailableException {
if(isRecording == false){
label.setText("Recording");
fileName = RT.setFileName();
channelLocationTracker(channelSelectToggleGroup);
try{
TargetDataLine dataLine =AudioSystem.getTargetDataLine(audioFormat);
}
catch (LineUnavailableException ex) {
ex.printStackTrace();
}
isRecording=true;
}
else{
System.out.println("Already recording");
}
}
' ''
Код для начала записи в отдельном классе, откуда происходит объект "RT":
'' '
public TargetDataLine getDataLine() throws LineUnavailableException{
audioFormat = getAudioFormat();
DataLine.Info info = new DataLine.Info(TargetDataLine.class, audioFormat);
if (!AudioSystem.isLineSupported(info)) {
throw new LineUnavailableException(
"Format Unsupported");
}
final TargetDataLine dataLine = AudioSystem.getTargetDataLine(audioFormat);;
AudioSystem.getLine(info);
return dataLine;
}
' '' '' '
public void recordStart(boolean isRecording) throws LineUnavailableException{
isRecording = false;
audioFormat = getAudioFormat();
dataLine = getDataLine();
dataLine.open(audioFormat);
dataLine.start();
System.out.println("open line");
System.out.println("start recording");
byte[] buffer = new byte[bufferSz];
int bytesRead = 0;
recordedBytes = new ByteArrayOutputStream();
isRecording = true;
while (isRecording) {
bytesRead = getDataLine().read(buffer, 0, buffer.length);
recordedBytes.write(buffer, 0, bytesRead);
}
}
'' '
И сам поток:
' ''
private void startRecord(){
Thread startRec = new Thread(new Runnable(){
public void run(){
try {
isRecording=true;
RT.recordStart(isRecording);
} catch (LineUnavailableException ex) {
Logger.getLogger(FXMLDocumentController.class.getName()).log(Level.SEVERE, null, ex);
}
}
});
startRec.start();
}
'' '
Возникла проблема Когда я нажимаю кнопку остановки записи, она будет печатать сливную линию в оболочке, но GUI будет обрабатывать sh, и запись, остановленная, не будет напечатана. Я думаю, что проблема связана с методом .drain ().
Еще раз вот F XML:
'' '
@FXML
private void stopButtonAction(ActionEvent event) throws IOException, LineUnavailableException,
UnsupportedAudioFileException {
RT.setFileName("recording"+".wav");
recordedFileWAV = RT.getFile();
if(isRecording == true){
endRecord();
}
}
'' '
Отдельный класс для остановки записи:
' ''
public void recordStop(boolean isRecording){
isRecording = false;
System.out.println("drain line");
dataLine.drain();
System.out.println("stop recording");
dataLine.close();
}
'' '
И метод в записи класс, который вы можете сохранить:
'' '
public void recordSave(File wavFile) throws IOException {
byte[] lineData = recordedBytes.toByteArray();
ByteArrayInputStream bais = new ByteArrayInputStream(lineData);
AudioInputStream AIS = new AudioInputStream(bais, audioFormat,lineData.length /
audioFormat.getFrameSize());
AudioSystem.write(AIS, AudioFileFormat.Type.WAVE, wavFile);
AIS.close();
recordedBytes.close();
}
Пожалуйста, дайте мне знать, если вы можете выяснить, что происходит не так или вы можете указать мне в правильном направлении:)