package com.utils;
import net.dv8tion.jda.api.audio.AudioSendHandler;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import javax.sound.sampled.UnsupportedAudioFileException;
public class MyAudioSendHandler implements AudioSendHandler {
private static final int SAMPLE_RATE = 48000; // 48KHz
private static final int BITS_PER_SAMPLE = 16; // 16-bit
private static final int CHANNELS = 2; // Stereo
private static final int BYTES_PER_SAMPLE = BITS_PER_SAMPLE / 8;
private static final int FRAME_SIZE = BYTES_PER_SAMPLE * CHANNELS;
private static final int BUFFER_SIZE = FRAME_SIZE * SAMPLE_RATE * 20 / 1000; // buffer for 20ms of audio
private final URL audioUrl;
private InputStream inputStream;
private final byte[] buffer = new byte[BUFFER_SIZE];
private volatile boolean isPlaying = false;
public MyAudioSendHandler(String urlString) throws IOException {
audioUrl = new URL(urlString);
openAudioStream();
}
private void openAudioStream() {
try {
String ffmpegCommand = "ffmpeg -i " + audioUrl + " -ar " + SAMPLE_RATE + " -sample_fmt s16 -ac "
+ CHANNELS
+ " -f s16le -";
ProcessBuilder builder = new ProcessBuilder(ffmpegCommand.split(" "));
builder.redirectErrorStream(true);
Process process = builder.start();
inputStream = process.getInputStream();
isPlaying = true;
} catch (Exception e) {
System.err.println("Failed to open audio stream: " + e.getMessage());
}
}
@Override
public boolean canProvide() {
return isPlaying && inputStream != null;
}
@Override
public ByteBuffer provide20MsAudio() {
ByteBuffer audioBuffer = ByteBuffer.allocate(BUFFER_SIZE);
audioBuffer.order(ByteOrder.BIG_ENDIAN);
try {
int bytesRead = inputStream.read(buffer); // Read directly into the buffer
if (bytesRead == -1) {
this.isPlaying = false;
inputStream.close();
return null;
}
audioBuffer.clear();
audioBuffer.put(buffer, 0, bytesRead);
audioBuffer.flip();
return audioBuffer;
} catch (IOException e) {
e.printStackTrace(); // Log any IO errors
return null;
}
}
@Override
public boolean isOpus() {
return false;
}
public void start() {
isPlaying = true;
System.out.println("Playback started.");
}
public void stop() {
isPlaying = false;
System.out.println("Playback stopped.");
try {
inputStream.close();
} catch (Exception e) {
System.err.println("Error closing audio stream: " + e.getMessage());
}
}
}
I’ve tried so many ways and this is the code that plays part of the song I try to put on. There is always a loud, high pitched noise.
I am trying to make my own AudioSendHandler, without relying on libraries like lavaplayer.
I am not sure but it could be that the ffmpeg stream is not downloading fast enough to be read.
New contributor
Joele Buffolo is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.