From 242ae2ffffe50676e803726faca61fb6a87061cc Mon Sep 17 00:00:00 2001 From: KGT1 Date: Wed, 23 Sep 2020 16:47:12 +0200 Subject: [PATCH] add seek functionality --- src/messagehandler.js | 2 +- src/playbackmanager.js | 42 ++++++++++++++++++++++++++++++++--------- src/util.js | 7 ++++++- src/websockethandler.js | 21 ++++++++++++++------- 4 files changed, 54 insertions(+), 18 deletions(-) diff --git a/src/messagehandler.js b/src/messagehandler.js index 6981ab2..b588934 100644 --- a/src/messagehandler.js +++ b/src/messagehandler.js @@ -113,7 +113,7 @@ async function playThis (message) { discordClient.user.client.voice.connections.forEach((element) => { songPlayMessage(message, argument); - playbackmanager.startPlaying(element, itemID, isSummendByPlay); + playbackmanager.startPlaying(element, itemID, 0, isSummendByPlay); }); } diff --git a/src/playbackmanager.js b/src/playbackmanager.js index 939c2ba..ed545f5 100644 --- a/src/playbackmanager.js +++ b/src/playbackmanager.js @@ -1,11 +1,17 @@ +const discordclientmanager = require("./discordclientmanager"); const { getAudioDispatcher, setAudioDispatcher } = require("./dispachermanager"); +const { + ticksToSeconds +} = require("./util"); var currentPlayingItemId; var progressInterval; var isPaused; +var _disconnectOnFinish; +var _seek; const jellyfinClientManager = require("./jellyfinclientmanager"); function streamURLbuilder (itemID, bitrate) { @@ -15,13 +21,20 @@ function streamURLbuilder (itemID, bitrate) { return `${jellyfinClientManager.getJellyfinClient().serverAddress()}/Audio/${itemID}/universal?UserId=${jellyfinClientManager.getJellyfinClient().getCurrentUserId()}&DeviceId=${jellyfinClientManager.getJellyfinClient().deviceId()}&MaxStreamingBitrate=${bitrate}&Container=${supportedContainers}&AudioCodec=${supportedCodecs}&api_key=${jellyfinClientManager.getJellyfinClient().accessToken()}&TranscodingContainer=ts&TranscodingProtocol=hls`; } -function startPlaying (voiceconnection, itemID, disconnectOnFinish) { +function startPlaying (voiceconnection = discordclientmanager.getDiscordClient().user.client.voice.connections.first(), itemID = currentPlayingItemId, seekTo, disconnectOnFinish = _disconnectOnFinish) { isPaused = false; + currentPlayingItemId = itemID; + _disconnectOnFinish = disconnectOnFinish; + _seek=seekTo*1000; async function playasync () { const url = streamURLbuilder(itemID, voiceconnection.channel.bitrate); - jellyfinClientManager.getJellyfinClient().reportPlaybackStart({ userID: `${jellyfinClientManager.getJellyfinClient().getCurrentUserId()}`, itemID: `${itemID}` }); - currentPlayingItemId = itemID; - setAudioDispatcher(voiceconnection.play(url)); + setAudioDispatcher(voiceconnection.play(url ,{seek: seekTo})); + console.log(seekTo, ticksToSeconds(getPostitionTicks())); + if(seekTo){ + jellyfinClientManager.getJellyfinClient().reportPlaybackProgress(getProgressPayload()); + }else{ + jellyfinClientManager.getJellyfinClient().reportPlaybackStart({ userID: `${jellyfinClientManager.getJellyfinClient().getCurrentUserId()}`, itemID: `${itemID}`, canSeek: true ,playSessionId: getPlaySessionId(), playMethod:getPlayMethod()}); + } getAudioDispatcher().on("finish", () => { if (disconnectOnFinish) { @@ -33,6 +46,16 @@ function startPlaying (voiceconnection, itemID, disconnectOnFinish) { } playasync().catch((rsn) => { console.log(rsn); }); } +/** + * @param {Number} toSeek - where to seek in ticks + */ +function seek(toSeek = 0){ + if(getAudioDispatcher()){ + startPlaying(undefined,undefined,ticksToSeconds(toSeek),_disconnectOnFinish); + jellyfinClientManager.getJellyfinClient().reportPlaybackProgress(getProgressPayload()); + } +} + /** * @param {Object=} disconnectVoiceConnection - Optional The voice Connection do disconnect from */ @@ -41,7 +64,7 @@ function stop (disconnectVoiceConnection) { if (disconnectVoiceConnection) { disconnectVoiceConnection.disconnect(); } - jellyfinClientManager.getJellyfinClient().reportPlaybackStopped({ userId: jellyfinClientManager.getJellyfinClient().getCurrentUserId(), itemId: currentPlayingItemId }); + jellyfinClientManager.getJellyfinClient().reportPlaybackStopped({ userId: jellyfinClientManager.getJellyfinClient().getCurrentUserId(), itemId: currentPlayingItemId ,playSessionId: getPlaySessionId()}); if (getAudioDispatcher()) { getAudioDispatcher().destroy(); } setAudioDispatcher(undefined); clearInterval(progressInterval); @@ -63,12 +86,12 @@ function playPause () { function getPostitionTicks () { // this is very sketchy but i dont know how else to do it - return (getAudioDispatcher().streamTime - getAudioDispatcher().pausedTime) * 10000; + return (_seek+getAudioDispatcher().streamTime - getAudioDispatcher().pausedTime) * 10000; } function getPlayMethod () { // TODO figure out how to figure this out - return "Transcode"; + return 0; } function getRepeatMode () { @@ -94,7 +117,7 @@ function getNowPLayingQueue () { } function getCanSeek () { - return false; + return true; } function getIsMuted () { @@ -143,5 +166,6 @@ module.exports = { stop, playPause, resume, - pause + pause, + seek }; diff --git a/src/util.js b/src/util.js index 5a5eeb6..28003bd 100644 --- a/src/util.js +++ b/src/util.js @@ -3,6 +3,11 @@ function checkJellyfinItemIDRegex (strgintomatch) { return regexresult; } +function ticksToSeconds (ticks){ + return ticks/10000000; +} + module.exports = { - checkJellyfinItemIDRegex + checkJellyfinItemIDRegex, + ticksToSeconds }; diff --git a/src/websockethandler.js b/src/websockethandler.js index fab35ab..7bc0973 100644 --- a/src/websockethandler.js +++ b/src/websockethandler.js @@ -11,22 +11,29 @@ function openSocket () { SupportedCommands: "Play,Playstate" } ); + jellyfinClientManager.getJellyfinClient().ajax({ + + type: 'POST', + + url: jellyfinClientManager.getJellyfinClient().getUrl('system/info/public'), + + data: JSON.stringify({}), + + contentType: 'application/json' + + }).then((resp)=>{console.log(resp)}) jellyfinClientManager.getJellyfinEvents().on(jellyfinClientManager.getJellyfinClient(), "message", (type, data) => { - // console.log(data); if (data.MessageType === "Play") { if (data.Data.PlayCommand === "PlayNow") { - discordclientmanager.getDiscordClient().user.client.voice.connections.forEach((element) => { - playbackmanager.startPlaying(element, data.Data.ItemIds[data.Data.StartIndex || 0], false); - element.on("error", (error) => { - console.error(error); - }); - }); + playbackmanager.startPlaying(undefined, data.Data.ItemIds[data.Data.StartIndex || 0],0, false); } } else if (data.MessageType === "Playstate") { if (data.Data.Command === "PlayPause") { playbackmanager.playPause(); } else if (data.Data.Command === "Stop") { playbackmanager.stop(); + } else if (data.Data.Command === "Seek") { + playbackmanager.seek(data.Data.SeekPositionTicks); } } });