aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/commands/fseek.ts33
-rw-r--r--src/inversify.config.ts2
-rw-r--r--src/services/player.ts17
3 files changed, 52 insertions, 0 deletions
diff --git a/src/commands/fseek.ts b/src/commands/fseek.ts
new file mode 100644
index 0000000..2fae1e6
--- /dev/null
+++ b/src/commands/fseek.ts
@@ -0,0 +1,33 @@
+import {Message, TextChannel} from 'discord.js';
+import {TYPES} from '../types';
+import {inject, injectable} from 'inversify';
+import PlayerManager from '../managers/player';
+import LoadingMessage from '../utils/loading-message';
+import Command from '.';
+
+@injectable()
+export default class implements Command {
+ public name = 'fseek';
+ public description = 'forward seek position in currently playing song';
+ private readonly playerManager: PlayerManager;
+
+ constructor(@inject(TYPES.Managers.Player) playerManager: PlayerManager) {
+ this.playerManager = playerManager;
+ }
+
+ public async execute(msg: Message, args: string []): Promise<void> {
+ const seekTime = parseInt(args[0], 10);
+
+ const loading = new LoadingMessage(msg.channel as TextChannel, 'hold on a sec');
+
+ await loading.start();
+
+ try {
+ await this.playerManager.get(msg.guild!.id).forwardSeek(seekTime);
+
+ await loading.stop('seeked');
+ } catch (_) {
+ await loading.stop('error somewhere');
+ }
+ }
+}
diff --git a/src/inversify.config.ts b/src/inversify.config.ts
index 4095859..9b91743 100644
--- a/src/inversify.config.ts
+++ b/src/inversify.config.ts
@@ -23,6 +23,7 @@ import QueueManager from './managers/queue';
import Command from './commands';
import Clear from './commands/clear';
import Config from './commands/config';
+import ForwardSeek from './commands/fseek';
import Play from './commands/play';
import QueueCommad from './commands/queue';
import Seek from './commands/seek';
@@ -41,6 +42,7 @@ container.bind<QueueManager>(TYPES.Managers.Queue).to(QueueManager).inSingletonS
// Commands
container.bind<Command>(TYPES.Command).to(Clear).inSingletonScope();
container.bind<Command>(TYPES.Command).to(Config).inSingletonScope();
+container.bind<Command>(TYPES.Command).to(ForwardSeek).inSingletonScope();
container.bind<Command>(TYPES.Command).to(Play).inSingletonScope();
container.bind<Command>(TYPES.Command).to(QueueCommad).inSingletonScope();
container.bind<Command>(TYPES.Command).to(Seek).inSingletonScope();
diff --git a/src/services/player.ts b/src/services/player.ts
index dfdf4b0..3ce68ae 100644
--- a/src/services/player.ts
+++ b/src/services/player.ts
@@ -21,6 +21,9 @@ export default class {
private voiceConnection: VoiceConnection | null = null;
private dispatcher: StreamDispatcher | null = null;
+ private lastStreamTime = 0;
+ private positionInSeconds = 0;
+
constructor(queue: Queue, cacheDir: string) {
this.queue = queue;
this.cacheDir = cacheDir;
@@ -52,6 +55,16 @@ export default class {
await this.waitForCache(currentSong.url);
this.attachListeners(this.voiceConnection.play(this.getCachedPath(currentSong.url), {seek: positionSeconds}));
+
+ this.positionInSeconds = positionSeconds;
+ }
+
+ async forwardSeek(positionSeconds: number): Promise<void> {
+ return this.seek(this.positionInSeconds + positionSeconds);
+ }
+
+ getPosition(): number {
+ return this.positionInSeconds;
}
async play(): Promise<void> {
@@ -224,6 +237,10 @@ export default class {
private attachListeners(stream: StreamDispatcher): void {
stream.on('speaking', async isSpeaking => {
+ // Update position
+ this.positionInSeconds += (stream.streamTime - this.lastStreamTime) / 1000;
+ this.lastStreamTime = stream.streamTime;
+
// Automatically advance queued song at end
if (!isSpeaking && this.status === STATUS.PLAYING) {
if (this.queue.get().length > 0) {