Git Product home page Git Product logo

eris-lavalink's Introduction

eris-lavalink

A Lavalink client for eris

Links

Install

# Lavalink v2
npm install eris-lavalink

# Lavalink v1
npm install eris-lavalink@^0.1.3

Implementation

Start by creating the PlayerManager and passing a list of nodes and optional list of regions

const { PlayerManager } = require('eris-lavalink');

let nodes = [
	{ host: 'localhost', port: 8080, region: 'eu', password: 'youshallnotpass' }
];

let regions = {
	eu: ['eu', 'amsterdam', 'frankfurt', 'russia', 'hongkong', 'singapore', 'sydney'],
	us: ['us', 'brazil'],
};

if (!(client.voiceConnections instanceof PlayerManager)) {
	client.voiceConnections = new PlayerManager(client, nodes, {
		numShards: shardCount, // number of shards
		userId: userid, // the user id of the bot
		regions: regions,
		defaultRegion: 'eu',
	});
}

To resolve a track, use the Lavalink rest api

const superagent = require('superagent');

async function resolveTracks(node, search) {
	try {
		var result = await superagent.get(`http://${node.host}:2333/loadtracks?identifier=${search}`)
			.set('Authorization', node.password)
			.set('Accept', 'application/json');
	} catch (err) {
		throw err;
	}

	if (!result) {
		throw 'Unable play that video.';
	}

	return result.body; // array of tracks resolved from lavalink
}

resolveTracks(node, 'ytsearch:the 30 second video').then(tracks => {
	if (!tracks) {
		// no tracks to play
	}
	// do something with the tracks
})

To join and leave voice channels, use the Lavalink client rather than using eris.

// to get or join a channel
function getPlayer(channel) {
	if (!channel || !channel.guild) {
		return Promise.reject('Not a guild channel.');
	}

	let player = client.voiceConnections.get(channel.guild.id);
	if (player) {
		return Promise.resolve(player);
	}

	let options = {};
	if (channel.guild.region) {
		options.region = channel.guild.region;
	}

	return client.joinVoiceChannel(channel.id, options);
}

// play example
getPlayer(channel).then(player => {
	player.play(track); // track is the base64 track we get from Lavalink

	player.on('disconnect', (err) => {
		if (err) {
			// log error
		}
		// do something
	});

	player.on('error', err => {
		// log error and handle it
	});

	player.on('stuck', msg => {
		// track stuck event
	})

	player.once('end', data => {
		// REPLACED reason is emitted when playing without stopping, I ignore these to prevent skip loops
		if (data.reason && data.reason === 'REPLACED') {
			return;
		}

		// start playing the next song
	});
});

// stop example
getPlayer(channel).then(player => {
	player.stop();
	if (leave) {
		// disconnect and leave the channel
		client.leaveVoiceChannel(channel.id);
	}
})

A note on pauses

When you pause a player, the player will be kept in a paused state until you explicitly call resume or the player is disconnected. Calls to play and stop won't clear the pause state. player.paused can be used to check if the player is in paused state.

eris-lavalink's People

Contributors

anothergenz avatar briantanner avatar germanoeich avatar inatrance avatar itslukej avatar j3ns3n avatar thewsomeguy 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

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

eris-lavalink's Issues

License?

What license is this project licensed under?
I would want to use snippets of the code in my library.

Socket hang up from host.

I will go to get the lavalink client running but when I have it trying to connect to my host (which is just a a express http server) it gives me socket hang up when the host responds just fine. This is the code for the host.

'use strict';

const express = require('express');
const app = express();
module.exports = (client) => {
  app.get('/', (req, res) => res.send('Hello world!');

  app.listen(8080, () => console.log(`Listening on port 8080`));
};

end event weirdness

So for a while, my skip command would just end the current track by using .stop() on the player, causing the end event to fire wher I had code to play the next track. At some point I thought:

shouldn't I just .play() with a new track?

I can. But, this causes issues that I can't seem to figure out.

So there are 2 scenarios:

  1. (my old way of skipping or going to the next song for any reason)
  • play() a track - it plays.
  • end event works, inside the event i have code to go to the next song
  • if somebody skips, I just stop() the player, and the end event fires, again playing the next song
  1. (new way where I "replace" tracks)
  • play() a track - it plays.
  • end event works, inside the event i have code to go to the next song
  • if somebody skips, instead of stopping the player, which forces the end event to fire, I just play() the next track.
  • The track will play, BUT the end event will not fire for this track.

Also strange:
in the second scenario, the first and only the first track that i .play() while another is playing (rather than stopping to force the end event) will cause the end event to fire twice (yes, it is .once()). 2 identical data with "REPLACED" reason.
Calling play() while a song is playing subsequent times, the end event will fire with the "REPLACED" reason once as expected, however the "FINISHED" end event will never fire for any of these.


Edit: I think I figured out why this happens:
When playing the next track, the player starts and registers all the listeners (which are .once) before the end event with reason "REPLACED" occurs. Therefore, when the "REPLACED" event fires, both the .once listener stops listening to the end of the track and never sees the "FINISHED" event.

My sketchy solution (for now) was to make it a .on and remove all listeners imemdiately before doing .play(), then re-registering them afterwards as normal. This prevents the situation above.

TypeError: Cannot read property 'channels' of undefined

TypeError: Cannot read property 'channels' of undefined
  File "/home/dbots/oxyl/node_modules/eris/lib/Client.js", line 337, col 98, in Client.getChannel
    {snip} annelID] ? this.guilds.get(this.channelGuildMap[channelID]).channels.get(channelID) : this.privateChannels.get(channelID) || this.groupChann {snip}
  File "/home/dbots/oxyl/node_modules/eris-lavalink/src/PlayerManager.js", line 229, col 52, in Map.onMessage
    let voiceChannel = this.client.getChannel(message.channelId);
  File "events.js", line 115, col 13, in emitOne
  File "events.js", line 210, col 7, in Lavalink.emit
  File "/home/dbots/oxyl/node_modules/eris-lavalink/src/Lavalink.js", line 166, col 8, in Lavalink.onMessage
    this.emit('message', data);
  File "events.js", line 115, col 13, in emitOne
  File "events.js", line 210, col 7, in WebSocket.emit
  File "/home/dbots/oxyl/node_modules/ws/lib/WebSocket.js", line 143, col 47, in Receiver._receiver.onmessage
    this._receiver.onmessage = (data) => this.emit('message', data);
  File "/home/dbots/oxyl/node_modules/ws/lib/Receiver.js", line 389, col 14, in Receiver.dataMessage
    this.onmessage(buf.toString());
  File "/home/dbots/oxyl/node_modules/ws/lib/Receiver.js", line 330, col 12, in Receiver.getData
    this.dataMessage();
  File "/home/dbots/oxyl/node_modules/ws/lib/Receiver.js", line 165, col 16, in Receiver.startLoop
    this.getData();
  File "/home/dbots/oxyl/node_modules/ws/lib/Receiver.js", line 139, col 10, in Receiver.add
    this.startLoop();
  File "/home/dbots/oxyl/node_modules/ws/lib/WebSocket.js", line 139, col 22, in Socket._ultron.on
    this._receiver.add(data);
  File "events.js", line 115, col 13, in emitOne
  File "events.js", line 210, col 7, in Socket.emit
  File "_stream_readable.js", line 266, col 12, in addChunk
  File "_stream_readable.js", line 253, col 11, in readableAddChunk
  File "_stream_readable.js", line 211, col 10, in Socket.Readable.push
  File "net.js", line 585, col 20, in TCP.onread

[Question]: Is there any playlist commands?

I see in LavaLink jar file a reference to playlist but I see nothing about playlist in Eris-Lavalink. Is there an undocumented feature or Eris-Lavalink or does Eris-Lavalink not support any of Lavalinks playlist features?

player.setPause() does nothing

Hello. I just recently started using Lavalink, and I love it! I believe it's a great audio library, and it greatly decreased CPU usage. The only problem I have is when I try to use player.setPause(), it does nothing. No logs or errors, nothing. Here's my code: https://h.mayo.pw/ugogibamuv.js. I don't know what causes this, but it never works. Any help?

Note: This isn't my production code, I'm just messing around with Lavalink at the moment.

EventEmitter leak?

implementing the use of this into a bot, after extended usage of the bot playing on one guild i was presented with the following on the console down below, the bot has kept on playing and those events now have upwards of 80 listeners registered. is this a bug with the lib or my code?

(node:36915) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 disconnect listeners added. Use emitter.setMaxListeners() to increase limit
(node:36915) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 error listeners added. Use emitter.setMaxListeners() to increase limit
(node:36915) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 stuck listeners added. Use emitter.setMaxListeners() to increase limit

Voice Timeout set twice

For some reason (probaly due to my own code), playermanager's join function seems to be called twice, and the settimeout return value is being overwritten and as a result only the second one is being cancelled.
image
My modifacations
image
image
only console.log was added
I'll be posting reproduction code in a few hours

Voice connection timeout

Error: Voice connection timeout
     at Timeout.pendingGuilds.(anonymous function).timeout.setTimeout [as _onTimeout] (/home/jake/discord/Adonis/node_modules/eris-lavalink/src/PlayerManager.js:323:25)
     at ontimeout (timers.js:469:11)
     at tryOnTimeout (timers.js:304:5)
     at Timer.listOnTimeout (timers.js:264:5)

Error when running multiple player.play() after each other

I am trying to run a music bot, and it works great for only one song. When I try to use player.play(track) after the previous song ended, it emits end earlier than expected. Let's say I make the bot play a song, then queue another song after that. It finishes the first song, then goes onto the second song. Halfway through the second song, the player suddenly emits end even though the audio wasn't finished playing. Here is a picture of what console looks like when I let the song finish, and close up, then I play another song and let it rejoin:
image
This is what console looks like when I try to queue multiple songs after each other:
image
As you can see, it emits end twice before it even lets the second song end and the third song start. The reason it emits the error is because it called end before it let the other songs play, caused on my end of this. Here's my code: https://h.mayo.pw/exasojulos.js. I hope this helps, thanks!

Error: unexpected server response (404)

I ran my bot, and then it gave me this error:
events.js:167
throw er; // Unhandled 'error' event
^

Error: unexpected server response (404)
at ClientRequest._req.on (/root/TrinityAlpha/node_modules/ws/lib/WebSocket.j s:653:21)
at ClientRequest.emit (events.js:182:13)
at HTTPParser.parserOnIncomingClient [as onIncoming] (_http_client.js:538:21 )
at HTTPParser.parserOnHeadersComplete (_http_common.js:109:17)
at Socket.socketOnData (_http_client.js:425:20)
at Socket.emit (events.js:182:13)
at addChunk (_stream_readable.js:277:12)
at readableAddChunk (_stream_readable.js:262:11)
at Socket.Readable.push (_stream_readable.js:217:10)
at TCP.onread (net.js:638:20)
Emitted 'error' event at:
at Map.onError (/root/TrinityAlpha/node_modules/eris-lavalink/src/PlayerMana ger.js:142:21)
at Lavalink.emit (events.js:182:13)
at WebSocket.ws.on (/root/TrinityAlpha/node_modules/eris-lavalink/src/Lavali nk.js:77:9)
at WebSocket.emit (events.js:182:13)
at WebSocket.finalize (/root/TrinityAlpha/node_modules/ws/lib/WebSocket.js:1 82:41)
at ClientRequest._req.on (/root/TrinityAlpha/node_modules/ws/lib/WebSocket.j s:653:12)
at ClientRequest.emit (events.js:182:13)
[... lines matching original stack trace ...]
at TCP.onread (net.js:638:20)

TypeError: fn is not a function

Not quite sure how to solve this.

TypeError: fn is not a function
    at Map.processQueue (/Users/air/Documents/Adonis/node_modules/eris-lavalink/src/PlayerManager.js:125:9)
    at Map.queueFailover (/Users/air/Documents/Adonis/node_modules/eris-lavalink/src/PlayerManager.js:115:25)
    at Map.shardReady (/Users/air/Documents/Adonis/node_modules/eris-lavalink/src/PlayerManager.js:160:18)
    at emitOne (events.js:120:20)
    at Object.emit (events.js:210:7)
    at Function.shard.on (/Users/air/Documents/Adonis/node_modules/eris/lib/gateway/ShardManager.js:56:29)
    at new Func (/Users/air/Documents/Adonis/node_modules/rethinkdbdash/lib/term.js:3053:19)
    at Function.Term.expr (/Users/air/Documents/Adonis/node_modules/rethinkdbdash/lib/term.js:2339:12)
    at /Users/air/Documents/Adonis/node_modules/rethinkdbdash/lib/term.js:2364:40
    at Object.loopKeys (/Users/air/Documents/Adonis/node_modules/rethinkdbdash/lib/helper.js:56:14)
    at Function.Term.expr (/Users/air/Documents/Adonis/node_modules/rethinkdbdash/lib/term.js:2362:12)
    at /Users/air/Documents/Adonis/node_modules/rethinkdbdash/lib/term.js:2364:40
    at Object.loopKeys (/Users/air/Documents/Adonis/node_modules/rethinkdbdash/lib/helper.js:56:14)
    at Function.Term.expr (/Users/air/Documents/Adonis/node_modules/rethinkdbdash/lib/term.js:2362:12)
    at /Users/air/Documents/Adonis/node_modules/rethinkdbdash/lib/term.js:2364:40
    at Object.loopKeys (/Users/air/Documents/Adonis/node_modules/rethinkdbdash/lib/helper.js:56:14)

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.