use of org.javacord.core.event.audio.AudioSourceFinishedEventImpl in project Javacord by BtoBastian.
the class AudioUdpSocket method startSending.
/**
* Starts polling frames from the audio connection and sending them through the socket.
*/
public void startSending() {
if (shouldSend) {
return;
}
shouldSend = true;
DiscordApiImpl api = (DiscordApiImpl) connection.getChannel().getApi();
api.getThreadPool().getSingleThreadExecutorService(threadName).submit(() -> {
try {
long nextFrameTimestamp = System.nanoTime();
boolean dontSleep = true;
boolean speaking = false;
long framesOfSilenceToPlay = 5;
while (shouldSend) {
// Get the current audio source. If none is available, it will block the thread
AudioSource source = connection.getCurrentAudioSourceBlocking();
if (source == null) {
logger.error("Got null audio source without being interrupted ({})", connection);
return;
}
if (source.hasFinished()) {
connection.removeAudioSource();
dontSleep = true;
// Dispatch AudioSourceFinishedEvent AFTER removing the source.
// Otherwise, AudioSourceFinishedEvent#getNextSource() won't work
api.getEventDispatcher().dispatchAudioSourceFinishedEvent((ServerImpl) connection.getServer(), connection, ((AudioSourceBase) source).getDelegate(), new AudioSourceFinishedEventImpl(source, connection));
continue;
}
AudioPacket packet = null;
byte[] frame = source.hasNextFrame() ? source.getNextFrame() : null;
// If the source is muted, replace the frame with a muted frame
if (source.isMuted()) {
frame = null;
}
if (frame != null || framesOfSilenceToPlay > 0) {
if (!speaking && frame != null) {
speaking = true;
connection.setSpeaking(true);
}
packet = new AudioPacket(frame, ssrc, sequence, ((int) sequence) * 960);
// We can stop sending frames of silence after 5 frames
if (frame == null) {
framesOfSilenceToPlay--;
if (framesOfSilenceToPlay == 0) {
speaking = false;
connection.setSpeaking(false);
}
} else {
framesOfSilenceToPlay = 5;
}
}
nextFrameTimestamp = nextFrameTimestamp + 20_000_000;
sequence++;
if (packet != null) {
packet.encrypt(secretKey);
}
try {
if (dontSleep) {
nextFrameTimestamp = System.nanoTime() + 20_000_000;
dontSleep = false;
} else {
Thread.sleep(Math.max(0, nextFrameTimestamp - System.nanoTime()) / 1_000_000);
}
if (packet != null) {
socket.send(packet.asUdpPacket(address));
}
} catch (IOException e) {
logger.error("Failed to send audio packet for {}", connection);
}
}
} catch (InterruptedException e) {
if (shouldSend) {
logger.debug("Got interrupted unexpectedly while waiting for next audio source packet");
}
}
});
}
Aggregations