Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,10 @@ DJ_ROLE=123456789987654321
# PLEX MEDIA SERVER SETTINGS
ENABLE_PLEX=false
PLEX_SERVER='http://YOUR_IPADDRESS:32400'
PLEX_AUTHTOKEN='YOUR_AUTH_TOKEN'
PLEX_AUTHTOKEN='YOUR_AUTH_TOKEN'

# SUBSONIC MEDIA SERVER SETTINGS
ENABLE_SUBSONIC=false
SUBSONIC_URL=http://YOUR_IPADDRESS:4533
SUBSONIC_USERNAME=YOUR_USERNAME
SUBSONIC_PASSWORD=YOUR_PASSWORD
38 changes: 28 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ The first step is to clone the repository or download it manually as a folder to
Head over to the download page and download the .zip source code. Next, using a tool such as [7-Zip](https://www.7-zip.org/), extract the files from the .zip folder. You can now move on to the following steps.

#### Download using Git
An alternative way to download the repository is through the usage of [Git](https://git-scm.com/). If you do not have Git installed, please use the basic download method. Git users can run the command `git clone https://github.com/ThatGuyJacobee/Elite-Bot-Music/tree/main` to automatically clone the repository to a new folder.
An alternative way to download the repository is through the usage of [Git](https://git-scm.com/). If you do not have Git installed, please use the basic download method. Git users can run the command `gh repo clone ripsawuk/Elite-Music` to automatically clone the repository to a new folder.

#### Continuing the Setup
Now that you have downloaded the repository, you can continue with the following steps.
Expand Down Expand Up @@ -74,29 +74,29 @@ Elite Music now has Docker image and Docker Compose support, allowing you to sim
You can access the [Docker Image via Docker Hub](https://hub.docker.com/r/thatguyjacobee/elitemusic) which provides the image and the instructions within the description. The instructions to either install via Docker Run or Docker Compose are also provided below. Once you have installed and configured your bot, you will need to add your bot to your server now in order to use it. Follow this [useful guide](https://discordjs.guide/preparations/adding-your-bot-to-servers.html#bot-invite-links) from the discord.js Guide which explains how to do this with great detail if you need help understanding how to do this.

#### Docker Run Command
You should use the following command to download the image and run it:
Use the current image and container naming from our compose file:
```docker
docker run -d \
--name=elite-music \
--env-file /path/to/.env \
--name=elite-subsonic \
--env-file .env \
--restart unless-stopped \
thatguyjacobee/elitemusic:latest
ripsawuk/elitemusic:latest
```

Note: The `--env-file` path is relative to the directory you are running your docker run command from.

See the [.env.sample file](https://github.com/ThatGuyJacobee/Elite-Music/blob/main/.env.example) on the GitHub repository to view and copy over all of the environmental options into your target .env file for the bot.
See the [.env.sample file](https://github.com/ripsawuk/Elite-Music/blob/main/.env.example) on the GitHub repository to view and copy over all of the environmental options into your target .env file for the bot.

#### Docker Compose
Use the following for your `docker-compose.yml` file:
```yml
version: '3'
services:
elitemusic:
container_name: 'elite-music'
image: 'thatguyjacobee/elitemusic:latest'
elitesubsonic:
container_name: 'elite-subsonic'
image: 'ripsawuk/elite-subsonic:latest'
env_file:
- /path/to/.env
- .env
restart: unless-stopped
```

Expand All @@ -116,6 +116,24 @@ The Plex optional feature when enabled, allows you to stream music directly from
2. Next, you must provide a direct URL to your Plex Media Center. The default port that Plex Media Server runs on is `32400`. You can test that your `PLEX_SERVER` URL is correct, by pasting it into any web browser, and it should load successfully with a login page.
3. Finally, you must place your plex authentication token into the `PLEX_AUTHTOKEN` field. You can do this by browsing the XML file for a library item. Please follow the [official Plex Support article](https://support.plex.tv/articles/204059436-finding-an-authentication-token-x-plex-token/) to access your token. Once you have access to it, place it into your .env file.

Usage (after the bot is up):
- `/plex play query:<song>` — search and play from your library.
- `/plex albums query:<album>` - search and play albums from your library
- `/plex playlists query:<playlist>` — list your Plex playlists and enqueue them.

### Subsonic playback
Subsonic lets you stream from your Subsonic-compatible server (Subsonic/Airsonic/Navidrome/etc.) using the built-in Subsonic commands. All auth is via `.env`; no Discord login commands are required.

1. Set `ENABLE_SUBSONIC` to `true` in `.env`.
2. Set your server URL: `SUBSONIC_URL='http://YOUR_IP:PORT'`.
3. Set credentials: `SUBSONIC_USERNAME` and `SUBSONIC_PASSWORD` (account on your Subsonic server).
4. Restart the bot so the env vars are picked up.

Usage (after the bot is up):
- `/subsonic play query:<song>` — search and play from your library.
- `/subsonic albums query:<album>` - search and play albums from your library.
- `/subsonic playlists query:<playlist>` — list your Subsonic playlists and enqueue them.

### DJ Mode
Elite Music comes with a DJ Mode optional feature, which locks down the use of commands and interactions to members who have the specified DJ Role.

Expand Down
86 changes: 52 additions & 34 deletions commands/music/nowplaying.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,64 +14,82 @@ module.exports = {
var queue = player.nodes.get(interaction.guild.id);
if (!queue || !queue.isPlaying()) return interaction.reply({ content: `❌ | No music is currently being played!`, ephemeral: true });

const progress = queue.node.createProgressBar();
var create = progress.replace(/ 0:00/g, ' ◉ LIVE');
const progress = queue.node.createProgressBar({
indicator: '🔘',
leftChar: '▬',
rightChar: '▬',
length: 20
});
const createBar = progress.replace(/ 0:00/g, ' ◉ LIVE');

var coverImage = new AttachmentBuilder(queue.currentTrack.thumbnail, { name: 'coverimage.jpg', description: `Song Cover Image for ${queue.currentTrack.title}` })
// Get queue info
const queueSize = queue.tracks.size;
const loopMode = queue.repeatMode === 1 ? 'Track' : queue.repeatMode === 2 ? 'Queue' : 'Normal';
const pauseStatus = queue.node.isPaused() ? 'Paused' : 'Playing';

var coverImage = new AttachmentBuilder(queue.currentTrack.thumbnail, { name: 'coverimage.jpg', description: `Song Cover Image for ${queue.currentTrack.title}` });

const npembed = new EmbedBuilder()
.setAuthor({ name: interaction.client.user.tag, iconURL: interaction.client.user.displayAvatarURL() })
.setThumbnail('attachment://coverimage.jpg')
.setColor(client.config.embedColour)
.setTitle(`Now playing 🎵`)
.setDescription(`${queue.currentTrack.title} ${queue.currentTrack.queryType != 'arbitrary' ? `([Link](${queue.currentTrack.url}))` : ''}\n${create}`)
//.addField('\u200b', progress.replace(/ 0:00/g, ' ◉ LIVE'))
.setTimestamp()
.setAuthor({ name: interaction.client.user.tag, iconURL: interaction.client.user.displayAvatarURL() })
.setThumbnail('attachment://coverimage.jpg')
.setColor(client.config.embedColour)
.setTitle(`🎵 Now Playing`)
.setDescription(`**${queue.currentTrack.title}**${queue.currentTrack.queryType != 'arbitrary' ? ` ([Link](${queue.currentTrack.url}))` : ''}`)
.addFields(
{ name: '🎤 Artist', value: queue.currentTrack.author || 'Unknown', inline: true },
{ name: '⏱️ Duration', value: queue.currentTrack.duration || 'Unknown', inline: true },
{ name: '📊 Status', value: pauseStatus, inline: true },
{ name: '🔊 Volume', value: `${queue.node.volume}%`, inline: true },
{ name: '🔄 Loop Mode', value: loopMode, inline: true },
{ name: '📑 Queue', value: `${queueSize} song${queueSize !== 1 ? 's' : ''}`, inline: true },
{ name: '⏳ Progress', value: createBar, inline: false }
)
.setTimestamp();

if (queue.currentTrack.requestedBy != null) {
npembed.setFooter({ text: `Requested by: ${interaction.user.discriminator != 0 ? interaction.user.tag : interaction.user.username}` })
npembed.setFooter({ text: `Requested by: ${queue.currentTrack.requestedBy.discriminator != 0 ? queue.currentTrack.requestedBy.tag : queue.currentTrack.requestedBy.username}` });
}

var finalComponents = [
actionbutton = new ActionRowBuilder().addComponents(
new ButtonBuilder()
.setCustomId("np-delete")
.setStyle(4)
.setLabel("🗑️"),
//.addOptions(options)
const finalComponents = [
new ActionRowBuilder().addComponents(
new ButtonBuilder()
.setCustomId("np-back")
.setStyle(1)
.setLabel("⏮️ Previous"),
.setStyle(2)
.setEmoji("⏮️"),
new ButtonBuilder()
.setCustomId("np-pauseresume")
.setStyle(1)
.setLabel("⏯️ Play/Pause"),
.setStyle(2)
.setEmoji("⏯️"),
new ButtonBuilder()
.setCustomId("np-skip")
.setStyle(1)
.setLabel("⏭️ Skip"),
.setStyle(2)
.setEmoji("⏭️"),
new ButtonBuilder()
.setCustomId("np-clear")
.setStyle(1)
.setLabel("🧹 Clear Queue")
.setCustomId("np-stop")
.setStyle(2)
.setEmoji("⏹️")
),
actionbutton2 = new ActionRowBuilder().addComponents(
new ActionRowBuilder().addComponents(
new ButtonBuilder()
.setCustomId("np-volumeadjust")
.setStyle(1)
.setLabel("🔊 Adjust Volume"),
.setEmoji("🔊")
.setLabel("Volume"),
new ButtonBuilder()
.setCustomId("np-loop")
.setStyle(1)
.setLabel("🔂 Loop Once"),
.setEmoji("🔄")
.setLabel("Loop"),
new ButtonBuilder()
.setCustomId("np-shuffle")
.setStyle(1)
.setLabel("🔀 Shuffle Queue"),
.setEmoji("🔀")
.setLabel("Shuffle"),
new ButtonBuilder()
.setCustomId("np-stop")
.setStyle(1)
.setLabel("🛑 Stop Queue")
.setCustomId("np-clear")
.setStyle(4)
.setEmoji("🧹")
.setLabel("Clear")
)
];

Expand Down
2 changes: 1 addition & 1 deletion commands/music/play.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ module.exports = {
actionmenu.components[0].addOptions(
new StringSelectMenuOptionBuilder()
.setLabel(result.title.length > 100 ? `${result.title.substring(0, 97)}...` : result.title)
.setValue(`${!result.playlist ? 'song' : 'playlist' }_false_url=${result.url}`) // Schema: [type]_[playnext]_[url=track]...
.setValue(`${!result.playlist ? 'song' : 'playlist' }_false_url=${result.url}`)
.setDescription(`Duration - ${result.duration}`)
.setEmoji(emojis[count-1])
)
Expand Down
Loading