diff --git a/src/main/java/com/github/manevolent/ts3j/protocol/socket/client/LocalTeamspeakClientSocket.java b/src/main/java/com/github/manevolent/ts3j/protocol/socket/client/LocalTeamspeakClientSocket.java index 73ab324..87eeda1 100644 --- a/src/main/java/com/github/manevolent/ts3j/protocol/socket/client/LocalTeamspeakClientSocket.java +++ b/src/main/java/com/github/manevolent/ts3j/protocol/socket/client/LocalTeamspeakClientSocket.java @@ -399,6 +399,8 @@ public class LocalTeamspeakClientSocket } private class MicrophoneTask implements Runnable { + private boolean wasSendingAudio = false; + @Override public void run() { if (!isConnected()) return; @@ -421,6 +423,23 @@ public class LocalTeamspeakClientSocket try { writePacket(voice); + + wasSendingAudio = true; + } catch (Exception e) { + // All we are really concerned about here is a disconnection event, in which case the loop + // will exit. + getExceptionHandler().accept(e); + } + } else if (wasSendingAudio) { + PacketBody0Voice voice = new PacketBody0Voice(getRole().getOut()); + + voice.setCodecType(microphone.getCodec()); + voice.setCodecData(new byte[0]); + + try { + writePacket(voice); + + wasSendingAudio = false; } catch (Exception e) { // All we are really concerned about here is a disconnection event, in which case the loop // will exit. diff --git a/src/test/java/com/github/manevolent/ts3j/VoicePacketTest.java b/src/test/java/com/github/manevolent/ts3j/VoicePacketTest.java new file mode 100644 index 0000000..6109980 --- /dev/null +++ b/src/test/java/com/github/manevolent/ts3j/VoicePacketTest.java @@ -0,0 +1,35 @@ +package com.github.manevolent.ts3j; + +import com.github.manevolent.ts3j.enums.CodecType; +import com.github.manevolent.ts3j.protocol.Packet; +import com.github.manevolent.ts3j.protocol.ProtocolRole; +import com.github.manevolent.ts3j.protocol.packet.PacketBody0Voice; +import com.github.manevolent.ts3j.protocol.packet.PacketBodyType; +import com.github.manevolent.ts3j.util.Ts3Debugging; +import junit.framework.TestCase; + +import java.nio.ByteBuffer; + +/** + * I just sent a series of voice packets and caught the last packet, turns out Teamspeak sends a 0-length byte + * array on the last packet when the decoder should close. + */ +public class VoicePacketTest extends TestCase { + + public static void main(String[] args) throws Exception { + new VoicePacketTest().testParser(); + } + + public void testParser() throws Exception { + byte[] packetBytes = Ts3Debugging.hexStringToByteArray("c1a81dfa4699030e0cc10002800cc205"); + Packet voicePacket = new Packet(ProtocolRole.CLIENT); + voicePacket.read(ByteBuffer.wrap(packetBytes)); + + assertEquals(PacketBodyType.VOICE, voicePacket.getHeader().getType()); + assertEquals(CodecType.OPUS_MUSIC, ((PacketBody0Voice) voicePacket.getBody()).getCodecType()); + assertEquals(0, ((PacketBody0Voice)voicePacket.getBody()).getClientId()); + assertEquals(3266, ((PacketBody0Voice)voicePacket.getBody()).getPacketId()); + assertEquals(0, ((PacketBody0Voice)voicePacket.getBody()).getCodecData().length); + } + +}