mirror of
https://codeberg.org/godmaire/sergei.git
synced 2024-09-20 00:08:25 +00:00
feat: Add basic queueing functionality
This commit is contained in:
parent
8dd1283b62
commit
228a3df244
2 changed files with 65 additions and 6 deletions
|
@ -14,9 +14,14 @@ defmodule Sergei.Consumer do
|
||||||
opt.(3, "url", "URL of the audio to play", [])
|
opt.(3, "url", "URL of the audio to play", [])
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@queue_opts [
|
||||||
|
opt.(3, "url", "URL of the audio to queue", required: true)
|
||||||
|
]
|
||||||
|
|
||||||
@slash_commands [
|
@slash_commands [
|
||||||
{"ping", "Pong", []},
|
{"ping", "Pong", []},
|
||||||
{"play", "Play a song or resume playback", @play_opts},
|
{"play", "Play a song or resume playback", @play_opts},
|
||||||
|
{"queue", "Queue a song to play next", @queue_opts},
|
||||||
{"pause", "Pause media playback", []},
|
{"pause", "Pause media playback", []},
|
||||||
{"stop", "Stop media playback and leave the voice channel", []},
|
{"stop", "Stop media playback and leave the voice channel", []},
|
||||||
{"song", "What song is currently playing?", []}
|
{"song", "What song is currently playing?", []}
|
||||||
|
@ -127,6 +132,24 @@ defmodule Sergei.Consumer do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# /queue <url>
|
||||||
|
def do_command(%{
|
||||||
|
guild_id: guild_id,
|
||||||
|
data: %{name: "queue", options: [%{name: "url", value: url}]}
|
||||||
|
}) do
|
||||||
|
case Sergei.Player.queue(guild_id, url) do
|
||||||
|
:ok ->
|
||||||
|
{:ok, "Song queued."}
|
||||||
|
|
||||||
|
:not_playing ->
|
||||||
|
{:ok, "I'm not playing anything right now."}
|
||||||
|
|
||||||
|
{:error, err} ->
|
||||||
|
Logger.error("Failed to queue media: #{err}")
|
||||||
|
{:error, "This is embarassing..."}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
# /pause
|
# /pause
|
||||||
def do_command(%{guild_id: guild_id, data: %{name: "pause"}}) do
|
def do_command(%{guild_id: guild_id, data: %{name: "pause"}}) do
|
||||||
case Sergei.Player.pause(guild_id) do
|
case Sergei.Player.pause(guild_id) do
|
||||||
|
|
|
@ -24,6 +24,11 @@ defmodule Sergei.Player do
|
||||||
GenServer.call(__MODULE__, {:play, guild_id, channel_id, url})
|
GenServer.call(__MODULE__, {:play, guild_id, channel_id, url})
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@spec queue(integer(), String.t()) :: :ok | :not_playing | {:error, String.t()}
|
||||||
|
def queue(guild_id, url) do
|
||||||
|
GenServer.call(__MODULE__, {:queue, guild_id, url})
|
||||||
|
end
|
||||||
|
|
||||||
@spec pause(integer()) :: :ok | :not_playing | {:error, String.t()}
|
@spec pause(integer()) :: :ok | :not_playing | {:error, String.t()}
|
||||||
def pause(guild_id) do
|
def pause(guild_id) do
|
||||||
GenServer.call(__MODULE__, {:pause, guild_id})
|
GenServer.call(__MODULE__, {:pause, guild_id})
|
||||||
|
@ -50,8 +55,21 @@ defmodule Sergei.Player do
|
||||||
state
|
state
|
||||||
|> Enum.filter(fn {_id, %{paused: paused} = _state} -> not paused end)
|
|> Enum.filter(fn {_id, %{paused: paused} = _state} -> not paused end)
|
||||||
|> Enum.filter(fn {guild_id, _data} -> not Voice.playing?(guild_id) end)
|
|> Enum.filter(fn {guild_id, _data} -> not Voice.playing?(guild_id) end)
|
||||||
|> Enum.each(fn {guild_id, %{url: url}} = _state ->
|
|> Enum.map(fn {guild_id, %{queue: queue} = state} ->
|
||||||
|
state =
|
||||||
|
case :queue.out(queue) do
|
||||||
|
{{:value, url}, queue} ->
|
||||||
|
%{state | url: url, queue: queue}
|
||||||
|
|
||||||
|
{:empty, _} ->
|
||||||
|
state
|
||||||
|
end
|
||||||
|
|
||||||
|
{guild_id, state}
|
||||||
|
end)
|
||||||
|
|> Enum.map(fn {guild_id, %{url: url}} = state ->
|
||||||
Voice.play(guild_id, url, :ytdl)
|
Voice.play(guild_id, url, :ytdl)
|
||||||
|
state
|
||||||
end)
|
end)
|
||||||
|
|
||||||
Process.send_after(self(), :check_repeat, @check_repeat_interval)
|
Process.send_after(self(), :check_repeat, @check_repeat_interval)
|
||||||
|
@ -100,12 +118,28 @@ defmodule Sergei.Player do
|
||||||
state =
|
state =
|
||||||
Map.put(state, guild_id, %{
|
Map.put(state, guild_id, %{
|
||||||
url: url,
|
url: url,
|
||||||
paused: false
|
paused: false,
|
||||||
|
queue: :queue.new()
|
||||||
})
|
})
|
||||||
|
|
||||||
{:reply, res, state}
|
{:reply, res, state}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@impl true
|
||||||
|
def handle_call({:queue, guild_id, url}, _from, state) do
|
||||||
|
%{queue: queue} = instance = Map.fetch!(state, guild_id)
|
||||||
|
|
||||||
|
{
|
||||||
|
:reply,
|
||||||
|
:ok,
|
||||||
|
Map.put(
|
||||||
|
state,
|
||||||
|
guild_id,
|
||||||
|
%{instance | queue: :queue.in(url, queue)}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
def handle_call({_, guild_id}, _from, state) when not is_map_key(state, guild_id) do
|
def handle_call({_, guild_id}, _from, state) when not is_map_key(state, guild_id) do
|
||||||
{:reply, :not_playing, state}
|
{:reply, :not_playing, state}
|
||||||
|
@ -113,13 +147,14 @@ defmodule Sergei.Player do
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
def handle_call({:pause, guild_id}, _from, state) do
|
def handle_call({:pause, guild_id}, _from, state) do
|
||||||
%{url: url} = Map.fetch!(state, guild_id)
|
%{url: url, queue: queue} = Map.fetch!(state, guild_id)
|
||||||
Voice.pause(guild_id)
|
Voice.pause(guild_id)
|
||||||
|
|
||||||
state =
|
state =
|
||||||
Map.put(state, guild_id, %{
|
Map.put(state, guild_id, %{
|
||||||
url: url,
|
url: url,
|
||||||
paused: true
|
paused: true,
|
||||||
|
queue: queue
|
||||||
})
|
})
|
||||||
|
|
||||||
{:reply, :ok, state}
|
{:reply, :ok, state}
|
||||||
|
@ -127,13 +162,14 @@ defmodule Sergei.Player do
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
def handle_call({:resume, guild_id}, _from, state) do
|
def handle_call({:resume, guild_id}, _from, state) do
|
||||||
%{url: url} = Map.fetch!(state, guild_id)
|
%{url: url, queue: queue} = Map.fetch!(state, guild_id)
|
||||||
Voice.resume(guild_id)
|
Voice.resume(guild_id)
|
||||||
|
|
||||||
state =
|
state =
|
||||||
Map.put(state, guild_id, %{
|
Map.put(state, guild_id, %{
|
||||||
url: url,
|
url: url,
|
||||||
paused: false
|
paused: false,
|
||||||
|
queue: queue
|
||||||
})
|
})
|
||||||
|
|
||||||
{:reply, :ok, state}
|
{:reply, :ok, state}
|
||||||
|
|
Loading…
Reference in a new issue