This library has been superseded by koe, please check it out for your Discord audio needs. koe has multiple advantages over Magma:
- not built around inherited convoluted existing APIs
- less complicated, therefore easier to maintain and contribute to
My main take-away from this library is to stay far away from reactive libraries and paradigms as possible. The added complexity is not worth the downsides, especially when alternatives are possible to achieve similar performance goals.
A voice only API for Discord, focused on delivering music at scale.
Notable features:
- Event based and non-blocking at its core
Not supported:
- Audio Receiving
Magma is a heavily modified fork of JDA-Audio (Apache 2.0)
Big shout-out to the to the original authors and maintainers for doing great work!
Besides making use of most of the code for handling audio packets, Magma reuses some of JDAs APIs, namely:
- IAudioSendSystem
- IAudioSendFactory
- IPacketProvider
- AudioSendHandler
Magma does not ship any implementations for IAudioSendSystem and IAudioSendFactory.
It is important that the implementation you choose will never call any method of the packet provider but
IPacketProvider#getNextPacket
, because none of the others are supported by Magma.
Recommended implementations:
Only AudioSendHandler
s that provide packets in the opus format are supported.
Recommended providers:
- JitPack for builds straight from github code
Replace x.y.z
in the snippets below with the desired version. Latest:
repositories {
maven { url 'https://jitpack.io' }
}
dependencies {
compile group: 'space.npstr.magma', name: 'magma', version: 'x.y.z'
}
<repositories>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
</repositories>
<dependency>
<groupId>space.npstr.magma</groupId>
<artifactId>magma</artifactId>
<version>x.z.y</version>
</dependency>
Discord supports one single audio connection per user and guild (also called a "member"). This means, an audio connection is exactly identified by those two datapoints, and all of the methods of Magma require those to correctly identify the connection that you want to open/close/change something about.
Magma uses immutables.org to ensure type and parameter safety, both internally and in the Api you are going to use. Concretely, the Api makes use of immutable Member and ServerUpdate objects.
Member member = MagmaMember.builder()
.userId("...")
.guildId("...")
.build();
ServerUpdate = MagmaServerUpdate.builder()
.sessionId("...")
.endpoint("...")
.token("...")
.build();
Typical usage of the methods offered by the MagmaApi:
IAudioSendFactory audioSendFactory = <your implementation here>;
AudioSendHandler sendHandler = <your implementation here>;
MagmaApi magmaApi = MagmaFactory.of(__ -> audioSendFactory);
magmaApi.provideVoiceServerUpdate(member, serverUpdate);
magmaApi.setSendHandler(member, sendHandler);
// music plays, then later:
magmaApi.setSendHandler(member, someOtherHandler);
// other handler plays music / sounds
// to clean up:
magmaApi.removeSendHandler(member);
magmaApi.closeConnection(member);
// on shutting down
magmaApi.shutdown();
// Calling any other methods of a MagmaApi object after having called shutdown()
// will result in undefined behaviour. Do not do this, create a new MagmaApi instead.
// Please note that you are strongly encouraged to use a single MagmaApi object throughout
// the lifecycle of your application.
None of those calls are blocking, as they are translated into events to be processed as soon as possible. Currently, there is no feedback as to when and how these are processed.
You can subscribe to a stream of MagmaEvents
through MagmaApi#getEventStream
:
...
magmaApi.getEventStream()
.subscribe(this::handleMagmaEvent);
...
private void handleMagmaEvent(MagmaEvent magmaEvent) {
if (magmaEvent instanceof space.npstr.magma.events.api.WebSocketClosed) {
WebSocketClosed wsClosedEvent = (WebSocketClosed) magmaEvent;
log.info("WS in guild {} closed with code {} and reason {}", wsClosedEvent.getMember().getGuildId(),
wsClosedEvent.getCloseCode(), wsClosedEvent.getReason());
}
}
Check out these open-source projects for some more real world usage examples:
Magma might for various reasons not fit your needs. Don't worry, there are alternatives for sending voice to Discord:
(last updated for 0.2.1)
Magma has been written with Lavalink in mind, numbers shown here compare vanilla Lavalink to a Magma-based branch.
Graphs by courtesy of FredBoat.
Enabling TRACE/DEBUG logs can help with pinpointing and reporting issues.
To get the most out of these log levels, make sure your chosen logger implementation and configuration
prints additional MDC information. The MDC keys that Magma uses can be found in the MdcKeys
class.
If you are running Magma in a Spring Boot application with logback as the logger implementation
(Lavalink does this), adding these following lines to your Spring Application's application.yaml
will show the MDC information:
logging:
pattern:
level: "[%mdc] %5p"
level:
space.npstr.magma: TRACE
-
JSON In Java:
-
Simple Logging Facade for Java:
-
Spring Webflux:
-
Undertow Core:
-
SpotBugs Annotations:
-
Immutables.org Value: