mirror of
https://github.com/BluemediaDev/muse.git
synced 2025-05-09 19:51:36 +02:00
Parse duration strings for /fseek and /seek (#565)
This commit is contained in:
parent
03d5cfffd1
commit
6c00727a4a
7 changed files with 58 additions and 13 deletions
|
@ -5,15 +5,16 @@ import {inject, injectable} from 'inversify';
|
|||
import PlayerManager from '../managers/player.js';
|
||||
import Command from '.';
|
||||
import {prettyTime} from '../utils/time.js';
|
||||
import durationStringToSeconds from '../utils/duration-string-to-seconds.js';
|
||||
|
||||
@injectable()
|
||||
export default class implements Command {
|
||||
public readonly slashCommand = new SlashCommandBuilder()
|
||||
.setName('fseek')
|
||||
.setDescription('seek forward in the current song')
|
||||
.addNumberOption(option => option
|
||||
.setName('seconds')
|
||||
.setDescription('the number of seconds to skip forward')
|
||||
.addStringOption(option => option
|
||||
.setName('time')
|
||||
.setDescription('an interval expression or number of seconds (1m, 30s, 100)')
|
||||
.setRequired(true));
|
||||
|
||||
public requiresVC = true;
|
||||
|
@ -37,12 +38,14 @@ export default class implements Command {
|
|||
throw new Error('can\'t seek in a livestream');
|
||||
}
|
||||
|
||||
const seekTime = interaction.options.getNumber('seconds');
|
||||
const seekValue = interaction.options.getString('value');
|
||||
|
||||
if (!seekTime) {
|
||||
throw new Error('missing number of seconds to seek');
|
||||
if (!seekValue) {
|
||||
throw new Error('missing seek value');
|
||||
}
|
||||
|
||||
const seekTime = durationStringToSeconds(seekValue);
|
||||
|
||||
if (seekTime + player.getPosition() > currentSong.length) {
|
||||
throw new Error('can\'t seek past the end of the song');
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ import PlayerManager from '../managers/player.js';
|
|||
import Command from '.';
|
||||
import {parseTime, prettyTime} from '../utils/time.js';
|
||||
import {SlashCommandBuilder} from '@discordjs/builders';
|
||||
import durationStringToSeconds from '../utils/duration-string-to-seconds.js';
|
||||
|
||||
@injectable()
|
||||
export default class implements Command {
|
||||
|
@ -13,7 +14,7 @@ export default class implements Command {
|
|||
.setDescription('seek to a position from beginning of song')
|
||||
.addStringOption(option =>
|
||||
option.setName('time')
|
||||
.setDescription('time to seek')
|
||||
.setDescription('an interval expression or number of seconds (1m, 30s, 100)')
|
||||
.setRequired(true),
|
||||
);
|
||||
|
||||
|
@ -45,7 +46,7 @@ export default class implements Command {
|
|||
if (time.includes(':')) {
|
||||
seekTime = parseTime(time);
|
||||
} else {
|
||||
seekTime = parseInt(time, 10);
|
||||
seekTime = durationStringToSeconds(time);
|
||||
}
|
||||
|
||||
if (seekTime > currentSong.length) {
|
||||
|
|
|
@ -5,7 +5,17 @@ import ytdl from 'ytdl-core';
|
|||
import {WriteStream} from 'fs-capacitor';
|
||||
import ffmpeg from 'fluent-ffmpeg';
|
||||
import shuffle from 'array-shuffle';
|
||||
import {AudioPlayer, AudioPlayerStatus, createAudioPlayer, createAudioResource, joinVoiceChannel, StreamType, VoiceConnection, VoiceConnectionStatus} from '@discordjs/voice';
|
||||
import {
|
||||
AudioPlayer,
|
||||
AudioPlayerState,
|
||||
AudioPlayerStatus,
|
||||
createAudioPlayer,
|
||||
createAudioResource,
|
||||
joinVoiceChannel,
|
||||
StreamType,
|
||||
VoiceConnection,
|
||||
VoiceConnectionStatus,
|
||||
} from '@discordjs/voice';
|
||||
import FileCacheProvider from './file-cache.js';
|
||||
import debug from '../utils/debug.js';
|
||||
import {prisma} from '../utils/db.js';
|
||||
|
@ -493,7 +503,7 @@ export default class {
|
|||
}
|
||||
|
||||
if (this.audioPlayer.listeners('stateChange').length === 0) {
|
||||
this.audioPlayer.on('stateChange', this.onAudioPlayerStateChange.bind(this));
|
||||
this.audioPlayer.on(AudioPlayerStatus.Idle, this.onAudioPlayerIdle.bind(this));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -501,7 +511,7 @@ export default class {
|
|||
this.disconnect();
|
||||
}
|
||||
|
||||
private async onAudioPlayerStateChange(_oldState: {status: AudioPlayerStatus}, newState: {status: AudioPlayerStatus}): Promise<void> {
|
||||
private async onAudioPlayerIdle(_oldState: AudioPlayerState, newState: AudioPlayerState): Promise<void> {
|
||||
// Automatically advance queued song at end
|
||||
if (newState.status === AudioPlayerStatus.Idle && this.status === STATUS.PLAYING) {
|
||||
await this.forward(1);
|
||||
|
|
21
src/utils/duration-string-to-seconds.ts
Normal file
21
src/utils/duration-string-to-seconds.ts
Normal file
|
@ -0,0 +1,21 @@
|
|||
import parse from 'parse-duration';
|
||||
|
||||
/**
|
||||
* Parse duration strings to seconds.
|
||||
* @param str any common duration format, like 1m or 1hr 30s. If the input is a number it's assumed to be in seconds.
|
||||
* @returns seconds
|
||||
*/
|
||||
const durationStringToSeconds = (str: string) => {
|
||||
let seconds;
|
||||
const isInputSeconds = Boolean(/\d+$/.exec(str));
|
||||
|
||||
if (isInputSeconds) {
|
||||
seconds = Number.parseInt(str, 10);
|
||||
} else {
|
||||
seconds = parse(str) / 1000;
|
||||
}
|
||||
|
||||
return seconds;
|
||||
};
|
||||
|
||||
export default durationStringToSeconds;
|
Loading…
Add table
Add a link
Reference in a new issue