opus-jni is a very simple and comfortable to use JNI wrapper for the Opus codec, created for LabyMod. It might lack a few functions of the original Opus codec specifications but should be perfectly fine for most usecases.
See here for a very simple and complete echo example.
This repository uses submodules, so you need to clone with --recurse-submodules
or after
cloning run git submodule update --init
Building is slightly more complex than a normal Java project and only required if you want to change the way the library works.
Install CMake and make sure it is on the path. You will also need a compiler (not a Java compiler, but a C one). For windows you should install Visual Studio. For Linux and OSX choose your favorite method of installing the compiler (gcc and clang should both work).
After this is done, the project might be used like every other gradle project. Note that the
resulting jar will be in opus-jni-java/build/libs
and will just work on the platform it
was built on!. For instructions on how to build for all target platforms, see below.
You will need a machine for every platform you want to build on. This means, if you want to produce a jar which works on Linux, Windows and OSX, you will need an installation of each of the operating systems (it might be possible to just use Linux and cross compile, but that is not officially supported by us).
All 3 machines will need CMake and a compiler installed (refer to
Building for your platform). Then you need to run
the gradle task opus-jni-native:build
on each machine, which will result in the following
binaries in build/nativeBinaries
:
libopus-jni-native.dylib
(OSX)libopus-jni-native.so
(Linux)opus-jni-native.dll
(Windows)
Copy all of those binaries to one machine to one directory. On that machine invoke
gradlew -PnativeBinaryExternalDir=/path/to/your/directory opus-jni-java:build
, where
/path/to/your/directory
is the directory containing all 3 of the binaries above.
The final jar in opus-jni-java/build/libs
will support all platforms you have built the
binaries for. You may leave the ones out you don't need to support.
For further details, refer to the Github workflow.
- Every audio stream requires its own codec instance, because Opus is not stateless.
- Only the following sample rates are supported: 8khz, 12khz, 16khz, 24khz, 48khz
- Recommended bitrates for your purpose found here
- The default codec settings should be fine for every simple VoIP communication
- Unused instances of OpusCodec must be removed to prevent memory leaks with
OpusCodec#destroy
. This might not be critical when using only a fixed amount of instances, but can get dangerous when those instances have a life cycle and might be recreated once in a while.
OpusCodec codec = OpusCodec.createDefault();
OpusCodec codec = OpusCodec.newBuilder()
.withSampleRate(24000)
.withChannels(2)
.withBitrate(128000)
...
.build();
Encoding/Decoding an audio chunk is very straight forward.
byte[] data = new byte[codec.getFrameSize() * codec.getChannels() * 2];
... //Fill data
byte[] encoded = codec.encodeFrame(data);
byte[] decode = codec.decodeFrame(encoded);