Skip to content

Commit

Permalink
Fix inaccurate radio song time passed
Browse files Browse the repository at this point in the history
  • Loading branch information
ywssp committed Jun 24, 2024
1 parent 448bfbd commit f898e1d
Show file tree
Hide file tree
Showing 5 changed files with 104 additions and 5 deletions.
9 changes: 8 additions & 1 deletion src/commands/Music/NowPlaying.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,14 @@ export class NowPlayingCommand extends Command {
text: `${radioData.station === 'jpop' ? '🇯🇵 J-Pop' : '🇰🇷 K-Pop'} Station`
});

const startTime = DateTime.fromISO(lastUpdate.startTime);
let startTime = DateTime.fromISO(lastUpdate.startTime);
if (
lastUpdate.localStartTime !== undefined &&
lastUpdate.localStartTime !== null
) {
startTime = lastUpdate.localStartTime;
}

const currentTime = DateTime.now();

const passedTime = currentTime.diff(startTime);
Expand Down
15 changes: 14 additions & 1 deletion src/functions/music-utilities/radio/setupRadioWebsocket.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
} from '../../../interfaces/Music/Radio/AvailableRadioStations';
import { RadioWebsocketUpdate } from '../../../interfaces/Music/Radio/RadioWebsocketUpdate';
import { sendRadioUpdate } from './sendRadioUpdate';
import { DateTime } from 'luxon';

const radioWebsocketURLs: Record<
RadioStationNames,
Expand All @@ -21,6 +22,7 @@ export function createRadioWebsocketConnection(radioName: 'kpop' | 'jpop') {

socket.onopen = () => {
container.radioWebsockets[radioName].connection = socket;
container.radioWebsockets[radioName].firstUpdate = true;
};

socket.onmessage = (event) => {
Expand All @@ -46,11 +48,22 @@ export function createRadioWebsocketConnection(radioName: 'kpop' | 'jpop') {
}

if (data.op === 1) {
if (container.radioWebsockets[radioName].lastUpdate === data.d) {
if (
container.radioWebsockets[radioName].lastUpdate?.startTime ===
data.d.startTime
) {
return;
}

container.radioWebsockets[radioName].lastUpdate = data.d;

if (container.radioWebsockets[radioName].firstUpdate) {
container.radioWebsockets[radioName].firstUpdate = false;
} else {
container.radioWebsockets[radioName].lastUpdate.localStartTime =
DateTime.now();
}

for (const guildId of container.radioWebsockets[radioName].guildIdSet) {
sendRadioUpdate(guildId, data.d);
}
Expand Down
81 changes: 78 additions & 3 deletions src/interfaces/Music/Queue System/TrackInfo.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
import { User } from 'discord.js';
import { Duration } from 'luxon';
import { extractID, YouTubeVideo, SoundCloudTrack } from 'play-dl';
import {
extractID,
YouTubeVideo,
SoundCloudTrack,
SpotifyTrack
} from 'play-dl';
import { SongDetailed as YTMusicSong } from 'ytmusic-api';

export class TrackInfo {
readonly type = 'queue_track';
readonly source: 'youtube' | 'soundcloud' | 'youtube_music';
readonly source: 'youtube' | 'soundcloud' | 'youtube_music' | 'spotify';
readonly title: string;
readonly duration: Duration | 'Live Stream';
readonly url: string;
Expand All @@ -16,7 +21,14 @@ export class TrackInfo {
};
readonly thumbnail?: string;

constructor(data: TrackInfo | YouTubeVideo | SoundCloudTrack | YTMusicSong) {
constructor(
data:
| TrackInfo
| YouTubeVideo
| SoundCloudTrack
| YTMusicSong
| SpotifyTrack
) {
if (data instanceof TrackInfo) {
this.source = data.source;
this.title = data.title;
Expand Down Expand Up @@ -95,6 +107,21 @@ export class TrackInfo {
this.thumbnail = data.thumbnails[data.thumbnails.length - 1]?.url;
}

// Spotify Track handling
else if (data instanceof SpotifyTrack) {
this.source = 'spotify';
this.title = data.name;
this.url = data.url;
this.id = data.id.toString();
this.uploader = {
name: data.artists[0].name,
url: data.artists[0].url
};
this.duration = Duration.fromMillis(data.durationInMs);
this.thumbnail = data.thumbnail?.url;
return;
}

// If the data is not a valid type
else {
throw new Error('Invalid data type provided to TrackInfo constructor.');
Expand Down Expand Up @@ -122,3 +149,51 @@ export class CachedTrackInfo extends TrackInfo {
this.cachedAt = cachedAt;
}
}

export class AdaptedTrackInfo extends TrackInfo {
readonly matchedTrack: TrackInfo;
readonly isAdapted = true;
readonly source: 'spotify';

constructor(
data:
| AdaptedTrackInfo
| {
data: TrackInfo;
matchedTrack: TrackInfo;
}
) {
let trackData: TrackInfo;
let matchedTrack: TrackInfo;

if (data instanceof AdaptedTrackInfo) {
trackData = data;
matchedTrack = data.matchedTrack;
} else {
trackData = data.data;
matchedTrack = data.matchedTrack;
}

super(trackData);
this.source = 'spotify';
this.matchedTrack = matchedTrack;
}
}

export class QueuedAdaptedTrackInfo extends AdaptedTrackInfo {
readonly addedBy: string;

constructor(track: AdaptedTrackInfo, user: User) {
super(track);
this.addedBy = user.tag;
}
}

export class CachedAdaptedTrackInfo extends AdaptedTrackInfo {
readonly cachedAt: Date;

constructor(track: AdaptedTrackInfo, cachedAt: Date) {
super(track);
this.cachedAt = cachedAt;
}
}
2 changes: 2 additions & 0 deletions src/interfaces/Music/Radio/RadioWebsocketUpdate.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { DateTime } from 'luxon';
import { RadioSongInfo } from './RadioSongInfo';

export type RadioWebsocketUpdateData = {
song: RadioSongInfo;
startTime: string;
localStartTime: DateTime | undefined;
lastPlayed: RadioSongInfo[];
requester: {
name: string;
Expand Down
2 changes: 2 additions & 0 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import { CachedTrackInfo } from './interfaces/Music/Queue System/TrackInfo';
import { RadioWebsocketUpdate } from './interfaces/Music/Radio/RadioWebsocketUpdate';
import type WebSocket from 'ws';
import LRU from 'lru-cache';

declare module '@sapphire/pieces' {
interface Container {
guildMusicDataMap: Map<string, GuildMusicData>;
Expand All @@ -46,6 +47,7 @@ declare module '@sapphire/pieces' {
RadioStationNames,
{
connection: WebSocket | null;
firstUpdate: boolean;
heartbeat: NodeJS.Timeout | null;
lastUpdate: Exclude<RadioWebsocketUpdate, { op: 0 | 10 }>['d'] | null;
guildIdSet: Set<string>;
Expand Down

0 comments on commit f898e1d

Please sign in to comment.