diff options
| author | Max Isom <[email protected]> | 2021-11-17 16:16:00 -0500 |
|---|---|---|
| committer | Max Isom <[email protected]> | 2021-11-17 16:16:00 -0500 |
| commit | dd81fc47fd3810da2c977eb4164f09bc2151e0b2 (patch) | |
| tree | cecf621652600d2f1930774b8f17b3d83e104b2d /src/services | |
| parent | defb56ed5ec606da90557753f53ab66844e94843 (diff) | |
| parent | 41b050a2f1fe4e2cb94629e2add1b490a69a2004 (diff) | |
| download | muse-dd81fc47fd3810da2c977eb4164f09bc2151e0b2.tar.xz muse-dd81fc47fd3810da2c977eb4164f09bc2151e0b2.zip | |
Merge branch 'master' into bugfix/only-add-listeners-once
Diffstat (limited to 'src/services')
| -rw-r--r-- | src/services/player.ts | 58 |
1 files changed, 35 insertions, 23 deletions
diff --git a/src/services/player.ts b/src/services/player.ts index 77d45ff..4a5e161 100644 --- a/src/services/player.ts +++ b/src/services/player.ts @@ -1,4 +1,4 @@ -import {VoiceConnection, VoiceChannel, StreamDispatcher, Snowflake, Client, TextChannel} from 'discord.js'; +import {VoiceChannel, Snowflake, Client, TextChannel} from 'discord.js'; import {promises as fs, createWriteStream} from 'fs'; import {Readable, PassThrough} from 'stream'; import path from 'path'; @@ -8,6 +8,7 @@ import {WriteStream} from 'fs-capacitor'; import ffmpeg from 'fluent-ffmpeg'; import shuffle from 'array-shuffle'; import errorMsg from '../utils/error-msg.js'; +import {AudioPlayer, AudioPlayerStatus, createAudioPlayer, createAudioResource, joinVoiceChannel, StreamType, VoiceConnection, VoiceConnectionStatus} from '@discordjs/voice'; export interface QueuedPlaylist { title: string; @@ -35,7 +36,7 @@ export default class { private queue: QueuedSong[] = []; private queuePosition = 0; private readonly cacheDir: string; - private dispatcher: StreamDispatcher | null = null; + private audioPlayer: AudioPlayer | null = null; private nowPlaying: QueuedSong | null = null; private playPositionInterval: NodeJS.Timeout | undefined; private lastSongURL = ''; @@ -50,23 +51,26 @@ export default class { } async connect(channel: VoiceChannel): Promise<void> { - const conn = await channel.join(); + const conn = joinVoiceChannel({ + channelId: channel.id, + guildId: channel.guild.id, + adapterCreator: channel.guild.voiceAdapterCreator, + }); this.voiceConnection = conn; } - disconnect(breakConnection = true): void { + disconnect(): void { if (this.voiceConnection) { if (this.status === STATUS.PLAYING) { this.pause(); } - if (breakConnection) { - this.voiceConnection.disconnect(); - } + this.voiceConnection.destroy(); + this.audioPlayer?.stop(); this.voiceConnection = null; - this.dispatcher = null; + this.audioPlayer = null; } } @@ -88,8 +92,11 @@ export default class { } const stream = await this.getStream(currentSong.url, {seek: positionSeconds}); - this.dispatcher = this.voiceConnection.play(stream, {type: 'webm/opus', bitrate: 'auto'}); - + this.audioPlayer = createAudioPlayer(); + this.voiceConnection.subscribe(this.audioPlayer); + this.audioPlayer.play(createAudioResource(stream, { + inputType: StreamType.WebmOpus, + })); this.attachListeners(); this.startTrackingPosition(positionSeconds); @@ -117,8 +124,8 @@ export default class { // Resume from paused state if (this.status === STATUS.PAUSED && currentSong.url === this.nowPlaying?.url) { - if (this.dispatcher) { - this.dispatcher.resume(); + if (this.audioPlayer) { + this.audioPlayer.unpause(); this.status = STATUS.PLAYING; this.startTrackingPosition(); return; @@ -132,7 +139,11 @@ export default class { try { const stream = await this.getStream(currentSong.url); - this.dispatcher = this.voiceConnection.play(stream, {type: 'webm/opus'}); + this.audioPlayer = createAudioPlayer(); + this.voiceConnection.subscribe(this.audioPlayer); + this.audioPlayer.play(createAudioResource(stream, { + inputType: StreamType.WebmOpus, + })); this.attachListeners(); @@ -170,8 +181,8 @@ export default class { this.status = STATUS.PAUSED; - if (this.dispatcher) { - this.dispatcher.pause(); + if (this.audioPlayer) { + this.audioPlayer.pause(); } this.stopTrackingPosition(); @@ -369,6 +380,7 @@ export default class { '1', '-reconnect_delay_max', '5', + '-re', ]); if (options.seek) { @@ -440,26 +452,26 @@ export default class { return; } - if (this.voiceConnection.listeners('disconnect').length === 0) { - this.voiceConnection.on('disconnect', this.onVoiceConnectionDisconnect.bind(this)); + if (this.voiceConnection.listeners(VoiceConnectionStatus.Disconnected).length === 0) { + this.voiceConnection.on(VoiceConnectionStatus.Disconnected, this.onVoiceConnectionDisconnect.bind(this)); } - if (!this.dispatcher) { + if (!this.audioPlayer) { return; } - if (this.dispatcher.listeners('speaking').length === 0) { - this.dispatcher.on('speaking', this.onVoiceConnectionSpeaking.bind(this)); + if (this.audioPlayer.listeners('stateChange').length === 0) { + this.audioPlayer.on('stateChange', this.onAudioPlayerStateChange.bind(this)); } } private onVoiceConnectionDisconnect(): void { - this.disconnect(false); + this.disconnect(); } - private async onVoiceConnectionSpeaking(isSpeaking: boolean): Promise<void> { + private async onAudioPlayerStateChange(_oldState: {status: AudioPlayerStatus}, newState: {status: AudioPlayerStatus}): Promise<void> { // Automatically advance queued song at end - if (!isSpeaking && this.status === STATUS.PLAYING) { + if (newState.status === AudioPlayerStatus.Idle && this.status === STATUS.PLAYING) { await this.forward(1); } } |
