diff --git a/src/clients/discord/discord.voice.service.ts b/src/clients/discord/discord.voice.service.ts index 615fbc9..1e92493 100644 --- a/src/clients/discord/discord.voice.service.ts +++ b/src/clients/discord/discord.voice.service.ts @@ -41,7 +41,7 @@ export class DiscordVoiceService { private readonly eventEmitter: EventEmitter2, ) {} - @OnEvent('internal.audio.announce') + @OnEvent('internal.audio.track.announce') handleOnNewTrack(track: Track) { const resource = createAudioResource( track.getStreamUrl(this.jellyfinStreamBuilder), @@ -264,9 +264,12 @@ export class DiscordVoiceService { this.logger.debug(`Audio player finished playing old resource`); - const hasNextTrack = this.playbackService - .getPlaylistOrDefault() - .hasNextTrackInPlaylist(); + const playlist = this.playbackService.getPlaylistOrDefault(); + const finishedTrack = playlist.getActiveTrack(); + + this.eventEmitter.emit('internal.audio.track.finish', finishedTrack); + + const hasNextTrack = playlist.hasNextTrackInPlaylist(); this.logger.debug( `Playlist has next track: ${hasNextTrack ? 'yes' : 'no'}`, diff --git a/src/clients/jellyfin/jellyfin.playstate.service.ts b/src/clients/jellyfin/jellyfin.playstate.service.ts index 57b1483..c38221b 100644 --- a/src/clients/jellyfin/jellyfin.playstate.service.ts +++ b/src/clients/jellyfin/jellyfin.playstate.service.ts @@ -10,9 +10,9 @@ import { getSessionApi } from '@jellyfin/sdk/lib/utils/api/session-api'; import { Injectable, Logger } from '@nestjs/common'; import { OnEvent } from '@nestjs/event-emitter'; +import { Track } from 'src/models/shared/Track'; import { PlaybackService } from '../../playback/playback.service'; -import { Track } from '../../types/track'; @Injectable() export class JellyinPlaystateService { @@ -46,11 +46,28 @@ export class JellyinPlaystateService { this.logger.debug('Reported playback capabilities sucessfully'); } - @OnEvent('playback.newTrack') + @OnEvent('internal.audio.track.announce') private async onPlaybackNewTrack(track: Track) { + this.logger.debug(`Reporting playback start on track '${track.id}'`); await this.playstateApi.reportPlaybackStart({ playbackStartInfo: { - ItemId: track.jellyfinId, + ItemId: track.id, + }, + }); + } + + @OnEvent('internal.audio.track.finish') + private async onPlaybackFinished(track: Track) { + if (!track) { + this.logger.error( + `Unable to report playback because finished track was undefined`, + ); + return; + } + this.logger.debug(`Reporting playback finish on track '${track.id}'`); + await this.playstateApi.reportPlaybackStopped({ + playbackStopInfo: { + ItemId: track.id, }, }); } diff --git a/src/commands/stop.command.ts b/src/commands/stop.command.ts index d9d1579..b57b129 100644 --- a/src/commands/stop.command.ts +++ b/src/commands/stop.command.ts @@ -30,8 +30,8 @@ export class StopPlaybackCommand { ? 'In addition, your playlist has been cleared' : 'There is no active track in the queue'; if (hasActiveTrack) { - this.playbackService.getPlaylistOrDefault().clear(); this.discordVoiceService.stop(false); + // this.playbackService.getPlaylistOrDefault().clear(); } await interaction.reply({ diff --git a/src/models/shared/Playlist.ts b/src/models/shared/Playlist.ts index 9ca749a..d86d0ae 100644 --- a/src/models/shared/Playlist.ts +++ b/src/models/shared/Playlist.ts @@ -49,6 +49,8 @@ export class Playlist { * @returns if the track has been changed successfully */ setNextTrackAsActiveTrack(): boolean { + this.announceTrackFinishIfSet(); + if (this.activeTrackIndex >= this.tracks.length) { return false; } @@ -66,6 +68,8 @@ export class Playlist { * @returns if the track has been changed successfully */ setPreviousTrackAsActiveTrack(): boolean { + this.announceTrackFinishIfSet(); + if (this.activeTrackIndex <= 0) { return false; } @@ -124,6 +128,15 @@ export class Playlist { this.activeTrackIndex = undefined; } + private announceTrackFinishIfSet() { + if (this.activeTrackIndex === undefined) { + return; + } + + const currentTrack = this.getActiveTrack(); + this.eventEmitter.emit('internal.audio.track.finish', currentTrack); + } + private announceTrackChange() { if (!this.activeTrackIndex) { this.activeTrackIndex = 0; @@ -131,7 +144,7 @@ export class Playlist { const activeTrack = this.getActiveTrack(); activeTrack.playing = true; - this.eventEmitter.emit('internal.audio.announce', activeTrack); + this.eventEmitter.emit('internal.audio.track.announce', activeTrack); } private isActiveTrackOutOfSync(): boolean {