Я подозреваю, что ваш визг исходит из наполовину заполненного буфера, который передается в аудиосистему.
Как указано в комментарии выше, я бы использовал что-то вроде FFSampledSP ( если на ma c или Windows), а затем код, подобный следующему, что гораздо более java -esque.
Просто убедитесь, что полный JAR FFSampledSP находится на вашем пути, и вы должны быть хорошими go.
import javax.sound.sampled.*;
import java.io.File;
import java.io.IOException;
public class PlayerDemo {
/**
* Derive a PCM format.
*/
private static AudioFormat toSignedPCM(final AudioFormat format) {
final int sampleSizeInBits = format.getSampleSizeInBits() <= 0 ? 16 : format.getSampleSizeInBits();
final int channels = format.getChannels() <= 0 ? 2 : format.getChannels();
final float sampleRate = format.getSampleRate() <= 0 ? 44100f : format.getSampleRate();
return new AudioFormat(AudioFormat.Encoding.PCM_SIGNED,
sampleRate,
sampleSizeInBits,
channels,
(sampleSizeInBits > 0 && channels > 0) ? (sampleSizeInBits/8)*channels : AudioSystem.NOT_SPECIFIED,
sampleRate,
format.isBigEndian()
);
}
public static void main(final String[] args) throws IOException, UnsupportedAudioFileException, LineUnavailableException {
final File audioFile = new File(args[0]);
// open mp3 or whatever
final Long durationInMicroseconds = (Long)AudioSystem.getAudioFileFormat(audioFile).getProperty("duration");
// how long is the file, use AudioFileFormat properties
System.out.println("Duration in microseconds (not millis!): " + durationInMicroseconds);
// open the mp3 stream (not yet decoded)
final AudioInputStream mp3In = AudioSystem.getAudioInputStream(audioFile);
// derive a suitable PCM format that can be played by the AudioSystem
final AudioFormat desiredFormat = toSignedPCM(mp3In.getFormat());
// ask the AudioSystem for a source line for playback
// that corresponds to the derived PCM format
final SourceDataLine line = AudioSystem.getSourceDataLine(desiredFormat);
// now play, typically in separate thread
new Thread(() -> {
final byte[] buf = new byte[4096];
int justRead;
// convert to raw PCM samples with the AudioSystem
try (final AudioInputStream rawIn = AudioSystem.getAudioInputStream(desiredFormat, mp3In)) {
line.open();
line.start();
while ((justRead = rawIn.read(buf)) >= 0) {
// only write bytes we really read, not more!
line.write(buf, 0, justRead);
final long microsecondPosition = line.getMicrosecondPosition();
System.out.println("Current position in microseconds: " + microsecondPosition);
}
} catch (IOException | LineUnavailableException e) {
e.printStackTrace();
} finally {
line.drain();
line.stop();
}
}).start();
}
}
Обычный API Java не позволяет переходить на произвольные позиции. Однако FFSampledSP содержит расширение, то есть метод seek () . Чтобы использовать его, просто приведите rawIn
из приведенного выше примера к FFAudioInputStream
и вызовите seek()
с time
и timeUnit
.