Add volume command (#132)

This commit is contained in:
Manuel 2023-03-26 01:29:42 +01:00 committed by GitHub
parent 0130115be8
commit ea64f16661
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 99 additions and 2 deletions

View File

@ -29,8 +29,9 @@ import { DiscordMessageService } from './discord.message.service';
@Injectable()
export class DiscordVoiceService {
private readonly logger = new Logger(DiscordVoiceService.name);
private audioPlayer: AudioPlayer;
private voiceConnection: VoiceConnection;
private audioPlayer: AudioPlayer | undefined;
private voiceConnection: VoiceConnection | undefined;
private audioResource: AudioResource | undefined;
constructor(
private readonly discordMessageService: DiscordMessageService,
@ -44,6 +45,9 @@ export class DiscordVoiceService {
handleOnNewTrack(track: Track) {
const resource = createAudioResource(
track.getStreamUrl(this.jellyfinStreamBuilder),
{
inlineVolume: true,
},
);
this.playResource(resource);
}
@ -99,9 +103,14 @@ export class DiscordVoiceService {
};
}
changeVolume(volume: number) {
this.audioResource.volume.setVolume(volume);
}
playResource(resource: AudioResource<unknown>) {
this.logger.debug(`Playing audio resource with volume ${resource.volume}`);
this.createAndReturnOrGetAudioPlayer().play(resource);
this.audioResource = resource;
}
/**

View File

@ -16,6 +16,7 @@ import { StopPlaybackCommand } from './stop.command';
import { SummonCommand } from './summon.command';
import { PlaylistInteractionCollector } from './playlist/playlist.interaction-collector';
import { EnqueueRandomItemsCommand } from './random/random.command';
import { VolumeCommand } from './volume/volume.command';
@Module({
imports: [
@ -38,6 +39,7 @@ import { EnqueueRandomItemsCommand } from './random/random.command';
SummonCommand,
PlayItemCommand,
PreviousTrackCommand,
VolumeCommand,
],
exports: [],
})

View File

@ -0,0 +1,70 @@
import { SlashCommandPipe } from '@discord-nestjs/common';
import { Command, Handler, IA, InteractionEvent } from '@discord-nestjs/core';
import { Logger } from '@nestjs/common';
import { Injectable } from '@nestjs/common/decorators';
import { CommandInteraction } from 'discord.js';
import e from 'express';
import { DiscordMessageService } from 'src/clients/discord/discord.message.service';
import { DiscordVoiceService } from 'src/clients/discord/discord.voice.service';
import { PlaybackService } from 'src/playback/playback.service';
import { sleep } from 'src/utils/timeUtils';
import { VolumeCommandParams } from './volume.params';
@Injectable()
@Command({
name: 'volume',
description: 'Change the volume',
})
export class VolumeCommand {
private readonly logger = new Logger(VolumeCommand.name);
constructor(
private readonly discordVoiceService: DiscordVoiceService,
private readonly discordMessageService: DiscordMessageService,
private readonly playbackService: PlaybackService,
) {}
@Handler()
async handler(
@InteractionEvent(SlashCommandPipe) dto: VolumeCommandParams,
@IA() interaction: CommandInteraction,
): Promise<void> {
await interaction.deferReply();
if (!this.playbackService.getPlaylistOrDefault().hasActiveTrack()) {
await interaction.editReply({
embeds: [
this.discordMessageService.buildMessage({
title: `Unable to change your volume`,
description:
'The bot is not playing any music or is not straming to a channel',
}),
],
});
return;
}
const volume = dto.volume / 100;
this.logger.debug(
`Calculated volume ${volume} from dto param ${dto.volume}`,
);
this.discordVoiceService.changeVolume(volume);
// Discord takes some time to react. Confirmation message should appear after actual change
await sleep(1500);
await interaction.editReply({
embeds: [
this.discordMessageService.buildMessage({
title: `Sucessfully set volume to ${dto.volume.toFixed(0)}%`,
description:
'Updating may take a few seconds to take effect.\nPlease note that listening at a high volume for a long time may damage your hearing',
}),
],
});
}
}

View File

@ -0,0 +1,12 @@
import { Param, ParamType } from '@discord-nestjs/core';
export class VolumeCommandParams {
@Param({
required: true,
description: 'The desired volume',
type: ParamType.INTEGER,
minValue: 0,
maxValue: 150,
})
volume: number;
}

View File

@ -15,3 +15,7 @@ export const formatMillisecondsAsHumanReadable = (
);
return duration;
};
export function sleep(ms: number) {
return new Promise((resolve) => setTimeout(resolve, ms));
}