mirror of
https://github.com/BluemediaDev/muse.git
synced 2025-06-27 09:12:43 +02:00
feat: automatically turn down volume when people talks
This commit is contained in:
parent
534d8fafaa
commit
aae98255b1
7 changed files with 90 additions and 4 deletions
|
@ -2,22 +2,25 @@ import {inject, injectable} from 'inversify';
|
|||
import {TYPES} from '../types.js';
|
||||
import Player from '../services/player.js';
|
||||
import FileCacheProvider from '../services/file-cache.js';
|
||||
import Config from '../services/config.js';
|
||||
|
||||
@injectable()
|
||||
export default class {
|
||||
private readonly guildPlayers: Map<string, Player>;
|
||||
private readonly fileCache: FileCacheProvider;
|
||||
private readonly config: Config;
|
||||
|
||||
constructor(@inject(TYPES.FileCache) fileCache: FileCacheProvider) {
|
||||
constructor(@inject(TYPES.FileCache) fileCache: FileCacheProvider, @inject(TYPES.Config) config: Config) {
|
||||
this.guildPlayers = new Map();
|
||||
this.fileCache = fileCache;
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
get(guildId: string): Player {
|
||||
let player = this.guildPlayers.get(guildId);
|
||||
|
||||
if (!player) {
|
||||
player = new Player(this.fileCache, guildId);
|
||||
player = new Player(this.fileCache, guildId, this.config);
|
||||
|
||||
this.guildPlayers.set(guildId, player);
|
||||
}
|
||||
|
|
|
@ -14,6 +14,8 @@ const CONFIG_MAP = {
|
|||
YOUTUBE_API_KEY: process.env.YOUTUBE_API_KEY,
|
||||
SPOTIFY_CLIENT_ID: process.env.SPOTIFY_CLIENT_ID,
|
||||
SPOTIFY_CLIENT_SECRET: process.env.SPOTIFY_CLIENT_SECRET,
|
||||
TURN_DOWN_VOLUME_WHEN_PEOPLE_SPEAK: process.env.TURN_DOWN_VOLUME_WHEN_PEOPLE_SPEAK === 'true',
|
||||
TURN_DOWN_VOLUME_WHEN_PEOPLE_SPEAK_TARGET: process.env.TURN_DOWN_VOLUME_WHEN_PEOPLE_SPEAK_TARGET ?? 20,
|
||||
REGISTER_COMMANDS_ON_BOT: process.env.REGISTER_COMMANDS_ON_BOT === 'true',
|
||||
DATA_DIR,
|
||||
CACHE_DIR: path.join(DATA_DIR, 'cache'),
|
||||
|
@ -43,6 +45,8 @@ export default class Config {
|
|||
readonly DATA_DIR!: string;
|
||||
readonly CACHE_DIR!: string;
|
||||
readonly CACHE_LIMIT_IN_BYTES!: number;
|
||||
readonly TURN_DOWN_VOLUME_WHEN_PEOPLE_SPEAK!: boolean;
|
||||
readonly TURN_DOWN_VOLUME_WHEN_PEOPLE_SPEAK_TARGET!: number;
|
||||
readonly BOT_STATUS!: PresenceStatusData;
|
||||
readonly BOT_ACTIVITY_TYPE!: Exclude<ActivityType, ActivityType.Custom>;
|
||||
readonly BOT_ACTIVITY_URL!: string;
|
||||
|
|
|
@ -20,6 +20,7 @@ import FileCacheProvider from './file-cache.js';
|
|||
import debug from '../utils/debug.js';
|
||||
import {getGuildSettings} from '../utils/get-guild-settings.js';
|
||||
import {buildPlayingMessageEmbed} from '../utils/build-embed.js';
|
||||
import Config from './config.js';
|
||||
|
||||
export enum MediaSource {
|
||||
Youtube,
|
||||
|
@ -82,9 +83,13 @@ export default class {
|
|||
private readonly fileCache: FileCacheProvider;
|
||||
private disconnectTimer: NodeJS.Timeout | null = null;
|
||||
|
||||
constructor(fileCache: FileCacheProvider, guildId: string) {
|
||||
private readonly channelToSpeakingUsers: Map<string, Set<string>> = new Map();
|
||||
private readonly config: Config;
|
||||
|
||||
constructor(fileCache: FileCacheProvider, guildId: string, config: Config) {
|
||||
this.fileCache = fileCache;
|
||||
this.guildId = guildId;
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
async connect(channel: VoiceChannel): Promise<void> {
|
||||
|
@ -96,6 +101,7 @@ export default class {
|
|||
this.voiceConnection = joinVoiceChannel({
|
||||
channelId: channel.id,
|
||||
guildId: channel.guild.id,
|
||||
selfDeaf: false,
|
||||
adapterCreator: channel.guild.voiceAdapterCreator as DiscordGatewayAdapterCreator,
|
||||
});
|
||||
|
||||
|
@ -115,6 +121,9 @@ export default class {
|
|||
/* eslint-enable @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call */
|
||||
|
||||
this.currentChannel = channel;
|
||||
if (newState.status === VoiceConnectionStatus.Ready) {
|
||||
this.registerVoiceActivityListener();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -302,6 +311,62 @@ export default class {
|
|||
}
|
||||
}
|
||||
|
||||
registerVoiceActivityListener(): void {
|
||||
if (!this.config.TURN_DOWN_VOLUME_WHEN_PEOPLE_SPEAK || !this.voiceConnection) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.voiceConnection.receiver.speaking.on('start', (userId: string) => {
|
||||
if (!this.currentChannel) {
|
||||
return;
|
||||
}
|
||||
|
||||
const member = this.currentChannel.members.get(userId);
|
||||
const channelId = this.currentChannel?.id;
|
||||
|
||||
if (member) {
|
||||
if (!this.channelToSpeakingUsers.has(channelId)) {
|
||||
this.channelToSpeakingUsers.set(channelId, new Set());
|
||||
}
|
||||
|
||||
this.channelToSpeakingUsers.get(channelId)?.add(member.id);
|
||||
}
|
||||
|
||||
this.suppressVoiceWhenPeopleAreSpeaking();
|
||||
});
|
||||
|
||||
this.voiceConnection.receiver.speaking.on('end', (userId: string) => {
|
||||
if (!this.currentChannel) {
|
||||
return;
|
||||
}
|
||||
|
||||
const member = this.currentChannel.members.get(userId);
|
||||
const channelId = this.currentChannel.id;
|
||||
if (member) {
|
||||
if (!this.channelToSpeakingUsers.has(channelId)) {
|
||||
this.channelToSpeakingUsers.set(channelId, new Set());
|
||||
}
|
||||
|
||||
this.channelToSpeakingUsers.get(channelId)?.delete(member.id);
|
||||
}
|
||||
|
||||
this.suppressVoiceWhenPeopleAreSpeaking();
|
||||
});
|
||||
}
|
||||
|
||||
suppressVoiceWhenPeopleAreSpeaking(): void {
|
||||
if (!this.currentChannel) {
|
||||
return;
|
||||
}
|
||||
|
||||
const speakingUsers = this.channelToSpeakingUsers.get(this.currentChannel.id);
|
||||
if (speakingUsers && speakingUsers.size > 0) {
|
||||
this.setVolume(this.config.TURN_DOWN_VOLUME_WHEN_PEOPLE_SPEAK_TARGET);
|
||||
} else {
|
||||
this.setVolume(this.defaultVolume);
|
||||
}
|
||||
}
|
||||
|
||||
canGoForward(skip: number) {
|
||||
return (this.queuePosition + skip - 1) < this.queue.length;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue