|
2 | 2 |
|
3 | 3 | ## Installation
|
4 | 4 |
|
5 |
| -1. Download Java if you don't have it |
| 5 | +Download ext via `pip install --upgrade interactions-lavalink` |
| 6 | + |
| 7 | +## Configuring own lavalink server |
| 8 | + |
| 9 | +1. Download Java SE if you don't have it |
6 | 10 | 2. Download lavalink from [this repo](https://github.com/freyacodes/Lavalink)
|
7 | 11 | 3. Configure `application.yml` file like [here](https://github.com/freyacodes/Lavalink/blob/master/LavalinkServer/application.yml.example)
|
8 |
| -4. Download ext via `pip install interactions-lavalink` |
| 12 | +4. Run lavalink server via `java -jar Lavalink.jar` in same folder with `application.yml` file. |
9 | 13 |
|
10 | 14 | ## Usage
|
11 | 15 |
|
12 |
| -Run lavalink via `java -jar Lavalink.jar` in same folder with `application.yml` file. |
13 | 16 | Create bot like example and run it.
|
14 | 17 |
|
15 | 18 | Main file:
|
16 | 19 | ```python
|
17 |
| -import interactions |
18 |
| -from interactions.ext.lavalink import VoiceState, VoiceClient |
| 20 | +from interactions import Client |
| 21 | + |
19 | 22 |
|
20 |
| -client = VoiceClient(...) |
| 23 | +# Creating bot variable |
| 24 | +client = Client(...) |
21 | 25 |
|
| 26 | +# Loading your extension |
22 | 27 | client.load("exts.music")
|
23 | 28 |
|
| 29 | +# Starting bot |
24 | 30 | client.start()
|
25 | 31 | ```
|
26 | 32 |
|
27 | 33 | Extension file: `exts/music.py`
|
28 | 34 | ```python
|
29 |
| -import interactions |
30 |
| -from interactions.ext.lavalink import VoiceClient, VoiceState, listener, Player |
31 |
| -import lavalink |
| 35 | +from interactions import Extension, extension_command, extension_listener, option, CommandContext, VoiceState |
| 36 | +from interactions.ext.lavalink import Lavalink |
32 | 37 |
|
33 | 38 |
|
34 |
| -class Music(interactions.Extension): |
| 39 | +class Music(Extension): |
35 | 40 | def __init__(self, client):
|
36 |
| - self.client: VoiceClient = client |
| 41 | + self.client = client |
| 42 | + self.lavalink: Lavalink = None |
37 | 43 |
|
38 |
| - @listener() |
39 |
| - async def on_track_start(self, event: lavalink.TrackStartEvent): |
40 |
| - """ |
41 |
| - Fires when track starts |
42 |
| - """ |
43 |
| - print("STARTED", event.track) |
44 |
| - |
45 |
| - @interactions.extension_listener() |
| 44 | + @extension_listener() |
46 | 45 | async def on_start(self):
|
47 |
| - self.client.lavalink_client.add_node("127.0.0.1", 43421, "your_password", "eu") |
48 |
| - |
49 |
| - @interactions.extension_listener() |
50 |
| - async def on_voice_state_update(self, before: VoiceState, after: VoiceState): |
51 |
| - """ |
52 |
| - Disconnect if bot is alone |
53 |
| - """ |
54 |
| - if before and not after.joined: |
55 |
| - voice_states = self.client.get_channel_voice_states(before.channel_id) |
56 |
| - if len(voice_states) == 1 and voice_states[0].user_id == self.client.me.id: |
57 |
| - await self.client.disconnect(before.guild_id) |
58 |
| - |
59 |
| - @interactions.extension_command() |
60 |
| - @interactions.option() |
61 |
| - async def play(self, ctx: interactions.CommandContext, query: str): |
| 46 | + # Initialize lavalink instance |
| 47 | + self.lavalink: Lavalink = Lavalink(self.client) |
| 48 | + |
| 49 | + # Connect to lavalink server |
| 50 | + self.lavalink.add_node("127.0.0.1", 43421, "your_password", "eu") |
| 51 | + |
| 52 | + @extension_command() |
| 53 | + @option() |
| 54 | + async def play(self, ctx: CommandContext, query: str): |
62 | 55 | await ctx.defer()
|
63 | 56 |
|
64 |
| - # NOTE: ctx.author.voice can be None if you ran a bot after joining the voice channel |
65 |
| - voice: VoiceState = ctx.author.voice |
66 |
| - if not voice or not voice.joined: |
| 57 | + # Getting user's voice state |
| 58 | + voice_state: VoiceState = ctx.author.voice_state |
| 59 | + if not voice_state or not voice_state.joined: |
67 | 60 | return await ctx.send("You're not connected to the voice channel!")
|
68 | 61 |
|
69 |
| - player: Player # Typehint player variable to see their methods |
70 |
| - if (player := ctx.guild.player) is None: |
71 |
| - player = await voice.connect() |
| 62 | + # Connecting to voice channel and getting player instance |
| 63 | + player = await self.lavalink.connect(voice_state.guild_id, voice_state.channel_id) |
72 | 64 |
|
| 65 | + # Getting tracks from youtube |
73 | 66 | tracks = await player.search_youtube(query)
|
| 67 | + # Selecting first founded track |
74 | 68 | track = tracks[0]
|
| 69 | + # Adding track to the queue |
75 | 70 | player.add(requester=int(ctx.author.id), track=track)
|
76 | 71 |
|
| 72 | + # Check if already playing |
77 | 73 | if player.is_playing:
|
78 | 74 | return await ctx.send(f"Added to queue: `{track.title}`")
|
| 75 | + |
| 76 | + # Starting playing track |
79 | 77 | await player.play()
|
80 | 78 | await ctx.send(f"Now playing: `{track.title}`")
|
81 | 79 |
|
82 |
| - @interactions.extension_command() |
83 |
| - async def leave(self, ctx: interactions.CommandContext): |
84 |
| - await self.client.disconnect(ctx.guild_id) |
| 80 | + @extension_command() |
| 81 | + async def leave(self, ctx: CommandContext): |
| 82 | + # Disconnect from voice channel and remove player |
| 83 | + await self.lavalink.disconnect(ctx.guild_id) |
| 84 | + |
| 85 | + await ctx.send("Disconnected", ephemeral=True) |
| 86 | + |
| 87 | + |
| 88 | +def setup(client): |
| 89 | + Music(client) |
| 90 | + |
85 | 91 | ```
|
86 | 92 |
|
87 | 93 | ## Events
|
88 |
| -To listen lavalink event you have to use `@listener` decorator. |
| 94 | +To listen lavalink event you have to use either `@bot.event` or `@extension_listener` decorator. |
89 | 95 |
|
90 | 96 | ```python
|
91 |
| -import lavalink |
92 |
| -from interactions.ext.lavalink import listener |
| 97 | +from interactions import Extension, extension_listener |
93 | 98 |
|
| 99 | +import lavalink |
94 | 100 |
|
95 |
| -# NOTE: Works only in extensions. |
96 | 101 | class MusicExt(Extension):
|
97 |
| - ... |
| 102 | + ... # Some your cool music commands |
98 | 103 |
|
99 |
| - # There are most useful events for you. You can use other events if you want it. |
100 |
| - @listener() |
| 104 | + # There are many useful events for you. You can use other events if you want it. |
| 105 | + @extension_listener() |
101 | 106 | async def on_track_start(self, event: lavalink.TrackStartEvent):
|
102 | 107 | """Fires when track starts"""
|
103 | 108 |
|
104 |
| - @listener() |
| 109 | + @extension_listener() |
105 | 110 | async def on_track_end(self, event: lavalink.TrackEndEvent):
|
106 | 111 | """Fires when track ends"""
|
107 | 112 |
|
108 |
| - @listener() |
| 113 | + @extension_listener() |
109 | 114 | async def on_queue_end(self, event: lavalink.QueueEndEvent):
|
110 | 115 | """Fires when queue ends"""
|
111 | 116 |
|
112 | 117 | ```
|
113 | 118 |
|
114 |
| -## New methods/properties for interactions.py library |
115 |
| - |
116 |
| -`Member.voice` - returns current member's `VoiceState`. It can be `None` if not cached. |
117 |
| -`Channel.voice_states` - returns a list of voice states of the voice channel. Can be empty if not cached. |
118 |
| -`Guild.voice_states` - returns a list of guild voice states. Can be empty if not cached. |
| 119 | +More events you could find in the `lavalink.py` documentation |
119 | 120 |
|
120 | 121 | ## Documentation
|
121 | 122 |
|
122 |
| -[lavalink.py documentation](https://lavalink.readthedocs.io/en/master/) |
| 123 | +[lavalink.py documentation](https://lavalink.readthedocs.io/en/master/) \ |
123 | 124 | [lavalink.py repository](https://github.com/Devoxin/Lavalink.py)
|
124 |
| - |
125 |
| -## Credits |
126 |
| - |
127 |
| -Thanks EdVraz for `VoiceState` from [voice ext](https://github.com/interactions-py/voice) |
0 commit comments