mirror of
https://github.com/informaticker/discord-jellyfin-bot.git
synced 2024-11-23 18:21:55 +01:00
Format code using Prettier
This commit is contained in:
parent
8ba7ceb7f4
commit
00a66a668f
10
config.json
10
config.json
@ -1,10 +0,0 @@
|
|||||||
{
|
|
||||||
"token":"",
|
|
||||||
"server-address":"",
|
|
||||||
"jellyfin-username":"",
|
|
||||||
"jellyfin-password":"",
|
|
||||||
"discord-prefix":"?",
|
|
||||||
"jellyfin-app-name":"Jellyfin Discord Music Bot",
|
|
||||||
"interactive-seek-bar-update-intervall":2000,
|
|
||||||
"log-level":"info"
|
|
||||||
}
|
|
10
config.json.example
Normal file
10
config.json.example
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"token": "",
|
||||||
|
"server-address": "",
|
||||||
|
"jellyfin-username": "",
|
||||||
|
"jellyfin-password": "",
|
||||||
|
"discord-prefix": "?",
|
||||||
|
"jellyfin-app-name": "Jellyfin Discord Music Bot",
|
||||||
|
"interactive-seek-bar-update-intervall": 10000,
|
||||||
|
"log-level": "info"
|
||||||
|
}
|
@ -1,16 +1,13 @@
|
|||||||
const discordclientmanager = require("./discordclientmanager");
|
const discordclientmanager = require("./discordclientmanager");
|
||||||
const CONFIG = require("../config.json");
|
const CONFIG = require("../config.json");
|
||||||
const {
|
const { secondsToHms, ticksToSeconds } = require("./util");
|
||||||
secondsToHms,
|
|
||||||
ticksToSeconds
|
|
||||||
} = require("./util");
|
|
||||||
|
|
||||||
function getProgressString (percent) {
|
function getProgressString(percent) {
|
||||||
// the min with of the discord window allows for this many chars
|
// the min with of the discord window allows for this many chars
|
||||||
const NUMBER_OF_CHARS = 12;
|
const NUMBER_OF_CHARS = 12;
|
||||||
let string = "";
|
let string = "";
|
||||||
for (let iX = 0; iX < NUMBER_OF_CHARS; iX++) {
|
for (let iX = 0; iX < NUMBER_OF_CHARS; iX++) {
|
||||||
if (percent > (iX) / NUMBER_OF_CHARS) {
|
if (percent > iX / NUMBER_OF_CHARS) {
|
||||||
string += "█";
|
string += "█";
|
||||||
} else {
|
} else {
|
||||||
string += "▒";
|
string += "▒";
|
||||||
@ -24,7 +21,7 @@ function getProgressString (percent) {
|
|||||||
* @returns {String}
|
* @returns {String}
|
||||||
*/
|
*/
|
||||||
// TODO do this with something like wcwidth
|
// TODO do this with something like wcwidth
|
||||||
function getMaxWidthString (string) {
|
function getMaxWidthString(string) {
|
||||||
const NUMBER_OF_CHARS = 12;
|
const NUMBER_OF_CHARS = 12;
|
||||||
if (string.length > NUMBER_OF_CHARS) {
|
if (string.length > NUMBER_OF_CHARS) {
|
||||||
return string.slice(0, NUMBER_OF_CHARS - 3) + "...";
|
return string.slice(0, NUMBER_OF_CHARS - 3) + "...";
|
||||||
@ -49,35 +46,53 @@ class InterActivePlayMessage {
|
|||||||
* @param {Function} onNext
|
* @param {Function} onNext
|
||||||
* @param {Function} onRepeat
|
* @param {Function} onRepeat
|
||||||
*/
|
*/
|
||||||
constructor (message, title, artist, imageURL, itemURL, ticksLength, onPrevious, onPausePlay, onStop, onNext, onRepeat, playlistLenth) {
|
constructor(
|
||||||
|
message,
|
||||||
|
title,
|
||||||
|
artist,
|
||||||
|
imageURL,
|
||||||
|
itemURL,
|
||||||
|
ticksLength,
|
||||||
|
onPrevious,
|
||||||
|
onPausePlay,
|
||||||
|
onStop,
|
||||||
|
onNext,
|
||||||
|
onRepeat,
|
||||||
|
playlistLenth
|
||||||
|
) {
|
||||||
this.ticksLength = ticksLength;
|
this.ticksLength = ticksLength;
|
||||||
var exampleEmbed = {
|
var exampleEmbed = {
|
||||||
color: 0x0099ff,
|
color: 0x0099ff,
|
||||||
title: "Now Playing",
|
title: "Now Playing",
|
||||||
url: itemURL,
|
url: itemURL,
|
||||||
description: `${getMaxWidthString(title)}\nby\n ${getMaxWidthString(artist)}`,
|
description: `\`\`${getMaxWidthString(title)}\`\` by \`\`${getMaxWidthString(
|
||||||
|
artist
|
||||||
|
)}\`\``,
|
||||||
thumbnail: {
|
thumbnail: {
|
||||||
url: imageURL
|
url: imageURL,
|
||||||
},
|
},
|
||||||
fields: [],
|
fields: [],
|
||||||
timestamp: new Date()
|
timestamp: new Date(),
|
||||||
};
|
};
|
||||||
if (typeof CONFIG["interactive-seek-bar-update-intervall"] === "number") {
|
if (typeof CONFIG["interactive-seek-bar-update-intervall"] === "number") {
|
||||||
exampleEmbed.fields.push({
|
exampleEmbed.fields.push({
|
||||||
name: getProgressString(0 / this.ticksLength),
|
name: getProgressString(0 / this.ticksLength),
|
||||||
value: `${secondsToHms(0)} / ${secondsToHms(ticksToSeconds(this.ticksLength))}`,
|
value: `${secondsToHms(0)} / ${secondsToHms(
|
||||||
inline: false
|
ticksToSeconds(this.ticksLength)
|
||||||
|
)}`,
|
||||||
|
inline: false,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (playlistLenth) {
|
if (playlistLenth) {
|
||||||
exampleEmbed.fields.push({
|
exampleEmbed.fields.push({
|
||||||
name: `1 of ${playlistLenth}`,
|
name: `1 of ${playlistLenth}`,
|
||||||
value: "Playlist",
|
value: "Playlist",
|
||||||
inline: false
|
inline: false,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
message.channel.send({
|
message.channel
|
||||||
embed: exampleEmbed
|
.send({
|
||||||
|
embed: exampleEmbed,
|
||||||
})
|
})
|
||||||
.then((val) => {
|
.then((val) => {
|
||||||
this.musicplayermessage = val;
|
this.musicplayermessage = val;
|
||||||
@ -86,10 +101,11 @@ class InterActivePlayMessage {
|
|||||||
val.react("⏹️");
|
val.react("⏹️");
|
||||||
val.react("⏭️");
|
val.react("⏭️");
|
||||||
val.react("🔁");
|
val.react("🔁");
|
||||||
}).catch(console.error);
|
})
|
||||||
|
.catch(console.error);
|
||||||
|
|
||||||
function reactionchange (reaction, user, musicplayermessage) {
|
function reactionchange(reaction, user, musicplayermessage) {
|
||||||
if (reaction.message.id === musicplayermessage.id && !(user.bot)) {
|
if (reaction.message.id === musicplayermessage.id && !user.bot) {
|
||||||
try {
|
try {
|
||||||
switch (reaction._emoji.name) {
|
switch (reaction._emoji.name) {
|
||||||
case "⏮️":
|
case "⏮️":
|
||||||
@ -110,26 +126,34 @@ class InterActivePlayMessage {
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {}
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
discordclientmanager.getDiscordClient().on("messageReactionAdd", (reaction, user) => {
|
discordclientmanager
|
||||||
|
.getDiscordClient()
|
||||||
|
.on("messageReactionAdd", (reaction, user) => {
|
||||||
reactionchange(reaction, user, this.musicplayermessage);
|
reactionchange(reaction, user, this.musicplayermessage);
|
||||||
});
|
});
|
||||||
discordclientmanager.getDiscordClient().on("messageReactionRemove", (reaction, user) => {
|
discordclientmanager
|
||||||
|
.getDiscordClient()
|
||||||
|
.on("messageReactionRemove", (reaction, user) => {
|
||||||
reactionchange(reaction, user, this.musicplayermessage);
|
reactionchange(reaction, user, this.musicplayermessage);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
updateProgress (ticks) {
|
updateProgress(ticks) {
|
||||||
if (typeof this.musicplayermessage !== "undefined" && typeof this.musicplayermessage.embeds[0] !== "undefined" && typeof this.musicplayermessage.embeds[0].fields[0] !== "undefined") {
|
if (
|
||||||
|
typeof this.musicplayermessage !== "undefined" &&
|
||||||
|
typeof this.musicplayermessage.embeds[0] !== "undefined" &&
|
||||||
|
typeof this.musicplayermessage.embeds[0].fields[0] !== "undefined"
|
||||||
|
) {
|
||||||
this.musicplayermessage.embeds[0].fields[0] = {
|
this.musicplayermessage.embeds[0].fields[0] = {
|
||||||
name: getProgressString(ticks / this.ticksLength),
|
name: getProgressString(ticks / this.ticksLength),
|
||||||
value: `${secondsToHms(ticksToSeconds(ticks))} / ${secondsToHms(ticksToSeconds(this.ticksLength))}`,
|
value: `${secondsToHms(ticksToSeconds(ticks))} / ${secondsToHms(
|
||||||
inline: false
|
ticksToSeconds(this.ticksLength)
|
||||||
|
)}`,
|
||||||
|
inline: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
this.musicplayermessage.timestamp = new Date();
|
this.musicplayermessage.timestamp = new Date();
|
||||||
@ -137,19 +161,34 @@ class InterActivePlayMessage {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
updateCurrentSongMessage (title, artist, imageURL, itemURL, ticksLength, playlistIndex, playlistLenth) {
|
updateCurrentSongMessage(
|
||||||
|
title,
|
||||||
|
artist,
|
||||||
|
imageURL,
|
||||||
|
itemURL,
|
||||||
|
ticksLength,
|
||||||
|
playlistIndex,
|
||||||
|
playlistLenth
|
||||||
|
) {
|
||||||
this.musicplayermessage.embeds[0].url = itemURL;
|
this.musicplayermessage.embeds[0].url = itemURL;
|
||||||
this.musicplayermessage.embeds[0].description = `${getMaxWidthString(title)}\nby\n${getMaxWidthString(artist)}`;
|
this.musicplayermessage.embeds[0].description = `\`\`${getMaxWidthString(
|
||||||
|
title
|
||||||
|
)}\`\` by \`\`${getMaxWidthString(artist)}\`\``;
|
||||||
this.musicplayermessage.embeds[0].thumbnail = { url: imageURL };
|
this.musicplayermessage.embeds[0].thumbnail = { url: imageURL };
|
||||||
const indexOfPlaylistMessage = this.musicplayermessage.embeds[0].fields.findIndex((element) => { return element.value === "Playlist"; });
|
const indexOfPlaylistMessage =
|
||||||
|
this.musicplayermessage.embeds[0].fields.findIndex((element) => {
|
||||||
|
return element.value === "Playlist";
|
||||||
|
});
|
||||||
if (indexOfPlaylistMessage === -1) {
|
if (indexOfPlaylistMessage === -1) {
|
||||||
this.musicplayermessage.embeds[0].fields.push({
|
this.musicplayermessage.embeds[0].fields.push({
|
||||||
name: `${playlistIndex} of ${playlistLenth}`,
|
name: `${playlistIndex} of ${playlistLenth}`,
|
||||||
value: "Playlist",
|
value: "Playlist",
|
||||||
inline: false
|
inline: false,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
this.musicplayermessage.embeds[0].fields[indexOfPlaylistMessage].name = `${playlistIndex} of ${playlistLenth}`;
|
this.musicplayermessage.embeds[0].fields[
|
||||||
|
indexOfPlaylistMessage
|
||||||
|
].name = `${playlistIndex} of ${playlistLenth}`;
|
||||||
}
|
}
|
||||||
this.ticksLength = ticksLength;
|
this.ticksLength = ticksLength;
|
||||||
|
|
||||||
@ -157,7 +196,7 @@ class InterActivePlayMessage {
|
|||||||
this.musicplayermessage.edit(this.musicplayermessage.embeds[0]);
|
this.musicplayermessage.edit(this.musicplayermessage.embeds[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
destroy () {
|
destroy() {
|
||||||
this.musicplayermessage.delete();
|
this.musicplayermessage.delete();
|
||||||
delete this;
|
delete this;
|
||||||
}
|
}
|
||||||
|
@ -2,14 +2,14 @@ const Discord = require("discord.js");
|
|||||||
|
|
||||||
var discordClient;
|
var discordClient;
|
||||||
|
|
||||||
function init () {
|
function init() {
|
||||||
discordClient = new Discord.Client();
|
discordClient = new Discord.Client();
|
||||||
}
|
}
|
||||||
function getDiscordClient () {
|
function getDiscordClient() {
|
||||||
return discordClient;
|
return discordClient;
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
getDiscordClient,
|
getDiscordClient,
|
||||||
init
|
init,
|
||||||
};
|
};
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
var audioDispatcher;
|
var audioDispatcher;
|
||||||
|
|
||||||
function setAudioDispatcher (par) {
|
function setAudioDispatcher(par) {
|
||||||
audioDispatcher = par;
|
audioDispatcher = par;
|
||||||
}
|
}
|
||||||
function getAudioDispatcher () {
|
function getAudioDispatcher() {
|
||||||
return audioDispatcher;
|
return audioDispatcher;
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
setAudioDispatcher,
|
setAudioDispatcher,
|
||||||
getAudioDispatcher
|
getAudioDispatcher,
|
||||||
};
|
};
|
||||||
|
37
src/index.js
37
src/index.js
@ -1,3 +1,5 @@
|
|||||||
|
const log = require("loglevel");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const CONFIG = require("../config.json");
|
const CONFIG = require("../config.json");
|
||||||
|
|
||||||
@ -6,10 +8,8 @@ try {
|
|||||||
const discordclientmanager = require("./discordclientmanager");
|
const discordclientmanager = require("./discordclientmanager");
|
||||||
discordclientmanager.init();
|
discordclientmanager.init();
|
||||||
const discordClient = discordclientmanager.getDiscordClient();
|
const discordClient = discordclientmanager.getDiscordClient();
|
||||||
const {
|
const { handleChannelMessage } = require("./messagehandler");
|
||||||
handleChannelMessage
|
|
||||||
} = require("./messagehandler");
|
|
||||||
const log = require("loglevel");
|
|
||||||
const prefix = require("loglevel-plugin-prefix");
|
const prefix = require("loglevel-plugin-prefix");
|
||||||
const chalk = require("chalk");
|
const chalk = require("chalk");
|
||||||
const colors = {
|
const colors = {
|
||||||
@ -17,7 +17,7 @@ try {
|
|||||||
DEBUG: chalk.cyan,
|
DEBUG: chalk.cyan,
|
||||||
INFO: chalk.blue,
|
INFO: chalk.blue,
|
||||||
WARN: chalk.yellow,
|
WARN: chalk.yellow,
|
||||||
ERROR: chalk.red
|
ERROR: chalk.red,
|
||||||
};
|
};
|
||||||
|
|
||||||
log.setLevel(CONFIG["log-level"]);
|
log.setLevel(CONFIG["log-level"]);
|
||||||
@ -26,28 +26,39 @@ try {
|
|||||||
log.enableAll();
|
log.enableAll();
|
||||||
|
|
||||||
prefix.apply(log, {
|
prefix.apply(log, {
|
||||||
format (level, name, timestamp) {
|
format(level, name, timestamp) {
|
||||||
return `${chalk.gray(`[${timestamp}]`)} ${colors[level.toUpperCase()](level)} ${chalk.green(`${name}:`)}`;
|
return `${chalk.gray(`[${timestamp}]`)} ${colors[level.toUpperCase()](
|
||||||
}
|
level
|
||||||
|
)} ${chalk.green(`${name}:`)}`;
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
prefix.apply(log.getLogger("critical"), {
|
prefix.apply(log.getLogger("critical"), {
|
||||||
format (level, name, timestamp) {
|
format(level, name, timestamp) {
|
||||||
return chalk.red.bold(`[${timestamp}] ${level} ${name}:`);
|
return chalk.red.bold(`[${timestamp}] ${level} ${name}:`);
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
jellyfinClientManager.init();
|
jellyfinClientManager.init();
|
||||||
// TODO Error Checking as the apiclients is inefficent
|
// TODO Error Checking as the apiclients is inefficent
|
||||||
jellyfinClientManager.getJellyfinClient().authenticateUserByName(CONFIG["jellyfin-username"], CONFIG["jellyfin-password"]).then((response) => {
|
jellyfinClientManager
|
||||||
jellyfinClientManager.getJellyfinClient().setAuthenticationInfo(response.AccessToken, response.SessionInfo.UserId);
|
.getJellyfinClient()
|
||||||
|
.authenticateUserByName(
|
||||||
|
CONFIG["jellyfin-username"],
|
||||||
|
CONFIG["jellyfin-password"]
|
||||||
|
)
|
||||||
|
.then((response) => {
|
||||||
|
jellyfinClientManager
|
||||||
|
.getJellyfinClient()
|
||||||
|
.setAuthenticationInfo(response.AccessToken, response.SessionInfo.UserId);
|
||||||
});
|
});
|
||||||
|
|
||||||
discordClient.on("message", message => {
|
discordClient.on("message", (message) => {
|
||||||
handleChannelMessage(message);
|
handleChannelMessage(message);
|
||||||
});
|
});
|
||||||
|
|
||||||
discordClient.login(CONFIG.token);
|
discordClient.login(CONFIG.token);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
log.error(error);
|
||||||
console.error(error);
|
console.error(error);
|
||||||
}
|
}
|
||||||
|
@ -5,14 +5,40 @@ var iapm;
|
|||||||
|
|
||||||
var updateInterval;
|
var updateInterval;
|
||||||
|
|
||||||
function init (message, title, artist, imageURL, itemURL, getProgress, onPrevious, onPausePlay, onStop, onNext, onRepeat, playlistLenth) {
|
function init(
|
||||||
|
message,
|
||||||
|
title,
|
||||||
|
artist,
|
||||||
|
imageURL,
|
||||||
|
itemURL,
|
||||||
|
getProgress,
|
||||||
|
onPrevious,
|
||||||
|
onPausePlay,
|
||||||
|
onStop,
|
||||||
|
onNext,
|
||||||
|
onRepeat,
|
||||||
|
playlistLenth
|
||||||
|
) {
|
||||||
if (typeof iapm !== "undefined") {
|
if (typeof iapm !== "undefined") {
|
||||||
destroy();
|
destroy();
|
||||||
}
|
}
|
||||||
iapm = new InterActivePlayMessage(message, title, artist, imageURL, itemURL, getProgress, onPrevious, onPausePlay, onStop, onNext, onRepeat, playlistLenth);
|
iapm = new InterActivePlayMessage(
|
||||||
|
message,
|
||||||
|
title,
|
||||||
|
artist,
|
||||||
|
imageURL,
|
||||||
|
itemURL,
|
||||||
|
getProgress,
|
||||||
|
onPrevious,
|
||||||
|
onPausePlay,
|
||||||
|
onStop,
|
||||||
|
onNext,
|
||||||
|
onRepeat,
|
||||||
|
playlistLenth
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function destroy () {
|
function destroy() {
|
||||||
if (typeof iapm !== "undefined") {
|
if (typeof iapm !== "undefined") {
|
||||||
iapm.destroy();
|
iapm.destroy();
|
||||||
iapm = undefined;
|
iapm = undefined;
|
||||||
@ -26,7 +52,7 @@ function destroy () {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function hasMessage () {
|
function hasMessage() {
|
||||||
if (typeof iapm === "undefined") {
|
if (typeof iapm === "undefined") {
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
@ -37,17 +63,36 @@ function hasMessage () {
|
|||||||
*
|
*
|
||||||
* @param {Function} callback function to retrieve current ticks
|
* @param {Function} callback function to retrieve current ticks
|
||||||
*/
|
*/
|
||||||
function startUpate (callback) {
|
function startUpate(callback) {
|
||||||
if (typeof CONFIG["interactive-seek-bar-update-intervall"] === "number" && CONFIG["interactive-seek-bar-update-intervall"] > 0) {
|
if (
|
||||||
|
typeof CONFIG["interactive-seek-bar-update-intervall"] === "number" &&
|
||||||
|
CONFIG["interactive-seek-bar-update-intervall"] > 0
|
||||||
|
) {
|
||||||
updateInterval = setInterval(() => {
|
updateInterval = setInterval(() => {
|
||||||
iapm.updateProgress(callback());
|
iapm.updateProgress(callback());
|
||||||
}, CONFIG["interactive-seek-bar-update-intervall"]);
|
}, CONFIG["interactive-seek-bar-update-intervall"]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateCurrentSongMessage (title, artist, imageURL, itemURL, ticksLength, playlistIndex, playlistLenth) {
|
function updateCurrentSongMessage(
|
||||||
|
title,
|
||||||
|
artist,
|
||||||
|
imageURL,
|
||||||
|
itemURL,
|
||||||
|
ticksLength,
|
||||||
|
playlistIndex,
|
||||||
|
playlistLenth
|
||||||
|
) {
|
||||||
if (typeof iapm !== "undefined") {
|
if (typeof iapm !== "undefined") {
|
||||||
iapm.updateCurrentSongMessage(title, artist, imageURL, itemURL, ticksLength, playlistIndex, playlistLenth);
|
iapm.updateCurrentSongMessage(
|
||||||
|
title,
|
||||||
|
artist,
|
||||||
|
imageURL,
|
||||||
|
itemURL,
|
||||||
|
ticksLength,
|
||||||
|
playlistIndex,
|
||||||
|
playlistLenth
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
throw Error("No Interactive Message Found");
|
throw Error("No Interactive Message Found");
|
||||||
}
|
}
|
||||||
@ -58,5 +103,5 @@ module.exports = {
|
|||||||
destroy,
|
destroy,
|
||||||
hasMessage,
|
hasMessage,
|
||||||
startUpate,
|
startUpate,
|
||||||
updateCurrentSongMessage
|
updateCurrentSongMessage,
|
||||||
};
|
};
|
||||||
|
@ -1,24 +1,29 @@
|
|||||||
|
|
||||||
const { ApiClient, Events } = require("jellyfin-apiclient");
|
const { ApiClient, Events } = require("jellyfin-apiclient");
|
||||||
const CONFIG = require("../config.json");
|
const CONFIG = require("../config.json");
|
||||||
const os = require("os");
|
const os = require("os");
|
||||||
|
|
||||||
var jellyfinClient;
|
var jellyfinClient;
|
||||||
|
|
||||||
function init () {
|
function init() {
|
||||||
jellyfinClient = new ApiClient(CONFIG["server-address"], CONFIG["jellyfin-app-name"], "0.0.1", os.hostname(), os.hostname());
|
jellyfinClient = new ApiClient(
|
||||||
|
CONFIG["server-address"],
|
||||||
|
CONFIG["jellyfin-app-name"],
|
||||||
|
"0.0.1",
|
||||||
|
os.hostname(),
|
||||||
|
os.hostname()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getJellyfinClient () {
|
function getJellyfinClient() {
|
||||||
return jellyfinClient;
|
return jellyfinClient;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getJellyfinEvents () {
|
function getJellyfinEvents() {
|
||||||
return Events;
|
return Events;
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
getJellyfinClient,
|
getJellyfinClient,
|
||||||
getJellyfinEvents,
|
getJellyfinEvents,
|
||||||
init
|
init,
|
||||||
};
|
};
|
||||||
|
@ -1,12 +1,7 @@
|
|||||||
const CONFIG = require("../config.json");
|
const CONFIG = require("../config.json");
|
||||||
const Discord = require("discord.js");
|
const Discord = require("discord.js");
|
||||||
const {
|
const { checkJellyfinItemIDRegex } = require("./util");
|
||||||
checkJellyfinItemIDRegex
|
const { hmsToSeconds, getDiscordEmbedError } = require("./util");
|
||||||
} = require("./util");
|
|
||||||
const {
|
|
||||||
hmsToSeconds,
|
|
||||||
getDiscordEmbedError
|
|
||||||
} = require("./util");
|
|
||||||
|
|
||||||
const discordclientmanager = require("./discordclientmanager");
|
const discordclientmanager = require("./discordclientmanager");
|
||||||
const jellyfinClientManager = require("./jellyfinclientmanager");
|
const jellyfinClientManager = require("./jellyfinclientmanager");
|
||||||
@ -17,10 +12,12 @@ const discordClient = discordclientmanager.getDiscordClient();
|
|||||||
var isSummendByPlay = false;
|
var isSummendByPlay = false;
|
||||||
|
|
||||||
// random Color of the Jellyfin Logo Gradient
|
// random Color of the Jellyfin Logo Gradient
|
||||||
function getRandomDiscordColor () {
|
function getRandomDiscordColor() {
|
||||||
const random = Math.random();
|
const random = Math.random();
|
||||||
function randomNumber (b, a) {
|
function randomNumber(b, a) {
|
||||||
return Math.floor(random * Math.pow(Math.pow((b - a), 2), 1 / 2)) + (b > a ? a : b);
|
return (
|
||||||
|
Math.floor(random * Math.pow(Math.pow(b - a, 2), 1 / 2)) + (b > a ? a : b)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const GRANDIENT_START = "#AA5CC3";
|
const GRANDIENT_START = "#AA5CC3";
|
||||||
@ -40,14 +37,21 @@ function getRandomDiscordColor () {
|
|||||||
gE = parseInt(gE, 16);
|
gE = parseInt(gE, 16);
|
||||||
bE = parseInt(bE, 16);
|
bE = parseInt(bE, 16);
|
||||||
|
|
||||||
return ("#" + ("00" + (randomNumber(rS, rE)).toString(16)).substr(-2) + ("00" + (randomNumber(gS, gE)).toString(16)).substr(-2) + ("00" + (randomNumber(bS, bE)).toString(16)).substr(-2));
|
return (
|
||||||
|
"#" +
|
||||||
|
("00" + randomNumber(rS, rE).toString(16)).substr(-2) +
|
||||||
|
("00" + randomNumber(gS, gE).toString(16)).substr(-2) +
|
||||||
|
("00" + randomNumber(bS, bE).toString(16)).substr(-2)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Song Search, return the song itemID
|
// Song Search, return the song itemID
|
||||||
async function searchForItemID (searchString) {
|
async function searchForItemID(searchString) {
|
||||||
const response = await jellyfinClientManager.getJellyfinClient().getSearchHints({
|
const response = await jellyfinClientManager
|
||||||
|
.getJellyfinClient()
|
||||||
|
.getSearchHints({
|
||||||
searchTerm: searchString,
|
searchTerm: searchString,
|
||||||
includeItemTypes: "Audio,MusicAlbum,Playlist"
|
includeItemTypes: "Audio,MusicAlbum,Playlist",
|
||||||
});
|
});
|
||||||
|
|
||||||
if (response.TotalRecordCount < 1) {
|
if (response.TotalRecordCount < 1) {
|
||||||
@ -58,9 +62,15 @@ async function searchForItemID (searchString) {
|
|||||||
return [response.SearchHints[0].ItemId];
|
return [response.SearchHints[0].ItemId];
|
||||||
case "Playlist":
|
case "Playlist":
|
||||||
case "MusicAlbum": {
|
case "MusicAlbum": {
|
||||||
const resp = await jellyfinClientManager.getJellyfinClient().getItems(jellyfinClientManager.getJellyfinClient().getCurrentUserId(), { sortBy: "SortName", sortOrder: "Ascending", parentId: response.SearchHints[0].ItemId });
|
const resp = await jellyfinClientManager
|
||||||
|
.getJellyfinClient()
|
||||||
|
.getItems(jellyfinClientManager.getJellyfinClient().getCurrentUserId(), {
|
||||||
|
sortBy: "SortName",
|
||||||
|
sortOrder: "Ascending",
|
||||||
|
parentId: response.SearchHints[0].ItemId,
|
||||||
|
});
|
||||||
const itemArray = [];
|
const itemArray = [];
|
||||||
resp.Items.forEach(element => {
|
resp.Items.forEach((element) => {
|
||||||
itemArray.push(element.Id);
|
itemArray.push(element.Id);
|
||||||
});
|
});
|
||||||
return itemArray;
|
return itemArray;
|
||||||
@ -69,11 +79,11 @@ async function searchForItemID (searchString) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function summon (voiceChannel) {
|
function summon(voiceChannel) {
|
||||||
voiceChannel.join();
|
voiceChannel.join();
|
||||||
}
|
}
|
||||||
|
|
||||||
function summonMessage (message) {
|
function summonMessage(message) {
|
||||||
if (!message.member.voice.channel) {
|
if (!message.member.voice.channel) {
|
||||||
message.reply("please join a voice channel to summon me!");
|
message.reply("please join a voice channel to summon me!");
|
||||||
} else if (message.channel.type === "dm") {
|
} else if (message.channel.type === "dm") {
|
||||||
@ -93,8 +103,11 @@ function summonMessage (message) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function playThis (message) {
|
async function playThis(message) {
|
||||||
const indexOfItemID = message.content.indexOf(CONFIG["discord-prefix"] + "play") + (CONFIG["discord-prefix"] + "play").length + 1;
|
const indexOfItemID =
|
||||||
|
message.content.indexOf(CONFIG["discord-prefix"] + "play") +
|
||||||
|
(CONFIG["discord-prefix"] + "play").length +
|
||||||
|
1;
|
||||||
const argument = message.content.slice(indexOfItemID);
|
const argument = message.content.slice(indexOfItemID);
|
||||||
let items;
|
let items;
|
||||||
// check if play command was used with itemID
|
// check if play command was used with itemID
|
||||||
@ -107,17 +120,30 @@ async function playThis (message) {
|
|||||||
} catch (e) {
|
} catch (e) {
|
||||||
const noSong = getDiscordEmbedError(e);
|
const noSong = getDiscordEmbedError(e);
|
||||||
message.channel.send(noSong);
|
message.channel.send(noSong);
|
||||||
playbackmanager.stop(isSummendByPlay ? discordClient.user.client.voice.connections.first() : undefined);
|
playbackmanager.stop(
|
||||||
|
isSummendByPlay
|
||||||
|
? discordClient.user.client.voice.connections.first()
|
||||||
|
: undefined,
|
||||||
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
playbackmanager.startPlaying(discordClient.user.client.voice.connections.first(), items, 0, 0, isSummendByPlay);
|
playbackmanager.startPlaying(
|
||||||
|
discordClient.user.client.voice.connections.first(),
|
||||||
|
items,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
isSummendByPlay,
|
||||||
|
);
|
||||||
playbackmanager.spawnPlayMessage(message);
|
playbackmanager.spawnPlayMessage(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function addThis (message) {
|
async function addThis(message) {
|
||||||
const indexOfItemID = message.content.indexOf(CONFIG["discord-prefix"] + "add") + (CONFIG["discord-prefix"] + "add").length + 1;
|
const indexOfItemID =
|
||||||
|
message.content.indexOf(CONFIG["discord-prefix"] + "add") +
|
||||||
|
(CONFIG["discord-prefix"] + "add").length +
|
||||||
|
1;
|
||||||
const argument = message.content.slice(indexOfItemID);
|
const argument = message.content.slice(indexOfItemID);
|
||||||
let items;
|
let items;
|
||||||
// check if play command was used with itemID
|
// check if play command was used with itemID
|
||||||
@ -137,7 +163,7 @@ async function addThis (message) {
|
|||||||
playbackmanager.addTracks(items);
|
playbackmanager.addTracks(items);
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleChannelMessage (message) {
|
function handleChannelMessage(message) {
|
||||||
getRandomDiscordColor();
|
getRandomDiscordColor();
|
||||||
|
|
||||||
if (message.content.startsWith(CONFIG["discord-prefix"] + "summon")) {
|
if (message.content.startsWith(CONFIG["discord-prefix"] + "summon")) {
|
||||||
@ -146,7 +172,9 @@ function handleChannelMessage (message) {
|
|||||||
websocketHanler.openSocket();
|
websocketHanler.openSocket();
|
||||||
|
|
||||||
summonMessage(message);
|
summonMessage(message);
|
||||||
} else if (message.content.startsWith(CONFIG["discord-prefix"] + "disconnect")) {
|
} else if (
|
||||||
|
message.content.startsWith(CONFIG["discord-prefix"] + "disconnect")
|
||||||
|
) {
|
||||||
playbackmanager.stop();
|
playbackmanager.stop();
|
||||||
jellyfinClientManager.getJellyfinClient().closeWebSocket();
|
jellyfinClientManager.getJellyfinClient().closeWebSocket();
|
||||||
discordClient.user.client.voice.connections.forEach((element) => {
|
discordClient.user.client.voice.connections.forEach((element) => {
|
||||||
@ -160,7 +188,10 @@ function handleChannelMessage (message) {
|
|||||||
.setTimestamp()
|
.setTimestamp()
|
||||||
.setDescription("<:wave:757938481585586226> " + desc);
|
.setDescription("<:wave:757938481585586226> " + desc);
|
||||||
message.channel.send(vcJoin);
|
message.channel.send(vcJoin);
|
||||||
} else if ((message.content.startsWith(CONFIG["discord-prefix"] + "pause")) || (message.content.startsWith(CONFIG["discord-prefix"] + "resume"))) {
|
} else if (
|
||||||
|
message.content.startsWith(CONFIG["discord-prefix"] + "pause") ||
|
||||||
|
message.content.startsWith(CONFIG["discord-prefix"] + "resume")
|
||||||
|
) {
|
||||||
try {
|
try {
|
||||||
playbackmanager.playPause();
|
playbackmanager.playPause();
|
||||||
const noPlay = new Discord.MessageEmbed()
|
const noPlay = new Discord.MessageEmbed()
|
||||||
@ -188,7 +219,10 @@ function handleChannelMessage (message) {
|
|||||||
playbackmanager.stop();
|
playbackmanager.stop();
|
||||||
}
|
}
|
||||||
} else if (message.content.startsWith(CONFIG["discord-prefix"] + "seek")) {
|
} else if (message.content.startsWith(CONFIG["discord-prefix"] + "seek")) {
|
||||||
const indexOfArgument = message.content.indexOf(CONFIG["discord-prefix"] + "seek") + (CONFIG["discord-prefix"] + "seek").length + 1;
|
const indexOfArgument =
|
||||||
|
message.content.indexOf(CONFIG["discord-prefix"] + "seek") +
|
||||||
|
(CONFIG["discord-prefix"] + "seek").length +
|
||||||
|
1;
|
||||||
const argument = message.content.slice(indexOfArgument);
|
const argument = message.content.slice(indexOfArgument);
|
||||||
try {
|
try {
|
||||||
playbackmanager.seek(hmsToSeconds(argument) * 10000000);
|
playbackmanager.seek(hmsToSeconds(argument) * 10000000);
|
||||||
@ -216,43 +250,59 @@ function handleChannelMessage (message) {
|
|||||||
/* eslint-disable quotes */
|
/* eslint-disable quotes */
|
||||||
const reply = new Discord.MessageEmbed()
|
const reply = new Discord.MessageEmbed()
|
||||||
.setColor(getRandomDiscordColor())
|
.setColor(getRandomDiscordColor())
|
||||||
.setTitle("<:musical_note:757938541123862638> " + "Jellyfin Discord Music Bot" + " <:musical_note:757938541123862638> ")
|
.setTitle(
|
||||||
.addFields({
|
"<:musical_note:757938541123862638> " +
|
||||||
|
"Jellyfin Discord Music Bot" +
|
||||||
|
" <:musical_note:757938541123862638> ",
|
||||||
|
)
|
||||||
|
.addFields(
|
||||||
|
{
|
||||||
name: `${CONFIG["discord-prefix"]}summon`,
|
name: `${CONFIG["discord-prefix"]}summon`,
|
||||||
value: "Join the channel the author of the message"
|
value: "Join the channel the author of the message",
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
name: `${CONFIG["discord-prefix"]}disconnect`,
|
name: `${CONFIG["discord-prefix"]}disconnect`,
|
||||||
value: "Disconnect from all current Voice Channels"
|
value: "Disconnect from all current Voice Channels",
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
name: `${CONFIG["discord-prefix"]}play`,
|
name: `${CONFIG["discord-prefix"]}play`,
|
||||||
value: "Play the following item"
|
value: "Play the following item",
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
name: `${CONFIG["discord-prefix"]}add`,
|
name: `${CONFIG["discord-prefix"]}add`,
|
||||||
value: "Add the following item to the current playlist"
|
value: "Add the following item to the current playlist",
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
name: `${CONFIG["discord-prefix"]}pause/resume`,
|
name: `${CONFIG["discord-prefix"]}pause/resume`,
|
||||||
value: "Pause/Resume audio"
|
value: "Pause/Resume audio",
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
name: `${CONFIG["discord-prefix"]}seek`,
|
name: `${CONFIG["discord-prefix"]}seek`,
|
||||||
value: "Where to Seek to in seconds or MM:SS"
|
value: "Where to Seek to in seconds or MM:SS",
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
name: `${CONFIG["discord-prefix"]}skip`,
|
name: `${CONFIG["discord-prefix"]}skip`,
|
||||||
value: "Skip this Song"
|
value: "Skip this Song",
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
name: `${CONFIG["discord-prefix"]}spawn`,
|
name: `${CONFIG["discord-prefix"]}spawn`,
|
||||||
value: "Spawns an Interactive Play Controller"
|
value: "Spawns an Interactive Play Controller",
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
name: `${CONFIG["discord-prefix"]}help`,
|
name: `${CONFIG["discord-prefix"]}help`,
|
||||||
value: "Display this help message"
|
value: "Display this help message",
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
name: `GitHub`,
|
name: `GitHub`,
|
||||||
value: "Find the code for this bot at: https://github.com/KGT1/jellyfin-discord-music-bot"
|
value:
|
||||||
});
|
"Find the code for this bot at: https://github.com/KGT1/jellyfin-discord-music-bot",
|
||||||
|
},
|
||||||
|
);
|
||||||
message.channel.send(reply);
|
message.channel.send(reply);
|
||||||
/* eslint-enable quotes */
|
/* eslint-enable quotes */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
handleChannelMessage
|
handleChannelMessage,
|
||||||
};
|
};
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
const interactivemsghandler = require("./interactivemsghandler");
|
const interactivemsghandler = require("./interactivemsghandler");
|
||||||
const CONFIG = require("../config.json");
|
const CONFIG = require("../config.json");
|
||||||
const discordclientmanager = require("./discordclientmanager");
|
const discordclientmanager = require("./discordclientmanager");
|
||||||
@ -6,11 +5,9 @@ const log = require("loglevel");
|
|||||||
|
|
||||||
const {
|
const {
|
||||||
getAudioDispatcher,
|
getAudioDispatcher,
|
||||||
setAudioDispatcher
|
setAudioDispatcher,
|
||||||
} = require("./dispachermanager");
|
} = require("./dispachermanager");
|
||||||
const {
|
const { ticksToSeconds } = require("./util");
|
||||||
ticksToSeconds
|
|
||||||
} = require("./util");
|
|
||||||
|
|
||||||
// this whole thing should be a class but its probably too late now.
|
// this whole thing should be a class but its probably too late now.
|
||||||
|
|
||||||
@ -23,42 +20,77 @@ var _seek;
|
|||||||
|
|
||||||
const jellyfinClientManager = require("./jellyfinclientmanager");
|
const jellyfinClientManager = require("./jellyfinclientmanager");
|
||||||
|
|
||||||
function streamURLbuilder (itemID, bitrate) {
|
function streamURLbuilder(itemID, bitrate) {
|
||||||
// so the server transcodes. Seems appropriate as it has the source file.(doesnt yet work i dont know why)
|
// so the server transcodes. Seems appropriate as it has the source file.(doesnt yet work i dont know why)
|
||||||
const supportedCodecs = "opus";
|
const supportedCodecs = "opus";
|
||||||
const supportedContainers = "ogg,opus";
|
const supportedContainers = "ogg,opus";
|
||||||
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`;
|
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 = discordclientmanager.getDiscordClient().user.client.voice.connections.first(), itemIDPlaylist = currentPlayingPlaylist, playlistIndex = currentPlayingPlaylistIndex, seekTo, disconnectOnFinish = _disconnectOnFinish) {
|
function startPlaying(
|
||||||
log.debug("start playing ", playlistIndex, ". of list: ", itemIDPlaylist, " in a voiceconnection?: ", typeof voiceconnection !== "undefined");
|
voiceconnection = discordclientmanager
|
||||||
|
.getDiscordClient()
|
||||||
|
.user.client.voice.connections.first(),
|
||||||
|
itemIDPlaylist = currentPlayingPlaylist,
|
||||||
|
playlistIndex = currentPlayingPlaylistIndex,
|
||||||
|
seekTo,
|
||||||
|
disconnectOnFinish = _disconnectOnFinish
|
||||||
|
) {
|
||||||
|
log.debug(
|
||||||
|
"start playing ",
|
||||||
|
playlistIndex,
|
||||||
|
". of list: ",
|
||||||
|
itemIDPlaylist,
|
||||||
|
" in a voiceconnection?: ",
|
||||||
|
typeof voiceconnection !== "undefined"
|
||||||
|
);
|
||||||
isPaused = false;
|
isPaused = false;
|
||||||
currentPlayingPlaylist = itemIDPlaylist;
|
currentPlayingPlaylist = itemIDPlaylist;
|
||||||
currentPlayingPlaylistIndex = playlistIndex;
|
currentPlayingPlaylistIndex = playlistIndex;
|
||||||
_disconnectOnFinish = disconnectOnFinish;
|
_disconnectOnFinish = disconnectOnFinish;
|
||||||
_seek = seekTo * 1000;
|
_seek = seekTo * 1000;
|
||||||
updatePlayMessage();
|
updatePlayMessage();
|
||||||
async function playasync () {
|
async function playasync() {
|
||||||
const url = streamURLbuilder(itemIDPlaylist[playlistIndex], voiceconnection.channel.bitrate);
|
const url = streamURLbuilder(
|
||||||
setAudioDispatcher(voiceconnection.play(url, {
|
itemIDPlaylist[playlistIndex],
|
||||||
seek: seekTo
|
voiceconnection.channel.bitrate
|
||||||
}));
|
);
|
||||||
|
setAudioDispatcher(
|
||||||
|
voiceconnection.play(url, {
|
||||||
|
seek: seekTo,
|
||||||
|
})
|
||||||
|
);
|
||||||
if (seekTo) {
|
if (seekTo) {
|
||||||
jellyfinClientManager.getJellyfinClient().reportPlaybackProgress(getProgressPayload());
|
jellyfinClientManager
|
||||||
|
.getJellyfinClient()
|
||||||
|
.reportPlaybackProgress(getProgressPayload());
|
||||||
} else {
|
} else {
|
||||||
jellyfinClientManager.getJellyfinClient().reportPlaybackStart({
|
jellyfinClientManager.getJellyfinClient().reportPlaybackStart({
|
||||||
userID: `${jellyfinClientManager.getJellyfinClient().getCurrentUserId()}`,
|
userID: `${jellyfinClientManager.getJellyfinClient().getCurrentUserId()}`,
|
||||||
itemID: `${itemIDPlaylist[playlistIndex]}`,
|
itemID: `${itemIDPlaylist[playlistIndex]}`,
|
||||||
canSeek: true,
|
canSeek: true,
|
||||||
playSessionId: getPlaySessionId(),
|
playSessionId: getPlaySessionId(),
|
||||||
playMethod: getPlayMethod()
|
playMethod: getPlayMethod(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
getAudioDispatcher().on("finish", () => {
|
getAudioDispatcher().on("finish", () => {
|
||||||
if (isRepeat) {
|
if (isRepeat) {
|
||||||
log.debug("repeat and sending following payload as reportPlaybackStopped to the server: ", getStopPayload());
|
log.debug(
|
||||||
jellyfinClientManager.getJellyfinClient().reportPlaybackStopped(getStopPayload());
|
"repeat and sending following payload as reportPlaybackStopped to the server: ",
|
||||||
|
getStopPayload()
|
||||||
|
);
|
||||||
|
jellyfinClientManager
|
||||||
|
.getJellyfinClient()
|
||||||
|
.reportPlaybackStopped(getStopPayload());
|
||||||
startPlaying(voiceconnection, undefined, currentPlayingPlaylistIndex, 0);
|
startPlaying(voiceconnection, undefined, currentPlayingPlaylistIndex, 0);
|
||||||
} else {
|
} else {
|
||||||
if (currentPlayingPlaylist.length < playlistIndex) {
|
if (currentPlayingPlaylist.length < playlistIndex) {
|
||||||
@ -68,9 +100,19 @@ function startPlaying (voiceconnection = discordclientmanager.getDiscordClient()
|
|||||||
stop(undefined, currentPlayingPlaylist[playlistIndex - 1]);
|
stop(undefined, currentPlayingPlaylist[playlistIndex - 1]);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
log.debug("repeat and sending following payload as reportPlaybackStopped to the server: ", getStopPayload());
|
log.debug(
|
||||||
jellyfinClientManager.getJellyfinClient().reportPlaybackStopped(getStopPayload());
|
"repeat and sending following payload as reportPlaybackStopped to the server: ",
|
||||||
startPlaying(voiceconnection, undefined, currentPlayingPlaylistIndex + 1, 0);
|
getStopPayload()
|
||||||
|
);
|
||||||
|
jellyfinClientManager
|
||||||
|
.getJellyfinClient()
|
||||||
|
.reportPlaybackStopped(getStopPayload());
|
||||||
|
startPlaying(
|
||||||
|
voiceconnection,
|
||||||
|
undefined,
|
||||||
|
currentPlayingPlaylistIndex + 1,
|
||||||
|
0
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -80,20 +122,44 @@ function startPlaying (voiceconnection = discordclientmanager.getDiscordClient()
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async function spawnPlayMessage (message) {
|
async function spawnPlayMessage(message) {
|
||||||
log.debug("spawned Play Message?: ", typeof message !== "undefined");
|
log.debug("spawned Play Message?: ", typeof message !== "undefined");
|
||||||
const itemIdDetails = await jellyfinClientManager.getJellyfinClient().getItem(jellyfinClientManager.getJellyfinClient().getCurrentUserId(), getItemId());
|
const itemIdDetails = await jellyfinClientManager
|
||||||
const imageURL = await jellyfinClientManager.getJellyfinClient().getImageUrl(itemIdDetails.AlbumId || getItemId(), { type: "Primary" });
|
.getJellyfinClient()
|
||||||
|
.getItem(
|
||||||
|
jellyfinClientManager.getJellyfinClient().getCurrentUserId(),
|
||||||
|
getItemId()
|
||||||
|
);
|
||||||
|
const imageURL = await jellyfinClientManager
|
||||||
|
.getJellyfinClient()
|
||||||
|
.getImageUrl(itemIdDetails.AlbumId || getItemId(), { type: "Primary" });
|
||||||
try {
|
try {
|
||||||
interactivemsghandler.init(message, itemIdDetails.Name, itemIdDetails.Artists[0] || "VA", imageURL,
|
interactivemsghandler.init(
|
||||||
`${jellyfinClientManager.getJellyfinClient().serverAddress()}/web/index.html#!/details?id=${itemIdDetails.AlbumId}`,
|
message,
|
||||||
|
itemIdDetails.Name,
|
||||||
|
itemIdDetails.Artists[0] || "VA",
|
||||||
|
imageURL,
|
||||||
|
`${jellyfinClientManager
|
||||||
|
.getJellyfinClient()
|
||||||
|
.serverAddress()}/web/index.html#!/details?id=${itemIdDetails.AlbumId}`,
|
||||||
itemIdDetails.RunTimeTicks,
|
itemIdDetails.RunTimeTicks,
|
||||||
((ticksToSeconds(getPostitionTicks()) > 10) ? previousTrack : seek),
|
ticksToSeconds(getPostitionTicks()) > 10 ? previousTrack : seek,
|
||||||
playPause,
|
playPause,
|
||||||
() => { stop(_disconnectOnFinish ? discordclientmanager.getDiscordClient().user.client.voice.connections.first() : undefined); },
|
() => {
|
||||||
|
stop(
|
||||||
|
_disconnectOnFinish
|
||||||
|
? discordclientmanager
|
||||||
|
.getDiscordClient()
|
||||||
|
.user.client.voice.connections.first()
|
||||||
|
: undefined
|
||||||
|
);
|
||||||
|
},
|
||||||
nextTrack,
|
nextTrack,
|
||||||
() => { setIsRepeat(!isRepeat); },
|
() => {
|
||||||
currentPlayingPlaylist.length);
|
setIsRepeat(!isRepeat);
|
||||||
|
},
|
||||||
|
currentPlayingPlaylist.length
|
||||||
|
);
|
||||||
if (typeof CONFIG["interactive-seek-bar-update-intervall"] === "number") {
|
if (typeof CONFIG["interactive-seek-bar-update-intervall"] === "number") {
|
||||||
interactivemsghandler.startUpate(getPostitionTicks);
|
interactivemsghandler.startUpate(getPostitionTicks);
|
||||||
}
|
}
|
||||||
@ -102,23 +168,52 @@ async function spawnPlayMessage (message) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function updatePlayMessage () {
|
async function updatePlayMessage() {
|
||||||
if (getItemId() !== undefined) {
|
if (getItemId() !== undefined) {
|
||||||
const itemIdDetails = await jellyfinClientManager.getJellyfinClient().getItem(jellyfinClientManager.getJellyfinClient().getCurrentUserId(), getItemId());
|
const itemIdDetails = await jellyfinClientManager
|
||||||
const imageURL = await jellyfinClientManager.getJellyfinClient().getImageUrl(itemIdDetails.AlbumId || getItemId(), { type: "Primary" });
|
.getJellyfinClient()
|
||||||
interactivemsghandler.updateCurrentSongMessage(itemIdDetails.Name, itemIdDetails.Artists[0] || "VA", imageURL,
|
.getItem(
|
||||||
`${jellyfinClientManager.getJellyfinClient().serverAddress()}/web/index.html#!/details?id=${itemIdDetails.AlbumId}`, itemIdDetails.RunTimeTicks, currentPlayingPlaylistIndex + 1, currentPlayingPlaylist.length);
|
jellyfinClientManager.getJellyfinClient().getCurrentUserId(),
|
||||||
|
getItemId()
|
||||||
|
);
|
||||||
|
const imageURL = await jellyfinClientManager
|
||||||
|
.getJellyfinClient()
|
||||||
|
.getImageUrl(itemIdDetails.AlbumId || getItemId(), { type: "Primary" });
|
||||||
|
|
||||||
|
try {
|
||||||
|
interactivemsghandler.updateCurrentSongMessage(
|
||||||
|
itemIdDetails.Name,
|
||||||
|
itemIdDetails.Artists[0] || "VA",
|
||||||
|
imageURL,
|
||||||
|
`${jellyfinClientManager
|
||||||
|
.getJellyfinClient()
|
||||||
|
.serverAddress()}/web/index.html#!/details?id=${itemIdDetails.AlbumId}`,
|
||||||
|
itemIdDetails.RunTimeTicks,
|
||||||
|
currentPlayingPlaylistIndex + 1,
|
||||||
|
currentPlayingPlaylist.length
|
||||||
|
);
|
||||||
|
} catch (exception) {
|
||||||
|
console.error(exception);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {Number} toSeek - where to seek in ticks
|
* @param {Number} toSeek - where to seek in ticks
|
||||||
*/
|
*/
|
||||||
function seek (toSeek = 0) {
|
function seek(toSeek = 0) {
|
||||||
log.debug("seek to: ", toSeek);
|
log.debug("seek to: ", toSeek);
|
||||||
if (getAudioDispatcher()) {
|
if (getAudioDispatcher()) {
|
||||||
startPlaying(undefined, undefined, undefined, ticksToSeconds(toSeek), _disconnectOnFinish);
|
startPlaying(
|
||||||
jellyfinClientManager.getJellyfinClient().reportPlaybackProgress(getProgressPayload());
|
undefined,
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
ticksToSeconds(toSeek),
|
||||||
|
_disconnectOnFinish
|
||||||
|
);
|
||||||
|
jellyfinClientManager
|
||||||
|
.getJellyfinClient()
|
||||||
|
.reportPlaybackProgress(getProgressPayload());
|
||||||
} else {
|
} else {
|
||||||
throw Error("No Song Playing");
|
throw Error("No Song Playing");
|
||||||
}
|
}
|
||||||
@ -127,46 +222,74 @@ function seek (toSeek = 0) {
|
|||||||
*
|
*
|
||||||
* @param {Array} itemID - array of itemIDs to be added
|
* @param {Array} itemID - array of itemIDs to be added
|
||||||
*/
|
*/
|
||||||
function addTracks (itemID) {
|
function addTracks(itemID) {
|
||||||
log.debug("added track: ", itemID);
|
log.debug("added track: ", itemID);
|
||||||
currentPlayingPlaylist = currentPlayingPlaylist.concat(itemID);
|
currentPlayingPlaylist = currentPlayingPlaylist.concat(itemID);
|
||||||
}
|
}
|
||||||
|
|
||||||
function nextTrack () {
|
function nextTrack() {
|
||||||
log.debug("nextTrack");
|
log.debug("nextTrack");
|
||||||
if (!(currentPlayingPlaylist)) {
|
if (!currentPlayingPlaylist) {
|
||||||
throw Error("There is currently nothing playing");
|
throw Error("There is currently nothing playing");
|
||||||
} else if (currentPlayingPlaylistIndex + 1 >= currentPlayingPlaylist.length) {
|
} else if (currentPlayingPlaylistIndex + 1 >= currentPlayingPlaylist.length) {
|
||||||
throw Error("This is the Last song");
|
throw Error("This is the Last song");
|
||||||
}
|
}
|
||||||
|
|
||||||
log.debug("sending following payload as reportPlaybackStopped to the server: ", getStopPayload());
|
log.debug(
|
||||||
jellyfinClientManager.getJellyfinClient().reportPlaybackStopped(getStopPayload());
|
"sending following payload as reportPlaybackStopped to the server: ",
|
||||||
|
getStopPayload()
|
||||||
|
);
|
||||||
|
jellyfinClientManager
|
||||||
|
.getJellyfinClient()
|
||||||
|
.reportPlaybackStopped(getStopPayload());
|
||||||
|
|
||||||
startPlaying(undefined, undefined, currentPlayingPlaylistIndex + 1, 0, _disconnectOnFinish);
|
startPlaying(
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
currentPlayingPlaylistIndex + 1,
|
||||||
|
0,
|
||||||
|
_disconnectOnFinish
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function previousTrack () {
|
function previousTrack() {
|
||||||
log.debug("previousTrack");
|
log.debug("previousTrack");
|
||||||
if (ticksToSeconds(getPostitionTicks()) < 10) {
|
if (ticksToSeconds(getPostitionTicks()) < 10) {
|
||||||
if (!(currentPlayingPlaylist)) {
|
if (!currentPlayingPlaylist) {
|
||||||
throw Error("There is currently nothing playing");
|
throw Error("There is currently nothing playing");
|
||||||
} else if (currentPlayingPlaylistIndex - 1 < 0) {
|
} else if (currentPlayingPlaylistIndex - 1 < 0) {
|
||||||
startPlaying(undefined, undefined, currentPlayingPlaylistIndex, 0, _disconnectOnFinish);
|
startPlaying(
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
currentPlayingPlaylistIndex,
|
||||||
|
0,
|
||||||
|
_disconnectOnFinish
|
||||||
|
);
|
||||||
throw Error("This is the First song");
|
throw Error("This is the First song");
|
||||||
}
|
}
|
||||||
|
|
||||||
log.debug("sending following payload as reportPlaybackStopped to the server: ", getStopPayload());
|
log.debug(
|
||||||
jellyfinClientManager.getJellyfinClient().reportPlaybackStopped(getStopPayload());
|
"sending following payload as reportPlaybackStopped to the server: ",
|
||||||
|
getStopPayload()
|
||||||
|
);
|
||||||
|
jellyfinClientManager
|
||||||
|
.getJellyfinClient()
|
||||||
|
.reportPlaybackStopped(getStopPayload());
|
||||||
|
|
||||||
startPlaying(undefined, undefined, currentPlayingPlaylistIndex - 1, 0, _disconnectOnFinish);
|
startPlaying(
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
currentPlayingPlaylistIndex - 1,
|
||||||
|
0,
|
||||||
|
_disconnectOnFinish
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {Object=} disconnectVoiceConnection - Optional The voice Connection do disconnect from
|
* @param {Object=} disconnectVoiceConnection - Optional The voice Connection do disconnect from
|
||||||
*/
|
*/
|
||||||
function stop (disconnectVoiceConnection, itemId = getItemId()) {
|
function stop(disconnectVoiceConnection, itemId = getItemId()) {
|
||||||
isPaused = true;
|
isPaused = true;
|
||||||
if (interactivemsghandler.hasMessage()) {
|
if (interactivemsghandler.hasMessage()) {
|
||||||
interactivemsghandler.destroy();
|
interactivemsghandler.destroy();
|
||||||
@ -174,8 +297,13 @@ function stop (disconnectVoiceConnection, itemId = getItemId()) {
|
|||||||
if (disconnectVoiceConnection) {
|
if (disconnectVoiceConnection) {
|
||||||
disconnectVoiceConnection.disconnect();
|
disconnectVoiceConnection.disconnect();
|
||||||
}
|
}
|
||||||
log.debug("stop playback and send following payload as reportPlaybackStopped to the server: ", getStopPayload());
|
log.debug(
|
||||||
jellyfinClientManager.getJellyfinClient().reportPlaybackStopped(getStopPayload());
|
"stop playback and send following payload as reportPlaybackStopped to the server: ",
|
||||||
|
getStopPayload()
|
||||||
|
);
|
||||||
|
jellyfinClientManager
|
||||||
|
.getJellyfinClient()
|
||||||
|
.reportPlaybackStopped(getStopPayload());
|
||||||
if (getAudioDispatcher()) {
|
if (getAudioDispatcher()) {
|
||||||
try {
|
try {
|
||||||
getAudioDispatcher().destroy();
|
getAudioDispatcher().destroy();
|
||||||
@ -186,22 +314,26 @@ function stop (disconnectVoiceConnection, itemId = getItemId()) {
|
|||||||
setAudioDispatcher(undefined);
|
setAudioDispatcher(undefined);
|
||||||
}
|
}
|
||||||
|
|
||||||
function pause () {
|
function pause() {
|
||||||
log.debug("pause");
|
log.debug("pause");
|
||||||
isPaused = true;
|
isPaused = true;
|
||||||
jellyfinClientManager.getJellyfinClient().reportPlaybackProgress(getProgressPayload());
|
jellyfinClientManager
|
||||||
|
.getJellyfinClient()
|
||||||
|
.reportPlaybackProgress(getProgressPayload());
|
||||||
getAudioDispatcher().pause(true);
|
getAudioDispatcher().pause(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
function resume () {
|
function resume() {
|
||||||
log.debug("resume");
|
log.debug("resume");
|
||||||
isPaused = false;
|
isPaused = false;
|
||||||
jellyfinClientManager.getJellyfinClient().reportPlaybackProgress(getProgressPayload());
|
jellyfinClientManager
|
||||||
|
.getJellyfinClient()
|
||||||
|
.reportPlaybackProgress(getProgressPayload());
|
||||||
getAudioDispatcher().resume();
|
getAudioDispatcher().resume();
|
||||||
}
|
}
|
||||||
|
|
||||||
function playPause () {
|
function playPause() {
|
||||||
if (!(getAudioDispatcher())) {
|
if (!getAudioDispatcher()) {
|
||||||
throw Error("There is nothing Playing right now!");
|
throw Error("There is nothing Playing right now!");
|
||||||
}
|
}
|
||||||
if (getAudioDispatcher().paused) {
|
if (getAudioDispatcher().paused) {
|
||||||
@ -211,17 +343,20 @@ function playPause () {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getPostitionTicks () {
|
function getPostitionTicks() {
|
||||||
// this is very sketchy but i dont know how else to do it
|
// this is very sketchy but i dont know how else to do it
|
||||||
return (_seek + getAudioDispatcher().streamTime - getAudioDispatcher().pausedTime) * 10000;
|
return (
|
||||||
|
(_seek + getAudioDispatcher().streamTime - getAudioDispatcher().pausedTime) *
|
||||||
|
10000
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getPlayMethod () {
|
function getPlayMethod() {
|
||||||
// TODO figure out how to figure this out
|
// TODO figure out how to figure this out
|
||||||
return "DirectPlay";
|
return "DirectPlay";
|
||||||
}
|
}
|
||||||
|
|
||||||
function getRepeatMode () {
|
function getRepeatMode() {
|
||||||
if (isRepeat) {
|
if (isRepeat) {
|
||||||
return "RepeatOne";
|
return "RepeatOne";
|
||||||
} else {
|
} else {
|
||||||
@ -229,43 +364,45 @@ function getRepeatMode () {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getPlaylistItemId () {
|
function getPlaylistItemId() {
|
||||||
return getItemId();
|
return getItemId();
|
||||||
}
|
}
|
||||||
|
|
||||||
function getPlaySessionId () {
|
function getPlaySessionId() {
|
||||||
// i think its just a number which you dont need to retrieve but need to report
|
// i think its just a number which you dont need to retrieve but need to report
|
||||||
return "ae2436edc6b91b11d72aeaa67f84e0ea";
|
return "ae2436edc6b91b11d72aeaa67f84e0ea";
|
||||||
}
|
}
|
||||||
|
|
||||||
function getNowPLayingQueue () {
|
function getNowPLayingQueue() {
|
||||||
return [{
|
return [
|
||||||
|
{
|
||||||
Id: getItemId(),
|
Id: getItemId(),
|
||||||
// as I curently dont support Playlists
|
// as I curently dont support Playlists
|
||||||
PlaylistItemId: getPlaylistItemId()
|
PlaylistItemId: getPlaylistItemId(),
|
||||||
}];
|
},
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
function getCanSeek () {
|
function getCanSeek() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getIsMuted () {
|
function getIsMuted() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getVolumeLevel () {
|
function getVolumeLevel() {
|
||||||
return 100;
|
return 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getItemId () {
|
function getItemId() {
|
||||||
if (typeof currentPlayingPlaylist !== "undefined") {
|
if (typeof currentPlayingPlaylist !== "undefined") {
|
||||||
return currentPlayingPlaylist[currentPlayingPlaylistIndex];
|
return currentPlayingPlaylist[currentPlayingPlaylistIndex];
|
||||||
}
|
}
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getIsPaused () {
|
function getIsPaused() {
|
||||||
// AudioDispacker Paused is to slow
|
// AudioDispacker Paused is to slow
|
||||||
|
|
||||||
if (isPaused === undefined) {
|
if (isPaused === undefined) {
|
||||||
@ -275,7 +412,7 @@ function getIsPaused () {
|
|||||||
return isPaused;
|
return isPaused;
|
||||||
}
|
}
|
||||||
|
|
||||||
function setIsRepeat (arg) {
|
function setIsRepeat(arg) {
|
||||||
if (arg === undefined) {
|
if (arg === undefined) {
|
||||||
if (!(isRepeat === undefined)) {
|
if (!(isRepeat === undefined)) {
|
||||||
isRepeat = !isRepeat;
|
isRepeat = !isRepeat;
|
||||||
@ -284,7 +421,7 @@ function setIsRepeat (arg) {
|
|||||||
isRepeat = arg;
|
isRepeat = arg;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getProgressPayload () {
|
function getProgressPayload() {
|
||||||
const payload = {
|
const payload = {
|
||||||
CanSeek: getCanSeek(),
|
CanSeek: getCanSeek(),
|
||||||
IsMuted: getIsMuted(),
|
IsMuted: getIsMuted(),
|
||||||
@ -298,18 +435,18 @@ function getProgressPayload () {
|
|||||||
PositionTicks: getPostitionTicks(),
|
PositionTicks: getPostitionTicks(),
|
||||||
RepeatMode: getRepeatMode(),
|
RepeatMode: getRepeatMode(),
|
||||||
VolumeLevel: getVolumeLevel(),
|
VolumeLevel: getVolumeLevel(),
|
||||||
EventName: "pauseplayupdate"
|
EventName: "pauseplayupdate",
|
||||||
};
|
};
|
||||||
return payload;
|
return payload;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getStopPayload () {
|
function getStopPayload() {
|
||||||
const payload = {
|
const payload = {
|
||||||
userId: jellyfinClientManager.getJellyfinClient().getCurrentUserId(),
|
userId: jellyfinClientManager.getJellyfinClient().getCurrentUserId(),
|
||||||
itemId: getItemId(),
|
itemId: getItemId(),
|
||||||
sessionID: getPlaySessionId(),
|
sessionID: getPlaySessionId(),
|
||||||
playSessionId: getPlaySessionId(),
|
playSessionId: getPlaySessionId(),
|
||||||
positionTicks: getPostitionTicks()
|
positionTicks: getPostitionTicks(),
|
||||||
};
|
};
|
||||||
return payload;
|
return payload;
|
||||||
}
|
}
|
||||||
@ -326,5 +463,5 @@ module.exports = {
|
|||||||
previousTrack,
|
previousTrack,
|
||||||
addTracks,
|
addTracks,
|
||||||
getPostitionTicks,
|
getPostitionTicks,
|
||||||
spawnPlayMessage
|
spawnPlayMessage,
|
||||||
};
|
};
|
||||||
|
21
src/util.js
21
src/util.js
@ -1,15 +1,20 @@
|
|||||||
function checkJellyfinItemIDRegex (strgintomatch) {
|
function checkJellyfinItemIDRegex(strgintomatch) {
|
||||||
const regexresult = strgintomatch.match(/([0-9]|[a-f]){32}/);
|
const regexresult = strgintomatch.match(/([0-9]|[a-f]){32}/);
|
||||||
if (regexresult) { return [regexresult[0]]; } else { return undefined; }
|
if (regexresult) {
|
||||||
|
return [regexresult[0]];
|
||||||
|
} else {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function ticksToSeconds (ticks) {
|
function ticksToSeconds(ticks) {
|
||||||
return ticks / 10000000;
|
return ticks / 10000000;
|
||||||
}
|
}
|
||||||
|
|
||||||
function hmsToSeconds (str) {
|
function hmsToSeconds(str) {
|
||||||
var p = str.split(":");
|
var p = str.split(":");
|
||||||
var s = 0; var m = 1;
|
var s = 0;
|
||||||
|
var m = 1;
|
||||||
|
|
||||||
while (p.length > 0) {
|
while (p.length > 0) {
|
||||||
s += m * parseInt(p.pop(), 10);
|
s += m * parseInt(p.pop(), 10);
|
||||||
@ -19,7 +24,7 @@ function hmsToSeconds (str) {
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
function secondsToHms (totalSeconds) {
|
function secondsToHms(totalSeconds) {
|
||||||
const hours = Math.floor(totalSeconds / 3600);
|
const hours = Math.floor(totalSeconds / 3600);
|
||||||
totalSeconds %= 3600;
|
totalSeconds %= 3600;
|
||||||
const minutes = Math.floor(totalSeconds / 60);
|
const minutes = Math.floor(totalSeconds / 60);
|
||||||
@ -32,7 +37,7 @@ function secondsToHms (totalSeconds) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getDiscordEmbedError (e) {
|
function getDiscordEmbedError(e) {
|
||||||
const Discord = require("discord.js");
|
const Discord = require("discord.js");
|
||||||
return new Discord.MessageEmbed()
|
return new Discord.MessageEmbed()
|
||||||
.setColor(0xff0000)
|
.setColor(0xff0000)
|
||||||
@ -46,5 +51,5 @@ module.exports = {
|
|||||||
ticksToSeconds,
|
ticksToSeconds,
|
||||||
hmsToSeconds,
|
hmsToSeconds,
|
||||||
getDiscordEmbedError,
|
getDiscordEmbedError,
|
||||||
secondsToHms
|
secondsToHms,
|
||||||
};
|
};
|
||||||
|
@ -2,19 +2,25 @@ const jellyfinClientManager = require("./jellyfinclientmanager");
|
|||||||
const playbackmanager = require("./playbackmanager");
|
const playbackmanager = require("./playbackmanager");
|
||||||
const { ticksToSeconds } = require("./util");
|
const { ticksToSeconds } = require("./util");
|
||||||
|
|
||||||
function openSocket () {
|
function openSocket() {
|
||||||
jellyfinClientManager.getJellyfinClient().openWebSocket();
|
jellyfinClientManager.getJellyfinClient().openWebSocket();
|
||||||
jellyfinClientManager.getJellyfinClient().reportCapabilities(
|
jellyfinClientManager.getJellyfinClient().reportCapabilities({
|
||||||
{
|
|
||||||
PlayableMediaTypes: "Audio",
|
PlayableMediaTypes: "Audio",
|
||||||
SupportsMediaControl: true,
|
SupportsMediaControl: true,
|
||||||
SupportedCommands: "SetRepeatMode,Play,Playstate"
|
SupportedCommands: "SetRepeatMode,Play,Playstate",
|
||||||
}
|
});
|
||||||
);
|
jellyfinClientManager
|
||||||
jellyfinClientManager.getJellyfinEvents().on(jellyfinClientManager.getJellyfinClient(), "message", (type, data) => {
|
.getJellyfinEvents()
|
||||||
|
.on(jellyfinClientManager.getJellyfinClient(), "message", (type, data) => {
|
||||||
if (data.MessageType === "Play") {
|
if (data.MessageType === "Play") {
|
||||||
if (data.Data.PlayCommand === "PlayNow") {
|
if (data.Data.PlayCommand === "PlayNow") {
|
||||||
playbackmanager.startPlaying(undefined, data.Data.ItemIds, data.Data.StartIndex || 0, 0, false);
|
playbackmanager.startPlaying(
|
||||||
|
undefined,
|
||||||
|
data.Data.ItemIds,
|
||||||
|
data.Data.StartIndex || 0,
|
||||||
|
0,
|
||||||
|
false
|
||||||
|
);
|
||||||
}
|
}
|
||||||
} else if (data.MessageType === "Playstate") {
|
} else if (data.MessageType === "Playstate") {
|
||||||
if (data.Data.Command === "PlayPause") {
|
if (data.Data.Command === "PlayPause") {
|
||||||
@ -23,7 +29,9 @@ function openSocket () {
|
|||||||
playbackmanager.stop();
|
playbackmanager.stop();
|
||||||
} else if (data.Data.Command === "Seek") {
|
} else if (data.Data.Command === "Seek") {
|
||||||
// because the server sends seek an privious track at same time so i have to do timing
|
// because the server sends seek an privious track at same time so i have to do timing
|
||||||
setTimeout(async () => { playbackmanager.seek(data.Data.SeekPositionTicks); }, 20);
|
setTimeout(async () => {
|
||||||
|
playbackmanager.seek(data.Data.SeekPositionTicks);
|
||||||
|
}, 20);
|
||||||
} else if (data.Data.Command === "NextTrack") {
|
} else if (data.Data.Command === "NextTrack") {
|
||||||
try {
|
try {
|
||||||
playbackmanager.nextTrack();
|
playbackmanager.nextTrack();
|
||||||
@ -44,5 +52,5 @@ function openSocket () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
openSocket
|
openSocket,
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user