Files
AsminVoicechat/source/decompiled/de/maxhenkel/voicechat/plugins/impl/audiochannel/AudioPlayerImpl.java
T
asminme bbccd4a815
Build AsminVoicechat / prepare-release (push) Successful in 14s
Build AsminVoicechat / build-and-test (17) (push) Canceled after 0s
Build AsminVoicechat / build-and-test (18) (push) Canceled after 0s
Build AsminVoicechat / build-and-test (19) (push) Canceled after 0s
Build AsminVoicechat / build-and-test (20) (push) Canceled after 0s
Build AsminVoicechat / build-and-test (21) (push) Canceled after 0s
Build AsminVoicechat / build-and-test (22) (push) Canceled after 0s
Build AsminVoicechat / build-and-test (23) (push) Canceled after 0s
Build AsminVoicechat / build-and-test (24) (push) Canceled after 0s
Build AsminVoicechat / build-and-test (25) (push) Canceled after 0s
Build AsminVoicechat / build-and-test (26) (push) Canceled after 0s
Build AsminVoicechat / build-and-test (27-ea) (push) Canceled after 0s
Build AsminVoicechat / build-and-test (16) (push) Canceled after 38s
first commit
2026-10-24 15:18:03 +02:00

103 lines
2.9 KiB
Java

/*
* Decompiled with CFR 0.152.
*
* Could not load the following classes:
* javax.annotation.Nonnull
* javax.annotation.Nullable
*/
package de.maxhenkel.voicechat.plugins.impl.audiochannel;
import de.maxhenkel.voicechat.Voicechat;
import de.maxhenkel.voicechat.api.audiochannel.AudioChannel;
import de.maxhenkel.voicechat.api.audiochannel.AudioPlayer;
import de.maxhenkel.voicechat.api.opus.OpusEncoder;
import de.maxhenkel.voicechat.debug.VoicechatUncaughtExceptionHandler;
import java.util.function.Supplier;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public class AudioPlayerImpl
extends Thread
implements AudioPlayer {
private static final long FRAME_SIZE_NS = 20000000L;
public static final int FRAME_SIZE = 960;
private final AudioChannel audioChannel;
private final OpusEncoder encoder;
private final Supplier<short[]> audioSupplier;
private boolean started;
@Nullable
private Runnable onStopped;
public AudioPlayerImpl(AudioChannel audioChannel, @Nonnull OpusEncoder encoder, Supplier<short[]> audioSupplier) {
this.audioChannel = audioChannel;
this.encoder = encoder;
this.audioSupplier = audioSupplier;
this.setDaemon(true);
this.setName(String.format("AudioPlayer-%s", audioChannel.getId()));
this.setUncaughtExceptionHandler(new VoicechatUncaughtExceptionHandler());
}
@Override
public void startPlaying() {
if (this.started) {
return;
}
this.start();
this.started = true;
}
@Override
public void stopPlaying() {
this.interrupt();
}
@Override
public boolean isStarted() {
return this.started;
}
@Override
public boolean isPlaying() {
return this.isAlive();
}
@Override
public boolean isStopped() {
return this.started && !this.isAlive();
}
@Override
public void setOnStopped(Runnable onStopped) {
this.onStopped = onStopped;
}
@Override
public void run() {
short[] frame;
int framePosition = 0;
long startTime = System.nanoTime();
while ((frame = this.audioSupplier.get()) != null) {
if (frame.length != 960) {
Voicechat.LOGGER.error("Got invalid audio frame size {}!={}", frame.length, 960);
break;
}
this.audioChannel.send(this.encoder.encode(frame));
long waitTimestamp = startTime + (long)(++framePosition) * 20000000L;
long waitNanos = waitTimestamp - System.nanoTime();
try {
if (waitNanos <= 0L) continue;
Thread.sleep(waitNanos / 1000000L, (int)(waitNanos % 1000000L));
}
catch (InterruptedException e) {
break;
}
}
this.encoder.close();
this.audioChannel.flush();
if (this.onStopped != null) {
this.onStopped.run();
}
}
}