Created
December 3, 2019 22:29
-
-
Save HyCraftHD/4374742d0cc5e6d1c9b111ad52fa2083 to your computer and use it in GitHub Desktop.
Basic UDP audio transmission (Audio data is encoded with opus)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package test.voicechat; | |
import java.net.*; | |
import javax.sound.sampled.*; | |
import org.concentus.*; | |
/** | |
* Use of native java opus port (https://github.com/lostromb/concentus) used in here. Every other opus java wrapper shoud work too. | |
*/ | |
public class VoiceChat { | |
private final static String HOST = "echo.udp-server.example"; | |
private static DatagramSocket socket; | |
private static final AudioFormat format = new AudioFormat(48000, 16, 2, true, false); | |
private static final DataLine.Info micInfo = new DataLine.Info(TargetDataLine.class, format); | |
private static final DataLine.Info speakerInfo = new DataLine.Info(SourceDataLine.class, format); | |
public static void main(String[] args) throws Exception { | |
socket = new DatagramSocket(); | |
send(); | |
receive(); | |
} | |
private static void send() { | |
final Runnable runnable = () -> { | |
try { | |
TargetDataLine targetLine = (TargetDataLine) AudioSystem.getLine(micInfo); | |
targetLine.open(format); | |
targetLine.start(); | |
OpusEncoder encoder = new OpusEncoder(48000, 2, OpusApplication.OPUS_APPLICATION_AUDIO); | |
encoder.setBitrate(96000); | |
encoder.setSignalType(OpusSignal.OPUS_SIGNAL_MUSIC); | |
encoder.setComplexity(10); | |
int numBytesRead; | |
byte[] targetData = new byte[960 * 2 * 2]; | |
byte[] encodedData = new byte[1000]; | |
while (true) { | |
numBytesRead = targetLine.read(targetData, 0, targetData.length); | |
if (numBytesRead >= 0) { | |
int encodedLength = encoder.encode(targetData, 0, 960, encodedData, 0, encodedData.length); | |
final DatagramPacket datagramPacket = new DatagramPacket(encodedData, encodedLength, InetAddress.getByName(HOST), 10000); | |
socket.send(datagramPacket); | |
} | |
} | |
} catch (Exception ex) { | |
ex.printStackTrace(); | |
} | |
}; | |
new Thread(runnable).start(); | |
} | |
private static void receive() { | |
final Runnable runnable = () -> { | |
try { | |
SourceDataLine sourceLine = (SourceDataLine) AudioSystem.getLine(speakerInfo); | |
sourceLine.open(format); | |
sourceLine.start(); | |
OpusDecoder decoder = new OpusDecoder(48000, 2); | |
byte[] decodedData = new byte[960 * 2 * 2]; | |
while (true) { | |
final byte[] array = new byte[1000]; | |
final DatagramPacket datagramPacket = new DatagramPacket(array, array.length); | |
socket.receive(datagramPacket); | |
decoder.decode(array, 0, datagramPacket.getLength(), decodedData, 0, 960, false); | |
sourceLine.write(decodedData, 0, decodedData.length); | |
} | |
} catch (Exception ex) { | |
ex.printStackTrace(); | |
} | |
}; | |
new Thread(runnable).start(); | |
} | |
} |
You need to convert your byte array to a short array, as the provided audio data uses 16 bits = 2 bytes = 1 short.
You can have a look here for the encoder and decoder: https://github.com/MC-U-Team/Voice-Chat/blob/1.16.5/audio-client/src/main/java/info/u_team/voice_chat/audio_client/opus/PcmOpusDecoder.java
https://github.com/MC-U-Team/Voice-Chat/blob/1.16.5/audio-client/src/main/java/info/u_team/voice_chat/audio_client/opus/PcmOpusEncoder.java
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Getting this issue with the encoder.encode method:
Required type: short[] Provided: byte[]
Any ideas why mine requires short[] instead of byte[]?