Git Product home page Git Product logo

lavaplayer's Introduction

LavaPlayer - Audio player library for Discord

LavaPlayer is an audio player library written in Java which can load audio tracks from various sources and convert them into a stream of Opus frames. It is designed for use with Discord bots, but it can be used anywhere where Opus format output is required.

Please read the FAQ in case of issues.

Maven package

Replace x.y.z with the latest version number: 1.3.77

Using in Gradle:

repositories {
  maven {
    url 'https://m2.dv8tion.net/releases'
  }
}

dependencies {
  implementation 'com.sedmelluq:lavaplayer:x.y.z'
}

Using in Maven:

<repositories>
  <repository>
    <id>dv8tion</id>
    <name>m2-dv8tion</name>
    <url>https://m2.dv8tion.net/releases</url>
  </repository>
</repositories>

<dependencies>
  <dependency>
    <groupId>com.sedmelluq</groupId>
    <artifactId>lavaplayer</artifactId>
    <version>x.y.z</version>
  </dependency>
</dependencies>

Supported formats

The set of sources where LavaPlayer can load tracks from is easily extensible, but the ones currently included by default are:

  • YouTube
  • SoundCloud
  • Bandcamp
  • Vimeo
  • Twitch streams
  • Local files
  • HTTP URLs

The file formats that LavaPlayer can currently handle are (relevant for file/url sources):

  • MP3
  • FLAC
  • WAV
  • Matroska/WebM (AAC, Opus or Vorbis codecs)
  • MP4/M4A (AAC codec)
  • OGG streams (Opus, Vorbis and FLAC codecs)
  • AAC streams
  • Stream playlists (M3U and PLS)

Resource usage

What makes LavaPlayer unique is that it handles everything in the same process. Different sources and container formats are handled in Java, while decoding and encoding of audio are handled by embedded native libraries. This gives it a very fine-grained control over the resources that it uses, which means a low memory footprint as well as the chance to skip decoding and encoding steps altogether when the input format matches the output format. Some key things to remember:

  • Memory usage is both predictable and low. The amount of memory used per track when testing with YouTube was at most 350 kilobytes per track plus the off-heap memory for the thread stack, since there is one thread per playing track.
  • The most common format used in YouTube is Opus, which matches the exact output format required for Discord. When no volume adjustment is applied, the packets from YouTube are directly passed to output, which saves CPU cycles.
  • Resource leaks are unlikely because there are no additional processes launched and only one thread per playing track. When an audio player is not queried for an user-configured amount of time, then the playing track is aborted and the thread cleaned up. This avoids thread leaks even when the audio player is not shut down as it is supposed to.

Features

Precise seeking support

Seeking is supported on all non-stream formats and sources. When a seek is performed on a playing track, the previously buffered audio samples will be provided until the seek is finished (this is configurable). When a seek is performed on a track which has not yet started, it will start immediately from the chosen position.

Due to media containers supporting seeking at different resolutions, the position that a media player can start reading data from might be several seconds from the location that the user actually wanted to seek to. LavaPlayer handles it by remembering the position where it was requested to seek to, jumping to the highest position which is not after that and then ignoring the audio until the actual position that was requested. This provides a millisecond accuracy on seeking.

Easy track loading

When creating an instance of an AudioPlayerManager, sources where the tracks should be loaded from with it must be manually registered. When loading tracks, you pass the manager an identifier and a handler which will get asynchronously called when the result has arrived. The handler has separate methods for receiving resolved tracks, resolved playlists, exceptions or being notified when nothing was found for the specified identifier.

Since the tracks hold only minimal meta-information (title, author, duration and identifier), loading playlists does not usually require the library to check the page of each individual track for sources such as YouTube or SoundCloud. This makes loading playlists pretty fast.

Load balancing

LavaPlayer includes the support for delegating the decoding/encoding/resampling operations to separate nodes running the lavaplayer-node Spring Boot application. These can be easily enabled by calling:

manager.useRemoteNodes("somehost:8080", "otherhost:8080")

The library will automatically assign the processing of new tracks to them by selecting a node based on the number of tracks they are currently processing and the CPU usage of the machine they are running on.

Extensibility

Any source that implements the AudioSourceManager interface can be registered to the player manager. These can be custom sources using either some of the supported containers and codecs or defining a totally new way the tracks are actually executed, such as delegating it to another process, should the set of formats supported by LavaPlayer by default not be enough.

Usage

Creating an audio player manager

First thing you have to do when using the library is to create a DefaultAudioPlayerManager and then configure it to use the settings and sources you want. Here is a sample:

AudioPlayerManager playerManager = new DefaultAudioPlayerManager();
AudioSourceManagers.registerRemoteSources(playerManager);

There are various configuration settings that can be modified:

  • Opus encoding and resampling quality settings.
  • Frame buffer duration: how much of audio is buffered in advance.
  • Stuck track threshold: when no data from a playing track comes in the specified time, an event is sent.
  • Abandoned player cleanup threshold: when the player is not queried in the specified amount of time, it is stopped.
  • Garbage collection monitoring: logs statistics of garbage collection pauses every 2 minutes. If the pauses are long enough to cause a stutter in the audio, it will be logged with a warning level, so you could take action to optimize your GC settings.

If possible, you should use a single instance of a player manager for your whole application. A player manager manages several thread pools which make no sense to duplicate.

Creating an audio player

Once you have a player manager, you can create players from it. Generally you would want to create a player per every different target you might want to separately stream audio to. It is totally fine to create them even if they are unlikely to be used, as they do not use any resources on their own without an active track.

Creating a player is rather simple:

AudioPlayer player = playerManager.createPlayer();

Once you have an instance of an audio player, you need some way to receive events from it. For that you should register a listener to it which either extends the AudioEventAdapter class or implements AudioEventListener. Since that listener receives the events for starting and ending tracks, it makes sense to also make it responsible for scheduling tracks. Assuming TrackScheduler is a class that implements AudioEventListener:

TrackScheduler trackScheduler = new TrackScheduler(player);
player.addListener(trackScheduler);

Now you have an audio player capable of playing instances of AudioTrack. However, what you don't have is audio tracks, which are the next things you have to obtain.

Loading audio tracks

To load a track, you have to call either the loadItem or loadItemOrdered method of an AudioPlayerManager. loadItem takes an identifier parameter and a load handler parameter. The identifier is a piece of text that should identify the track for some source. For example if it is a YouTube video ID, then YouTube source manager will load it, if it is a file path then the local file source will load it. The handler parameter is an instance of AudioLoadResultHandler, which has separate methods for different results of the loading process. You can either have a dedicated class for this or you can simply pass it an anonymous class as in the next example:

playerManager.loadItem(identifier, new AudioLoadResultHandler() {
  @Override
  public void trackLoaded(AudioTrack track) {
    trackScheduler.queue(track);
  }

  @Override
  public void playlistLoaded(AudioPlaylist playlist) {
    for (AudioTrack track : playlist.getTracks()) {
      trackScheduler.queue(track);
    }
  }

  @Override
  public void noMatches() {
    // Notify the user that we've got nothing
  }

  @Override
  public void loadFailed(FriendlyException throwable) {
    // Notify the user that everything exploded
  }
});

Most of these methods are rather obvious. In addition to everything exploding, loadFailed will also be called for example when a YouTube track is blocked or not available in your area. The FriendlyException class has a field called severity. If the value of this is COMMON, then it means that the reason is definitely not a bug or a network issue, but because the track is not available, such as the YouTube blocked video example. These message in this case can simply be forwarded as is to the user.

The other method for loading tracks, loadItemOrdered is for cases where you want the tracks to be loaded in order for example within one player. loadItemOrdered takes an ordering channel key as the first parameter, which is simply any object which remains the same for all the requests that should be loaded in the same ordered queue. The most common use would probably be to just pass it the AudioPlayer instance that the loaded tracks will be queued for.

Playing audio tracks

In the previous example I did not actually start playing the loaded track yet, but sneakily passed it on to our fictional TrackScheduler class instead. Starting the track is however a trivial thing to do:

player.playTrack(track);

Now the track should be playing, which means buffered for whoever needs it to poll its frames. However, you would need to somehow react to events, most notably the track finishing, so you could start the next track.

Handling events

Events are handled by event handlers added to an AudioPlayer instance. The simplest way for creating the handler is to extend the AudioEventAdapter class. Here is a quick description of each of the methods it has, in the context of using it for a track scheduler:

public class TrackScheduler extends AudioEventAdapter {
  @Override
  public void onPlayerPause(AudioPlayer player) {
    // Player was paused
  }

  @Override
  public void onPlayerResume(AudioPlayer player) {
    // Player was resumed
  }

  @Override
  public void onTrackStart(AudioPlayer player, AudioTrack track) {
    // A track started playing
  }

  @Override
  public void onTrackEnd(AudioPlayer player, AudioTrack track, AudioTrackEndReason endReason) {
    if (endReason.mayStartNext) {
      // Start next track
    }

    // endReason == FINISHED: A track finished or died by an exception (mayStartNext = true).
    // endReason == LOAD_FAILED: Loading of a track failed (mayStartNext = true).
    // endReason == STOPPED: The player was stopped.
    // endReason == REPLACED: Another track started playing while this had not finished
    // endReason == CLEANUP: Player hasn't been queried for a while, if you want you can put a
    //                       clone of this back to your queue
  }

  @Override
  public void onTrackException(AudioPlayer player, AudioTrack track, FriendlyException exception) {
    // An already playing track threw an exception (track end event will still be received separately)
  }

  @Override
  public void onTrackStuck(AudioPlayer player, AudioTrack track, long thresholdMs) {
    // Audio track has been unable to provide us any audio, might want to just start a new track
  }
}

JDA integration

To use it with JDA 4, you would need an instance of AudioSendHandler. There is only the slight difference of no separate canProvide and provide methods in AudioPlayer, so the wrapper for this is simple:

public class AudioPlayerSendHandler implements AudioSendHandler {
  private final AudioPlayer audioPlayer;
  private AudioFrame lastFrame;

  public AudioPlayerSendHandler(AudioPlayer audioPlayer) {
    this.audioPlayer = audioPlayer;
  }

  @Override
  public boolean canProvide() {
    lastFrame = audioPlayer.provide();
    return lastFrame != null;
  }

  @Override
  public ByteBuffer provide20MsAudio() {
    return ByteBuffer.wrap(lastFrame.getData());
  }

  @Override
  public boolean isOpus() {
    return true;
  }
}

lavaplayer's People

Contributors

21joakim avatar bytealex avatar corruptcomputer avatar danthonywalker avatar devoxin avatar devyukine avatar din0s avatar ducc avatar duncte123 avatar emzi0767 avatar freyacodes avatar gmfonseca avatar jagrosh avatar jonbeckas avatar kimcore avatar matsprehn avatar minndevelopment avatar mpotthoff avatar nayvcake avatar nikammerlaan avatar reptar25 avatar robinfriedli avatar schnapster avatar sedmelluq avatar shadorc avatar shikhir-arora avatar shredder121 avatar toxicmushroom avatar walkyst avatar xavinlol avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

lavaplayer's Issues

libs issue

Hey I'm having issues finding all the libraries that lavaplayer uses...
I installed slf4j, and tried to install logback-core but I keep getting this issue
[13:21:55] [Fatal] [JDA]: java.lang.NoClassDefFoundError: ch/qos/logback/classic/selector/ContextSelector at org.slf4j.LoggerFactory.getSingleton(LoggerFactory.java:189) at org.slf4j.LoggerFactory.bind(LoggerFactory.java:112) at org.slf4j.LoggerFactory.performInitialization(LoggerFactory.java:105) at org.slf4j.LoggerFactory.getILoggerFactory(LoggerFactory.java:235) at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:208) at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:221) at com.sedmelluq.discord.lavaplayer.player.DefaultAudioPlayerManager.<clinit>(DefaultAudioPlayerManager.java:59) at net.mrwhitegoat.gabethedog.GabeListener.onGuildMessageReceived(GabeListener.java:43) at net.dv8tion.jda.core.hooks.ListenerAdapter.onEvent(ListenerAdapter.java:307) at net.dv8tion.jda.core.hooks.InterfacedEventManager.handle(InterfacedEventManager.java:64) at net.dv8tion.jda.core.handle.MessageCreateHandler.handleDefaultMessage(MessageCreateHandler.java:101) at net.dv8tion.jda.core.handle.MessageCreateHandler.handleInternally(MessageCreateHandler.java:51) at net.dv8tion.jda.core.handle.SocketHandler.handle(SocketHandler.java:38) at net.dv8tion.jda.core.requests.WebSocketClient.handleEvent(WebSocketClient.java:688) at net.dv8tion.jda.core.requests.WebSocketClient.onTextMessage(WebSocketClient.java:437) at com.neovisionaries.ws.client.ListenerManager.callOnTextMessage(ListenerManager.java:352) at com.neovisionaries.ws.client.ReadingThread.callOnTextMessage(ReadingThread.java:262) at com.neovisionaries.ws.client.ReadingThread.callOnTextMessage(ReadingThread.java:240) at com.neovisionaries.ws.client.ReadingThread.handleTextFrame(ReadingThread.java:965) at com.neovisionaries.ws.client.ReadingThread.handleFrame(ReadingThread.java:748) at com.neovisionaries.ws.client.ReadingThread.main(ReadingThread.java:110) at com.neovisionaries.ws.client.ReadingThread.run(ReadingThread.java:66) Caused by: java.lang.ClassNotFoundException: ch.qos.logback.classic.selector.ContextSelector at java.net.URLClassLoader.findClass(URLClassLoader.java:381) at java.lang.ClassLoader.loadClass(ClassLoader.java:424) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331) at java.lang.ClassLoader.loadClass(ClassLoader.java:357) ... 22 more

InterruptedException

Hello Sedmelluq,
if a track is ending the player give us an InterruptedException. Discord make an update can you please update the player.

Full Exception:

at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireSharedInterruptibly(AbstractQueuedSynchronizer.java:1302)
at java.util.concurrent.Semaphore.acquire(Semaphore.java:312)
at net.dv8tion.jda.core.requests.WebSocketClient.queueAudioDisconnect(WebSocketClient.java:1115)
at net.dv8tion.jda.core.audio.AudioWebSocket.close(AudioWebSocket.java:450)
at net.dv8tion.jda.core.audio.AudioConnection.close(AudioConnection.java:226)
at net.dv8tion.jda.core.managers.impl.AudioManagerImpl.closeAudioConnection(AudioManagerImpl.java:139)
at net.dv8tion.jda.core.managers.impl.AudioManagerImpl.closeAudioConnection(AudioManagerImpl.java:130)
at audioManager.TrackManager.onTrackEnd(TrackManager.java:79)
at com.sedmelluq.discord.lavaplayer.player.event.AudioEventAdapter.onEvent(AudioEventAdapter.java:70)
at com.sedmelluq.discord.lavaplayer.player.AudioPlayer.dispatchEvent(AudioPlayer.java:295)
at com.sedmelluq.discord.lavaplayer.player.AudioPlayer.handleTerminator(AudioPlayer.java:217)
at com.sedmelluq.discord.lavaplayer.player.AudioPlayer.provideDirectly(AudioPlayer.java:197)
at com.sedmelluq.discord.lavaplayer.player.AudioPlayer.provide(AudioPlayer.java:167)
at com.sedmelluq.discord.lavaplayer.track.playback.AudioFrameProviderTools.delegateToTimedProvide(AudioFrameProviderTools.java:18)
at com.sedmelluq.discord.lavaplayer.player.AudioPlayer.provide(AudioPlayer.java:162)
at audioManager.PlayerSendHandler.canProvide(PlayerSendHandler.java:18)
at net.dv8tion.jda.core.audio.AudioConnection$PacketProvider.getNextPacket(AudioConnection.java:607)
at net.dv8tion.jda.core.audio.factory.DefaultSendSystem.lambda$start$61(DefaultSendSystem.java:57)
at java.lang.Thread.run(Thread.java:748)

Sorry for my bad english i am german.

~Endergame15

Error while trying to play music

I'm trying to use the JDA Demo with the latest version of lavaplayer and i get this error whenever I try to play music.
java.lang.ClassNotFoundException: com.sedmelluq.discord.lavaplayer.tools.DaemonThreadFactory

SocketTimeouts

Hello,

I've been experiencing SocketTimeouts when playing the Monster cat 24/7 stream. When I first issue the play command, the bot will play the stream normally, but anywhere from 15mins to 1hour, Lavalink will stop playing out of nowhere and the following exception will be raised: https://sentry.io/share/issue/3232313230322e333536343935383737/

This doesn't happen when playing long videos from youtube, so it seems to be an issue related to twitch.tv.

I'm running lavalink (lavaplayer 1.2.43, lavalink 1.1) as a systemd unit service, on an ubuntu 16.04 box. Neither my machine or network are being rammed, for now this machine is only playing one song at a time.

Java information (default-jre):

openjdk version "1.8.0_131"
OpenJDK Runtime Environment (build 1.8.0_131-8u131-b11-2ubuntu1.16.04.3-b11)
OpenJDK 64-Bit Server VM (build 25.131-b11, mixed mode)

If it matters, lavalink is running with root privileges. I am using eris-lavalink as a client.

Is this normal behavior? Am I supposed to handle this somehow?

erros.log:
[11:27:36] [lava-daemon-pool-info-loader-2-thread-1] [AudioLoader] Load failed com.sedmelluq.discord.lavaplayer.tools.FriendlyException: Loading Twitch channel information failed. at com.sedmelluq.discord.lavaplayer.source.twitch.TwitchStreamAudioSourceManager.fetchStreamChannelInfo(TwitchStreamAudioSourceManager.java:146) at com.sedmelluq.discord.lavaplayer.source.twitch.TwitchStreamAudioSourceManager.loadItem(TwitchStreamAudioSourceManager.java:59) at com.sedmelluq.discord.lavaplayer.player.DefaultAudioPlayerManager.checkSourcesForItemOnce(DefaultAudioPlayerManager.java:429) at com.sedmelluq.discord.lavaplayer.player.DefaultAudioPlayerManager.checkSourcesForItem(DefaultAudioPlayerManager.java:415) at com.sedmelluq.discord.lavaplayer.player.DefaultAudioPlayerManager.lambda$createItemLoader$0(DefaultAudioPlayerManager.java:219) at java.util.concurrent.FutureTask.run(FutureTask.java:266) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at java.lang.Thread.run(Thread.java:748) Caused by: java.net.SocketTimeoutException: Read timed out at java.net.SocketInputStream.socketRead0(Native Method) at java.net.SocketInputStream.socketRead(SocketInputStream.java:116) at java.net.SocketInputStream.read(SocketInputStream.java:171) at java.net.SocketInputStream.read(SocketInputStream.java:141) at sun.security.ssl.InputRecord.readFully(InputRecord.java:465) at sun.security.ssl.InputRecord.read(InputRecord.java:503) at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:973) at sun.security.ssl.SSLSocketImpl.readDataRecord(SSLSocketImpl.java:930) at sun.security.ssl.AppInputStream.read(AppInputStream.java:105) at org.apache.http.impl.io.SessionInputBufferImpl.streamRead(SessionInputBufferImpl.java:139) at org.apache.http.impl.io.SessionInputBufferImpl.fillBuffer(SessionInputBufferImpl.java:155) at org.apache.http.impl.io.SessionInputBufferImpl.readLine(SessionInputBufferImpl.java:284) at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:140) at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:57) at org.apache.http.impl.io.AbstractMessageParser.parse(AbstractMessageParser.java:261) at org.apache.http.impl.DefaultBHttpClientConnection.receiveResponseHeader(DefaultBHttpClientConnection.java:165) at org.apache.http.impl.conn.CPoolProxy.receiveResponseHeader(CPoolProxy.java:167) at org.apache.http.protocol.HttpRequestExecutor.doReceiveResponse(HttpRequestExecutor.java:272) at org.apache.http.protocol.HttpRequestExecutor.execute(HttpRequestExecutor.java:124) at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:271) at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:184) at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:88) at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110) at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:184) at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82) at com.sedmelluq.discord.lavaplayer.tools.io.HttpInterface.execute(HttpInterface.java:60) at com.sedmelluq.discord.lavaplayer.tools.io.HttpClientTools.fetchResponseAsJson(HttpClientTools.java:286) at com.sedmelluq.discord.lavaplayer.source.twitch.TwitchStreamAudioSourceManager.fetchStreamChannelInfo(TwitchStreamAudioSourceManager.java:144) ... 8 common frames omitted [17:46:06] [lava-daemon-pool-info-loader-2-thread-1] [AudioLoader] Load failed com.sedmelluq.discord.lavaplayer.tools.FriendlyException: Loading Twitch channel information failed. at com.sedmelluq.discord.lavaplayer.source.twitch.TwitchStreamAudioSourceManager.fetchStreamChannelInfo(TwitchStreamAudioSourceManager.java:146) at com.sedmelluq.discord.lavaplayer.source.twitch.TwitchStreamAudioSourceManager.loadItem(TwitchStreamAudioSourceManager.java:59) at com.sedmelluq.discord.lavaplayer.player.DefaultAudioPlayerManager.checkSourcesForItemOnce(DefaultAudioPlayerManager.java:429) at com.sedmelluq.discord.lavaplayer.player.DefaultAudioPlayerManager.checkSourcesForItem(DefaultAudioPlayerManager.java:415) at com.sedmelluq.discord.lavaplayer.player.DefaultAudioPlayerManager.lambda$createItemLoader$0(DefaultAudioPlayerManager.java:219) at java.util.concurrent.FutureTask.run(FutureTask.java:266) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at java.lang.Thread.run(Thread.java:748) Caused by: java.net.SocketTimeoutException: Read timed out at java.net.SocketInputStream.socketRead0(Native Method) at java.net.SocketInputStream.socketRead(SocketInputStream.java:116) at java.net.SocketInputStream.read(SocketInputStream.java:171) at java.net.SocketInputStream.read(SocketInputStream.java:141) at sun.security.ssl.InputRecord.readFully(InputRecord.java:465) at sun.security.ssl.InputRecord.read(InputRecord.java:503) at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:973) at sun.security.ssl.SSLSocketImpl.readDataRecord(SSLSocketImpl.java:930) at sun.security.ssl.AppInputStream.read(AppInputStream.java:105) at org.apache.http.impl.io.SessionInputBufferImpl.streamRead(SessionInputBufferImpl.java:139) at org.apache.http.impl.io.SessionInputBufferImpl.fillBuffer(SessionInputBufferImpl.java:155) at org.apache.http.impl.io.SessionInputBufferImpl.readLine(SessionInputBufferImpl.java:284) at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:140) at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:57) at org.apache.http.impl.io.AbstractMessageParser.parse(AbstractMessageParser.java:261) at org.apache.http.impl.DefaultBHttpClientConnection.receiveResponseHeader(DefaultBHttpClientConnection.java:165) at org.apache.http.impl.conn.CPoolProxy.receiveResponseHeader(CPoolProxy.java:167) at org.apache.http.protocol.HttpRequestExecutor.doReceiveResponse(HttpRequestExecutor.java:272) at org.apache.http.protocol.HttpRequestExecutor.execute(HttpRequestExecutor.java:124) at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:271) at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:184) at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:88) at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110) at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:184) at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82) at com.sedmelluq.discord.lavaplayer.tools.io.HttpInterface.execute(HttpInterface.java:60) at com.sedmelluq.discord.lavaplayer.tools.io.HttpClientTools.fetchResponseAsJson(HttpClientTools.java:286) at com.sedmelluq.discord.lavaplayer.source.twitch.TwitchStreamAudioSourceManager.fetchStreamChannelInfo(TwitchStreamAudioSourceManager.java:144) ... 8 common frames omitted

I can run tests and provide more information if needed.

Chiptune Support?

I have a friend whose Discord music bot apparently uses this player. I'm wondering if including support for various chiptune formats, such as .spc, .vgm, and .nsf, would be possible. There are no doubt some open chiptune players here or elsewhere on the internet.

Compile Error

Hi i cant compile, i dont rly know how to do it and when i test with gradlew build the error is:

FAILURE: Build failed with an exception.

  • Where:
    Build file 'C:\Users\renardn\Desktop\lavaplayer-master\lavaplayer-master\natives
    \build.gradle' line: 119

  • What went wrong:
    Execution failed for task ':natives:connector-32-setup'.

Cannot run program "cmake" (in directory "C:\Users\renardn\Desktop\lavaplayer-
master\lavaplayer-master\natives\build\tmp\vsloc"): CreateProcess error=2, File not found

Audio Stuttering

I have been trying to figure out why my bot's audio stutters and I think it may be an issue with lavaplayer. At first I thought the issue was with Discord4J, as I have been told this is an issue if I use its built in audio player, but I am using lavaplayer for my audio. My bot is based on this example provided: https://github.com/decyg/d4jexamplebot

Is there an issue with that that causes the audio to stutter, or should I just live with it and assume its normal?

High CPU Usage on RPi3

When streaming a video from YouTube, HTOP reports CPU usage of 100% and the sound playback stutters. A Raspberry Pi 3 should easily be able to stream and process audio; prior to using LavaPlayer I was using JDA's old built-in system on a RPi 1A without an issue.

Is there anything I can do to reduce CPU usage, otherwise I believe this should be considered an issue worth looking into?

It is perhaps also worth noting that on my desktop PC the application is reported as using 0% CPU; perhaps the network IO is straining the Pi?

Required library at /natives/linux-arm/libconnector.so was not found: Rpi3(Raspian 8)

Hello,

I'm encountering an issue with running the bot on a RPi3 as a JAR. It connects fine but once a track is queued for playback it errors out on missing dependencies:
[18:11:24] [Info] [JDA]: Login Successful! [18:11:25] [Info] [JDASocket]: Connected to WebSocket [18:11:25] [Info] [JDA]: Finished Loading! [18:11:35] [Info] [JDAAudioManager]: Audio System successfully setup! Exception in thread "lava-daemon-pool-playback-1-thread-1" java.lang.UnsatisfiedLinkError: Required library at /natives/linux-arm/libconnector.so was not found at com.sedmelluq.discord.lavaplayer.natives.NativeLibLoader.extractLibrary(NativeLibLoader.java:93) at com.sedmelluq.discord.lavaplayer.natives.NativeLibLoader.load(NativeLibLoader.java:77) at com.sedmelluq.discord.lavaplayer.natives.ConnectorNativeLibLoader.loadConnectorLibrary(ConnectorNativeLibLoader.java:17) at com.sedmelluq.discord.lavaplayer.natives.vorbis.VorbisDecoderLibrary.getInstance(VorbisDecoderLibrary.java:13) at com.sedmelluq.discord.lavaplayer.natives.vorbis.VorbisDecoder.<init>(VorbisDecoder.java:19) at com.sedmelluq.discord.lavaplayer.container.ogg.OggVorbisTrackProvider.<init>(OggVorbisTrackProvider.java:33) at com.sedmelluq.discord.lavaplayer.container.ogg.OggTrackLoader.chooseTrackFromIdentifier(OggTrackLoader.java:40) at com.sedmelluq.discord.lavaplayer.container.ogg.OggTrackLoader.loadTrack(OggTrackLoader.java:31) at com.sedmelluq.discord.lavaplayer.container.ogg.OggAudioTrack.processTrackLoop(OggAudioTrack.java:50) at com.sedmelluq.discord.lavaplayer.container.ogg.OggAudioTrack.lambda$process$0(OggAudioTrack.java:42) at com.sedmelluq.discord.lavaplayer.track.playback.LocalAudioTrackExecutor.executeProcessingLoop(LocalAudioTrackExecutor.java:248) at com.sedmelluq.discord.lavaplayer.container.ogg.OggAudioTrack.process(OggAudioTrack.java:40) at com.sedmelluq.discord.lavaplayer.track.DelegatedAudioTrack.processDelegate(DelegatedAudioTrack.java:27) at com.sedmelluq.discord.lavaplayer.source.http.HttpAudioTrack.process(HttpAudioTrack.java:51) at com.sedmelluq.discord.lavaplayer.track.playback.LocalAudioTrackExecutor.execute(LocalAudioTrackExecutor.java:90) at com.sedmelluq.discord.lavaplayer.player.DefaultAudioPlayerManager.lambda$executeTrack$1(DefaultAudioPlayerManager.java:348) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at java.lang.Thread.run(Thread.java:745)

I used maven to built this bot and the same JAR functions fine on Windows systems.

Seek into tracks with undefined duration?

What is the best way (if any) to seek tracks that Lavaplayer determines to not be seekable? I have some tracks that I queue and are local (queued directly from a link). They are encoded using opusenc and are correctly formatted (48K, 2 channel, VBR). They do have the correct metadata and Lavaplayer recognizes the ogg container format. However, the duration is set to Long.MAX_VALUE making seeking impossible on these tracks.

I assume it's because the OggOpusTrackStream in Lavaplayer returns an unsupported operation exception for the seekToTimecode method by default.

Is there a better way to encode these tracks on my end (MP3 and the likes work fine), or does something like GreedyInputStream have to be used to override and seek into tracks until the buffer is invalid or throws an EOF?

Thanks!

Feature request: ARM support

Trying to compile this in an ARM based devices such as Raspberry Pi 3 results in failure, particularly the native libraries in the "natives" folder.

Browsing the source code of build.gradle and natives/build.gradle indicates that it only supports x86 & x86-64 for Linux.

Doesn't work on Raspberry Pi 2

I get this when I try to play something:

Exception in thread "lava-daemon-pool-playback-1-thread-1" java.lang.UnsatisfiedLinkError: Required library at /natives/linux-arm/libconnector.so was not found
        at com.sedmelluq.discord.lavaplayer.natives.NativeLibLoader.extractLibrary(NativeLibLoader.java:93)
        at com.sedmelluq.discord.lavaplayer.natives.NativeLibLoader.load(NativeLibLoader.java:77)
        at com.sedmelluq.discord.lavaplayer.natives.ConnectorNativeLibLoader.loadConnectorLibrary(ConnectorNativeLibLoader.java:17)
        at com.sedmelluq.discord.lavaplayer.natives.aac.AacDecoderLibrary.getInstance(AacDecoderLibrary.java:14)
        at com.sedmelluq.discord.lavaplayer.natives.aac.AacDecoder.<init>(AacDecoder.java:28)
        at com.sedmelluq.discord.lavaplayer.container.mpeg.MpegAacTrackConsumer.<init>(MpegAacTrackConsumer.java:38)
        at com.sedmelluq.discord.lavaplayer.container.mpeg.MpegAudioTrack.selectAudioTrack(MpegAudioTrack.java:86)
        at com.sedmelluq.discord.lavaplayer.container.mpeg.MpegAudioTrack.loadAudioTrack(MpegAudioTrack.java:63)
        at com.sedmelluq.discord.lavaplayer.container.mpeg.MpegAudioTrack.process(MpegAudioTrack.java:42)
        at com.sedmelluq.discord.lavaplayer.track.DelegatedAudioTrack.processDelegate(DelegatedAudioTrack.java:27)
        at com.sedmelluq.discord.lavaplayer.source.youtube.YoutubeAudioTrack.processStatic(YoutubeAudioTrack.java:77)
        at com.sedmelluq.discord.lavaplayer.source.youtube.YoutubeAudioTrack.process(YoutubeAudioTrack.java:67)
        at com.sedmelluq.discord.lavaplayer.track.playback.LocalAudioTrackExecutor.execute(LocalAudioTrackExecutor.java:90)
        at com.sedmelluq.discord.lavaplayer.player.DefaultAudioPlayerManager.lambda$executeTrack$1(DefaultAudioPlayerManager.java:348)
        at com.sedmelluq.discord.lavaplayer.player.DefaultAudioPlayerManager$$Lambda$51/20864022.run(Unknown Source)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
        at java.lang.Thread.run(Thread.java:745)

Converting raw PCM data into an AudioTrack

I've got a custom program that streams data from a device in my house,
perioidcally, public int onAudioDataDelivered(short[] samples, int sampleCount, int sampleRate, int channels) is called to deliver the stream.

How do I convert this into an AudioTrack?

Unable to get a match for any identifier string passed

Hey there! I'm having an issue integrating your project into an existing bot code base. I'm mostly trying to get a file path on my computer pointing to wav or mp3 files to be read and played. Here is where that is done in my code:

   private void playFile(File audioFile, Guild guild) {
    	AudioManager audio = guild.getAudioManager();
    	AudioPlayer player;
    	if (audio.getSendingHandler() == null || audioSchedulers.get(guild) == null) {
    		// Create a new player.
    		player = dispatcher.getAudioManager().createPlayer();
    		audio.setSendingHandler(new AudioPlayerSendHandler(player));
    		AudioTrackScheduler scheduler = new AudioTrackScheduler();
    		player.addListener(scheduler);
    		audioSchedulers.put(guild, scheduler);
    	} else {
    		player = ((AudioPlayerSendHandler)(audio.getSendingHandler())).getPlayer();
    	}
		String path = audioFile.getPath();
		LOG.info("Sending request for '" + path + "' to AudioManager");
		dispatcher.getAudioManager().loadItem(path, new AudioHandler(player));
    }

Where AudioHandler is defined as:

package net.dirtydeeds.discordsoundboard.audio;

import com.sedmelluq.discord.lavaplayer.player.AudioLoadResultHandler;
import com.sedmelluq.discord.lavaplayer.player.AudioPlayer;
import com.sedmelluq.discord.lavaplayer.tools.FriendlyException;
import com.sedmelluq.discord.lavaplayer.track.AudioPlaylist;
import com.sedmelluq.discord.lavaplayer.track.AudioTrack;

import net.dv8tion.jda.core.utils.SimpleLog;

public class AudioHandler implements AudioLoadResultHandler {

	public static final SimpleLog LOG = SimpleLog.getLog("AudioHandler");
	
	private AudioPlayer player;
	
	public AudioHandler(AudioPlayer player) {
		this.player = player;
	}
	
	@Override
	public void trackLoaded(AudioTrack track) {
		LOG.info("Loaded track " + track.getIdentifier() + " => " + track);
		boolean started = player.startTrack(track, false);
		LOG.info("Started track with success: " + started);
	}

	@Override
	public void playlistLoaded(AudioPlaylist playlist) {
	}

	@Override
	public void noMatches() {
		LOG.warn("No match for audio identifier.");
	}

	@Override
	public void loadFailed(FriendlyException exception) {
		exception.printStackTrace();
	}

}

However, I seem to keep hitting the noMatches() function call for the path being passed (e.g., /home/safatli/Code/sounds/Memes/inception.mp3). I've also tried to pass a YouTube URL and am getting the same result.

Any insight?

Player stops while playing a YouTube livestream

Hey,

I always get a strange issue, if I play a YouTube livestream with the lavaplayer. The stream works for 1 - 3 hours, after that the bot stops playing and throws an exception. Sometimes it is this:

issue 1

But even sometimes it is this:

issue 2

Everything else (Non-youtubelivestream) seems to be working. (Twitch, Soundcloud etc.)

Cannot play local files on Mac OS

When playing locally stored files i get the following error:

Stacktrace:
http://pastebin.com/DqLsr3pC

I am compiling and running on Mac OS X.

build.gradle:

repositories {
[...]
    jcenter()
}
dependencies {
[...]
    compile 'com.sedmelluq:lavaplayer:1.1.37'
}

The files are valid and can be played with other players.

Constantly getting a FriendlyException randomly.

Does anyone have a solution for that, or knows what i am doing wrong?
Thanks for the Help.


[23:24:25] [ ERROR] [LocalAudioTrackExecutor] Error in playback of EFqjDXy9s5A
com.sedmelluq.discord.lavaplayer.tools.FriendlyException: Something broke when playing the track.
at com.sedmelluq.discord.lavaplayer.tools.ExceptionTools.wrapUnfriendlyExceptions(ExceptionTools.java:40)
at com.sedmelluq.discord.lavaplayer.track.playback.LocalAudioTrackExecutor.execute(LocalAudioTrackExecutor.java:97)
at com.sedmelluq.discord.lavaplayer.player.DefaultAudioPlayerManager.lambda$executeTrack$1(DefaultAudioPlayerManager.java:315)
at com.sedmelluq.discord.lavaplayer.player.DefaultAudioPlayerManager$$Lambda$31/1898224592.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.RuntimeException: org.apache.http.NoHttpResponseException: r2---sn-4g5e6nez.googlevideo.com:443 failed to respond
at com.sedmelluq.discord.lavaplayer.container.matroska.MatroskaAudioTrack.loadMatroskaFile(MatroskaAudioTrack.java:56)
at com.sedmelluq.discord.lavaplayer.container.matroska.MatroskaAudioTrack.process(MatroskaAudioTrack.java:34)
at com.sedmelluq.discord.lavaplayer.track.DelegatedAudioTrack.processDelegate(DelegatedAudioTrack.java:27)
at com.sedmelluq.discord.lavaplayer.source.youtube.YoutubeAudioTrack.processStatic(YoutubeAudioTrack.java:75)
at com.sedmelluq.discord.lavaplayer.source.youtube.YoutubeAudioTrack.process(YoutubeAudioTrack.java:67)
at com.sedmelluq.discord.lavaplayer.track.playback.LocalAudioTrackExecutor.execute(LocalAudioTrackExecutor.java:89)
... 5 common frames omitted
Caused by: org.apache.http.NoHttpResponseException: r2---sn-4g5e6nez.googlevideo.com:443 failed to respond
at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:143)
at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:57)
at org.apache.http.impl.io.AbstractMessageParser.parse(AbstractMessageParser.java:261)
at org.apache.http.impl.DefaultBHttpClientConnection.receiveResponseHeader(DefaultBHttpClientConnection.java:165)
at org.apache.http.impl.conn.CPoolProxy.receiveResponseHeader(CPoolProxy.java:167)
at org.apache.http.protocol.HttpRequestExecutor.doReceiveResponse(HttpRequestExecutor.java:272)
at org.apache.http.protocol.HttpRequestExecutor.execute(HttpRequestExecutor.java:124)
at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:271)
at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:184)
at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:88)
at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110)
at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:184)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82)
at com.sedmelluq.discord.lavaplayer.tools.io.HttpInterface.execute(HttpInterface.java:56)
at com.sedmelluq.discord.lavaplayer.tools.io.PersistentHttpStream.connect(PersistentHttpStream.java:94)
at com.sedmelluq.discord.lavaplayer.tools.io.PersistentHttpStream.internalRead(PersistentHttpStream.java:122)
at com.sedmelluq.discord.lavaplayer.tools.io.PersistentHttpStream.read(PersistentHttpStream.java:138)
at java.io.DataInputStream.readByte(DataInputStream.java:265)
at com.sedmelluq.discord.lavaplayer.container.matroska.format.MatroskaEbmlReader.readEbmlInteger(MatroskaEbmlReader.java:39)
at com.sedmelluq.discord.lavaplayer.container.matroska.format.MatroskaFileReader.readNextElement(MatroskaFileReader.java:40)
at com.sedmelluq.discord.lavaplayer.container.matroska.MatroskaStreamingFile.readFile(MatroskaStreamingFile.java:79)
at com.sedmelluq.discord.lavaplayer.container.matroska.MatroskaAudioTrack.loadMatroskaFile(MatroskaAudioTrack.java:51)
... 10 common frames omitted

Audio lagging / Skipping issues

I really love this lib as it's light yet powerful. But my bot experiencing some issues with playback rate, sometimes the song got jumpy, faster/slower. Is this mainly because of the ping to discord server? My machine is 2 Cores with 2GB mem. Please address how I would fix it.

Playing certain YouTube videos causes an exception

I get the following exception:

com.sedmelluq.discord.lavaplayer.tools.FriendlyException: Something broke when playing the track.
	at com.sedmelluq.discord.lavaplayer.tools.ExceptionTools.wrapUnfriendlyExceptions(ExceptionTools.java:40)
	at com.sedmelluq.discord.lavaplayer.track.playback.LocalAudioTrackExecutor.execute(LocalAudioTrackExecutor.java:102)
	at com.sedmelluq.discord.lavaplayer.player.DefaultAudioPlayerManager.lambda$executeTrack$1(DefaultAudioPlayerManager.java:348)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
	at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.IllegalStateException: Must find action functions from script.
	at com.sedmelluq.discord.lavaplayer.source.youtube.YoutubeSignatureCipherManager.extractTokensFromScript(YoutubeSignatureCipherManager.java:164)
	at com.sedmelluq.discord.lavaplayer.source.youtube.YoutubeSignatureCipherManager.getCipherKeyFromScript(YoutubeSignatureCipherManager.java:129)
	at com.sedmelluq.discord.lavaplayer.source.youtube.YoutubeSignatureCipherManager.getValidUrl(YoutubeSignatureCipherManager.java:88)
	at com.sedmelluq.discord.lavaplayer.source.youtube.YoutubeAudioTrack.loadBestFormatWithUrl(YoutubeAudioTrack.java:99)
	at com.sedmelluq.discord.lavaplayer.source.youtube.YoutubeAudioTrack.process(YoutubeAudioTrack.java:60)
	at com.sedmelluq.discord.lavaplayer.track.playback.LocalAudioTrackExecutor.execute(LocalAudioTrackExecutor.java:90)
	... 4 more

So far, the only video this has happened with is https://www.youtube.com/watch?v=tG35R8F2j8k. Every time I try and play this video, this exception gets thrown.

Playing audio and loadItem() has a few seconds delay

I have a folder full of small mp3-files (1 to 5 seconds). They are freshly encoded and without errors. I am using v1.1.41.
Every few invokations the audio takes a few seconds to be played. Additionally, following exception is thrown nearly every time a file is played:

22:45:05.664 [Voice Send Handler] ERROR sx.blah.discord.Discord4J - Encountered error on voice websocket:
org.eclipse.jetty.io.EofException: null
	at org.eclipse.jetty.io.ChannelEndPoint.flush(ChannelEndPoint.java:292)
	at org.eclipse.jetty.io.ssl.SslConnection$DecryptedEndPoint.flush(SslConnection.java:936)
	at org.eclipse.jetty.io.WriteFlusher.flush(WriteFlusher.java:429)
	at org.eclipse.jetty.io.WriteFlusher.write(WriteFlusher.java:322)
	at org.eclipse.jetty.io.AbstractEndPoint.write(AbstractEndPoint.java:372)
	at org.eclipse.jetty.websocket.common.io.FrameFlusher$Flusher.flush(FrameFlusher.java:153)
	at org.eclipse.jetty.websocket.common.io.FrameFlusher$Flusher.process(FrameFlusher.java:217)
	at org.eclipse.jetty.util.IteratingCallback.processing(IteratingCallback.java:241)
	at org.eclipse.jetty.util.IteratingCallback.iterate(IteratingCallback.java:224)
	at org.eclipse.jetty.websocket.common.io.FrameFlusher.enqueue(FrameFlusher.java:382)
	at org.eclipse.jetty.websocket.common.io.AbstractWebSocketConnection.outgoingFrame(AbstractWebSocketConnection.java:614)
	at org.eclipse.jetty.websocket.client.io.WebSocketClientConnection.outgoingFrame(WebSocketClientConnection.java:72)
	at org.eclipse.jetty.websocket.common.io.AbstractWebSocketConnection.close(AbstractWebSocketConnection.java:289)
	at org.eclipse.jetty.websocket.common.io.AbstractWebSocketConnection.close(AbstractWebSocketConnection.java:283)
	at org.eclipse.jetty.websocket.common.WebSocketSession.close(WebSocketSession.java:123)
	at sx.blah.discord.api.internal.DiscordVoiceWS.disconnect(DiscordVoiceWS.java:137)
	at sx.blah.discord.handle.impl.obj.VoiceChannel.leave(VoiceChannel.java:119)
	at main.Main.leaveVoiceChannel(Main.java:110)
	at main.Main.handleTrackFinished(Main.java:298)
	at util.TrackScheduler.onTrackEnd(LavaPlayer.java:119)
	at com.sedmelluq.discord.lavaplayer.player.event.AudioEventAdapter.onEvent(AudioEventAdapter.java:70)
	at com.sedmelluq.discord.lavaplayer.player.AudioPlayer.dispatchEvent(AudioPlayer.java:282)
	at com.sedmelluq.discord.lavaplayer.player.AudioPlayer.handleTerminator(AudioPlayer.java:211)
	at com.sedmelluq.discord.lavaplayer.player.AudioPlayer.provideDirectly(AudioPlayer.java:188)
	at com.sedmelluq.discord.lavaplayer.player.AudioPlayer.provide(AudioPlayer.java:160)
	at util.AudioProvider.isReady(LavaPlayer.java:175)
	at sx.blah.discord.handle.audio.impl.DefaultProcessor.isReady(DefaultProcessor.java:21)
	at sx.blah.discord.handle.audio.impl.AudioManager.getAudioDataForProvider(AudioManager.java:87)
	at sx.blah.discord.handle.audio.impl.AudioManager.getAudio(AudioManager.java:78)
	at sx.blah.discord.api.internal.DiscordVoiceWS$1.run(DiscordVoiceWS.java:153)
	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
	at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308)
	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:180)
	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
	at java.lang.Thread.run(Thread.java:745)
Caused by: java.nio.channels.ClosedByInterruptException: null
	at java.nio.channels.spi.AbstractInterruptibleChannel.end(AbstractInterruptibleChannel.java:202)
	at sun.nio.ch.SocketChannelImpl.write(SocketChannelImpl.java:478)
	at org.eclipse.jetty.io.ChannelEndPoint.flush(ChannelEndPoint.java:270)
	... 36 common frames omitted

My code is loosely based on the Discord4J-Demo. I marked in my code where the delays are produced.

public class LavaPlayer {
  private final AudioPlayerManager playerManager;
  private final Map<Long, GuildMusicManager> musicManagers;
  
  public LavaPlayer() {
    this.musicManagers = new HashMap<>();
    
    this.playerManager = new DefaultAudioPlayerManager();
    AudioSourceManagers.registerRemoteSources(playerManager);
    AudioSourceManagers.registerLocalSource(playerManager);
  }
  
  private synchronized GuildMusicManager getGuildAudioPlayer(IGuild guild) {
    long guildId = Long.parseLong(guild.getID());
    GuildMusicManager musicManager = musicManagers.get(guildId);
    
    if (musicManager == null) {
      musicManager = new GuildMusicManager(playerManager, guild);
      musicManagers.put(guildId, musicManager);
    }
    
    guild.getAudioManager().setAudioProvider(musicManager.getAudioProvider());
    
    return musicManager;
  }
  
  public void playAudio(IVoiceChannel voiceChannel, IChannel textChannel, URL soundFile, IUser user) {
    
    GuildMusicManager musicManager = getGuildAudioPlayer(textChannel.getGuild());
    
    playerManager.loadItem(soundFile.getPath(), new AudioLoadResultHandler() {
      @Override
      public void trackLoaded(AudioTrack track) {

// sometimes bot takes a few seconds to join channel
        voiceChannel.join();

// sometimes bot takes a few seconds to play audio after joining
        musicManager.player.playTrack(track);
      }
      
      @Override
      public void playlistLoaded(AudioPlaylist playlist) {}
      
      @Override
      public void noMatches() {}
      
      @Override
      public void loadFailed(FriendlyException exception) {
        Main.getInstance().writeMessage(textChannel, "Could not play: " + exception.getMessage());
      }
    });
  }
}

class GuildMusicManager {
  public final AudioPlayer player;
  
  public GuildMusicManager(AudioPlayerManager manager, IGuild guild) {
    player = manager.createPlayer();

    player.addListener(new AudioEventAdapter() {
      @Override
      public void onTrackEnd(AudioPlayer player, AudioTrack track, AudioTrackEndReason endReason) {
        Main.getInstance().handleTrackFinished(guild);
      }
    });
  }
  
  public AudioProvider getAudioProvider() {
    return new AudioProvider(player);
  }
}

class AudioProvider implements IAudioProvider {
  private final AudioPlayer audioPlayer;
  private AudioFrame lastFrame;
  
  public AudioProvider(AudioPlayer audioPlayer) {
    this.audioPlayer = audioPlayer;
  }
  
  @Override
  public boolean isReady() {
    if (lastFrame == null) {
      lastFrame = audioPlayer.provide();
    }
    
    return lastFrame != null;
  }
  
  @Override
  public byte[] provide() {
    if (lastFrame == null) {
      lastFrame = audioPlayer.provide();
    }
    
    byte[] data = lastFrame != null ? lastFrame.data : null;
    lastFrame = null;
    
    return data;
  }
  
  @Override
  public int getChannels() {
    return 2;
  }
  
  @Override
  public AudioEncodingType getAudioEncodingType() {
    return AudioEncodingType.OPUS;
  }
}

I don't know where to go from here.

Additional info: The bot ist hosted on a 2GHz, 2GB RAM machine with 100 MBit/s upload. There are roughly 1600 connected guilds, the bot is invoked every few seconds.

No ".index/nexus-maven-repository-index.properties"

There is no .index/nexus-maven-repository-index.properties file. Because of that, the repository can't be updated and LavaPlayer not used.

Stacktrace from IntelliJ (2016.3.2):

Caused by: java.lang.RuntimeException: java.lang.RuntimeException: java.io.FileNotFoundException: Resource nexus-maven-repository-index.properties does not exist
        at org.jetbrains.idea.maven.server.Maven3ServerIndexerImpl$2.run(Maven3ServerIndexerImpl.java:204)
        at org.jetbrains.idea.maven.server.Maven3ServerEmbedderImpl.executeWithMavenSession(Maven3ServerEmbedderImpl.java:621)
        at org.jetbrains.idea.maven.server.Maven3ServerIndexerImpl.updateIndex(Maven3ServerIndexerImpl.java:170)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:324)
        at sun.rmi.transport.Transport$1.run(Transport.java:200)
        at sun.rmi.transport.Transport$1.run(Transport.java:197)
        at java.security.AccessController.doPrivileged(Native Method)
        at sun.rmi.transport.Transport.serviceCall(Transport.java:196)
        at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:568)
        at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:826)
        at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:683)
        at java.security.AccessController.doPrivileged(Native Method)
        at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:682)

Youtube region restriction

Hello,

First, Thank you for made lavaplayer.
I am using lavaplayer well, but having some issue about Youtube region restriction. For example, this video cannot play outside of South Korea and Japan. The server that using lavaplayer is in Japan but It is not working with following error message.
This video contains content from PONYCANYON, who has blocked it in your country on copyright grounds.

What should I do for play video like this?
Thank you.

Error on Run

Got this error and its preventing the bot from running, the method is in there, and without any errors

Exception in thread "main" java.lang.NoSuchMethodError: com.sedmelluq.discord.lavaplayer.tools.ExecutorTools.createEagerlyScalingExecutor(IIJLjava/lang/String;)Ljava/util/concurrent/ExecutorService;
at com.sedmelluq.discord.lavaplayer.player.DefaultAudioPlayerManager.(DefaultAudioPlayerManager.java:91)
at dAndroid.dAndroid2.(dAndroid2.java:335)
at dAndroid.dAndroid2.main(dAndroid2.java:51)

YouTube Playback issue

I'm having trouble playing some YouTube videos like this one:
https://www.youtube.com/watch?v=oTWv63RyLP8

I'm using lavaplayer 1.2.9.

Stacktrace:

com.sedmelluq.discord.lavaplayer.tools.FriendlyException: Unable to play this YouTube track.
    at com.sedmelluq.discord.lavaplayer.source.youtube.YoutubeAudioTrack.loadTrackFormats(YoutubeAudioTrack.java:127)
    at com.sedmelluq.discord.lavaplayer.source.youtube.YoutubeAudioTrack.loadBestFormatWithUrl(YoutubeAudioTrack.java:94)
    at com.sedmelluq.discord.lavaplayer.source.youtube.YoutubeAudioTrack.process(YoutubeAudioTrack.java:60)
    at com.sedmelluq.discord.lavaplayer.track.playback.LocalAudioTrackExecutor.execute(LocalAudioTrackExecutor.java:85)
    at com.sedmelluq.discord.lavaplayer.player.DefaultAudioPlayerManager.lambda$executeTrack$1(DefaultAudioPlayerManager.java:315)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.IllegalStateException: No adaptive formats, no dash.
    ... 8 more

YouTube URLs containing valid punctuation throw an exception

URLs which contain a - (hyphen) or _ (underscore) throw an exception:

com.sedmelluq.discord.lavaplayer.tools.FriendlyException: Not a valid URL.
	at com.sedmelluq.discord.lavaplayer.source.http.HttpAudioSourceManager.detectContainerWithClient(HttpAudioSourceManager.java:106)
	at com.sedmelluq.discord.lavaplayer.source.http.HttpAudioSourceManager.detectContainer(HttpAudioSourceManager.java:83)
	at com.sedmelluq.discord.lavaplayer.source.http.HttpAudioSourceManager.loadItem(HttpAudioSourceManager.java:62)
	at com.sedmelluq.discord.lavaplayer.player.DefaultAudioPlayerManager.checkSourcesForItemOnce(DefaultAudioPlayerManager.java:357)
	at com.sedmelluq.discord.lavaplayer.player.DefaultAudioPlayerManager.checkSourcesForItem(DefaultAudioPlayerManager.java:343)
	at com.sedmelluq.discord.lavaplayer.player.DefaultAudioPlayerManager.lambda$createItemLoader$0(DefaultAudioPlayerManager.java:165)
	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
	at com.sedmelluq.discord.lavaplayer.tools.OrderedExecutor$ChannelRunnable.executeQueue(OrderedExecutor.java:98)
	at com.sedmelluq.discord.lavaplayer.tools.OrderedExecutor$ChannelRunnable.run(OrderedExecutor.java:87)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
	at java.lang.Thread.run(Thread.java:745)
Caused by: java.net.URISyntaxException: Illegal character in query at index 34: https://www.youtube.com/watch?v=ZI\_zlkGN46Y
	at java.net.URI$Parser.fail(URI.java:2848)
	at java.net.URI$Parser.checkChars(URI.java:3021)
	at java.net.URI$Parser.parseHierarchical(URI.java:3111)
	at java.net.URI$Parser.parse(URI.java:3053)
	at java.net.URI.<init>(URI.java:588)
	at com.sedmelluq.discord.lavaplayer.source.http.HttpAudioSourceManager.detectContainerWithClient(HttpAudioSourceManager.java:92)
	... 11 more```

Disable logger

Any way to disable the logger? It's spamming the entire console.

UnsatisfiedLinkError

I'm attempting to use lavaplayer with JDA for a Discord bot and I'm running into the following exception:

java.lang.UnsatisfiedLinkError: /tmp/lava-jni-natives/1489710936108/libconnector.so: /lib64/libm.so.6: version 'GLIBC_2.15' not found (required by /tmp/lava-jni-natives/1489710936108/libconnector.so)

I think it's telling me that the libconnector.so on the server was compiled against the wrong GLIBC version, but I'm walking through the code in the repo and it's not clear to me where it's actually trying to pull libconnector.so from. It seems to expect the server to have its own preexisting copy, I suppose? I guess this is more of a question of how the library actually works than a problem with it.

The server in question is a virtual one that I rent, so I don't have full control over it. I pointed the libconnector.so temp directory to a place I could access and listed its members with readelf and I'm finding lots of version markers for 2.2.5, which tells me something is outdated. If it really is a server problem, let me know so I can bring it up with my host.

No Sound when Bot gets kicked on other Guild (using JDA 3)

I have my test bot connected to two guilds. When i kick it of one guild the player will "stop" playing in the other guild. It is not really stopping the song, but not making any sound, like it was muted. By pausing and unpausing the bot again i can hear sound again. Is there anything i can do against that?
(My lavaplayer and the jda are up-to-date).

Thank you. ๐Ÿ˜ƒ

Cannot compile on linux

[..]
CMake Error at udpqueue/CMakeLists.txt:27 (add_library):
Cannot find source file:

linux/timing.c

[..]

As far as I can see, the directory udpqueue-natives/udpqueue/linux (with timing.c & mutex.c) is missing

InterruptedException when attampting to play audio from soundcloud

Every time I attempt to start playing audio from soundcloud I get this error when calling
AudioFrame frame = this.connection.player.provide();
The line in my code thats throwing the error
The error seems to originate at Line 18 in AudioFrameProviderTools.java, or atleast thats the deepest point printed in the stack trace.

[17:16:39] [DiscLoader/SEVERE]: java.lang.RuntimeException: java.lang.InterruptedException
[17:16:39] [DiscLoader/SEVERE]: at com.sedmelluq.discord.lavaplayer.track.playback.AudioFrameProviderTools.delegateToTimedProvide(AudioFrameProviderTools.java:21)
[17:16:39] [DiscLoader/SEVERE]: at com.sedmelluq.discord.lavaplayer.player.AudioPlayer.provide(AudioPlayer.java:162)
[17:16:39] [DiscLoader/SEVERE]: at io.discloader.discloader.network.voice.StreamProvider.getNextPacket(StreamProvider.java:72)
[17:16:39] [DiscLoader/SEVERE]: at io.discloader.discloader.network.voice.StreamSender$1.run(StreamSender.java:36)
[17:16:39] [DiscLoader/SEVERE]: Caused by: java.lang.InterruptedException
[17:16:39] [DiscLoader/SEVERE]: at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireInterruptibly(Unknown Source)
[17:16:39] [DiscLoader/SEVERE]: at java.util.concurrent.locks.ReentrantLock.lockInterruptibly(Unknown Source)
[17:16:39] [DiscLoader/SEVERE]: at java.util.concurrent.ArrayBlockingQueue.poll(Unknown Source)
[17:16:39] [DiscLoader/SEVERE]: at com.sedmelluq.discord.lavaplayer.track.playback.AudioFrameBuffer.provide(AudioFrameBuffer.java:106)
[17:16:39] [DiscLoader/SEVERE]: at com.sedmelluq.discord.lavaplayer.track.playback.LocalAudioTrackExecutor.provide(LocalAudioTrackExecutor.java:353)
[17:16:39] [DiscLoader/SEVERE]: at com.sedmelluq.discord.lavaplayer.track.BaseAudioTrack.provide(BaseAudioTrack.java:95)
[17:16:39] [DiscLoader/SEVERE]: at com.sedmelluq.discord.lavaplayer.player.AudioPlayer.provideDirectly(AudioPlayer.java:190)
[17:16:39] [DiscLoader/SEVERE]: at com.sedmelluq.discord.lavaplayer.player.AudioPlayer.provide(AudioPlayer.java:167)
[17:16:39] [DiscLoader/SEVERE]: at com.sedmelluq.discord.lavaplayer.track.playback.AudioFrameProviderTools.delegateToTimedProvide(AudioFrameProviderTools.java:18)
[17:16:39] [DiscLoader/SEVERE]: ... 3 more

I'm using version 1.2.27 if that helps.

"Unknown file format" Error when loading Nicovideo

Hi. An error has been occurred when loading audio from Nicovideo (www.nicovideo.jp).

com.sedmelluq.discord.lavaplayer.tools.FriendlyException: Unknown file format. at com.sedmelluq.discord.lavaplayer.source.ProbingAudioSourceManager.handleLoadResult(ProbingAudioSourceManager.java:21) at com.sedmelluq.discord.lavaplayer.source.http.HttpAudioSourceManager.loadItem(HttpAudioSourceManager.java:65) at com.sedmelluq.discord.lavaplayer.player.DefaultAudioPlayerManager.checkSourcesForItemOnce(DefaultAudioPlayerManager.java:429) at com.sedmelluq.discord.lavaplayer.player.DefaultAudioPlayerManager.checkSourcesForItem(DefaultAudioPlayerManager.java:415) at com.sedmelluq.discord.lavaplayer.player.DefaultAudioPlayerManager.lambda$createItemLoader$0(DefaultAudioPlayerManager.java:219) at java.util.concurrent.FutureTask.run(FutureTask.java:266) at com.sedmelluq.discord.lavaplayer.tools.OrderedExecutor$ChannelRunnable.executeQueue(OrderedExecutor.java:98) at com.sedmelluq.discord.lavaplayer.tools.OrderedExecutor$ChannelRunnable.run(OrderedExecutor.java:87) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at java.lang.Thread.run(Thread.java:745)

Youtube Video Starting at Certain Time

It would be nice to have an option in the YoutubeAudioSourceManager to be able to player a youtube video from a certain time. Maybe something like loadTrackWithVideoId(String videoId, int seconds, boolean mustExist);?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.