diff options
Diffstat (limited to 'lib/audio/util.ex')
| -rw-r--r-- | lib/audio/util.ex | 114 |
1 files changed, 114 insertions, 0 deletions
diff --git a/lib/audio/util.ex b/lib/audio/util.ex new file mode 100644 index 0000000..f45af4e --- /dev/null +++ b/lib/audio/util.ex @@ -0,0 +1,114 @@ +defmodule Thulani.Audio.Util do + @spec stream_type(Nostrum.Voice.play_input()) :: + {:ok, Nostrum.Voice.play_type()} | {:error, atom()} + + def stream_type(ref) when is_binary(ref) do + cond do + ytdl_link?(ref) -> {:ok, :ytdl} + streamlink?(ref) -> {:ok, :stream} + valid_url?(ref) -> {:ok, :url} + true -> {:ok, :pipe} + end + end + + def stream_type(_ref) do + {:error, :invalid} + end + + @spec ytdl_link?(String.t()) :: boolean + def ytdl_link?(s) when is_binary(s) do + valid_url?(s) and + ytdl_checks() + |> any_check?(s) + end + + def ytdl_link?(_s), do: false + + @spec streamlink?(String.t()) :: boolean + def streamlink?(s) when is_binary(s) do + valid_url?(s) and streamlink_checks() |> any_check?(s) + end + + def streamlink?(_s), do: false + + def valid_url?(s), do: String.match?(s, ~r/^https:\/\/.*/i) + + def ytdl_checks, do: [&youtube_link?/1, &vimeo_link?/1] + def streamlink_checks, do: [&twitch_link?/1] + + def youtube_link?(s), + do: String.match?(s, youtube_regex()) + + def vimeo_link?(s), + do: String.match?(s, vimeo_regex()) + + def twitch_link?(s), + do: String.match?(s, twitch_regex()) + + def youtube_regex, do: ~r/^https?:\/\/(?:www\.)?(?:youtube\.com|youtu\.be)\/.*/i + def vimeo_regex, do: ~r/^https?:\/\/(?:www\.)?(?:vimeo\.com)\/.*/i + def twitch_regex, do: ~r/^https?:\/\/(?:www\.)?(?:twitch\.com)\/.*/i + + defp any_check?(checks, s) do + checks + |> Stream.map(fn check -> check.(s) end) + |> Enum.reduce(false, fn acc, x -> acc or x end) + end + + def wait_ready(guild, interval \\ 100, count \\ 10) do + wait_for(guild, interval, count, &Nostrum.Voice.ready?/1) + end + + def wait_playing(guild, interval \\ 200, count \\ 30) do + wait_for(guild, interval, count, &Nostrum.Voice.playing?/1) + end + + def wait_no_channel(guild, interval \\ 200, count \\ 30) do + wait_for(guild, interval, count, fn guild -> no_channel?(guild) end) + end + + def wait_disconnected(guild, interval \\ 200, count \\ 30) do + wait_for(guild, interval, count, fn guild -> disconnected?(guild) end) + end + + defp wait_for(guild, interval, count, check) do + unless check.(guild) do + [playing] = + Stream.unfold(0, fn i -> + Process.sleep(interval) + playing_state = check.(guild) + {playing_state, i + 1} + end) + |> Thulani.Util.Stream.take_until(&Function.identity/1) + |> Stream.take(count) + |> Enum.take(-1) + + playing + else + true + end + end + + def connected?(guild) do + voice_state = Nostrum.Voice.get_voice(guild) + !is_nil(voice_state) && !is_nil(voice_state.channel_id) + end + + def disconnect(guild) do + voice_state = Nostrum.Voice.get_voice(guild) + Nostrum.Voice.leave_channel(guild) + + if not is_nil(voice_state) do + Nostrum.Voice.Session.close_connection(voice_state.session_pid) + end + end + + def disconnected?(guild) do + Nostrum.Voice.get_voice(guild) |> is_nil + end + + def no_channel?(guild) do + voice_state = Nostrum.Voice.get_voice(guild) + !is_nil(voice_state) && is_nil(voice_state.channel_id) + end +end |
