add playbackmanager and outsource all relevent components

This commit is contained in:
KGT1 2020-09-21 04:05:49 +02:00
parent e6d8db86f6
commit d9f25f816a
2 changed files with 188 additions and 32 deletions

View File

@ -4,12 +4,13 @@ const {
checkJellyfinItemIDRegex checkJellyfinItemIDRegex
} = require('./util'); } = require('./util');
const { const {
getAudioDispatcher, getAudioDispatcher
setAudioDispatcher
} = require('./dispachermanager'); } = require('./dispachermanager');
const discordclientmanager = require('./discordclientmanager'); const discordclientmanager = require('./discordclientmanager');
const jellyfinClientManager = require('./jellyfinclientmanager'); const jellyfinClientManager = require('./jellyfinclientmanager');
const playbackmanager = require('./playbackmanager');
const websocketHanler = require('./websockethandler');
const discordClient = discordclientmanager.getDiscordClient(); const discordClient = discordclientmanager.getDiscordClient();
@ -57,27 +58,35 @@ async function searchForItemID(searchString) {
} }
function summon(voiceChannel){ function summon(voiceChannel){
voiceChannel.join()
if (!voiceChannel) {
return message.reply('please join a voice channel to summon me!');
} }
voiceChannel.join() function summonMessage(message){
if (!message.member.voice.channel) {
message.reply('please join a voice channel to summon me!');
}else if(message.channel.type === 'dm'){
message.reply('no dms')
}
else{
summon(message.member.voice.channel)
}
} }
function handleChannelMessage(message) { function handleChannelMessage(message) {
getRandomDiscordColor() getRandomDiscordColor()
if (message.content.startsWith(CONFIG["discord-prefix"] + 'summon')) { if (message.content.startsWith(CONFIG["discord-prefix"] + 'summon')) {
if (message.channel.type === 'dm') { isSummendByPlay = false;
return;
}
summon(message.member.voice.channel); websocketHanler.openSocket();
summonMessage(message);
} else if (message.content.startsWith(CONFIG["discord-prefix"] + 'disconnect')) { } else if (message.content.startsWith(CONFIG["discord-prefix"] + 'disconnect')) {
playbackmanager.stop()
jellyfinClientManager.getJellyfinClient().closeWebSocket();
discordClient.user.client.voice.connections.forEach((element) => { discordClient.user.client.voice.connections.forEach((element) => {
element.disconnect(); element.disconnect();
}); });
@ -85,10 +94,7 @@ function handleChannelMessage(message) {
} 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'))) {
if (getAudioDispatcher() !== undefined) { if (getAudioDispatcher() !== undefined) {
if (getAudioDispatcher().paused) playbackmanager.playPause();
getAudioDispatcher().resume();
else
getAudioDispatcher().pause(true);
} else { } else {
message.reply("there is nothing playing!") message.reply("there is nothing playing!")
} }
@ -98,8 +104,7 @@ function handleChannelMessage(message) {
if (discordClient.user.client.voice.connections.size < 1) { if (discordClient.user.client.voice.connections.size < 1) {
discordClient.user.client.voice.connections.size summonMessage(message)
summon(message.member.voice.channel)
isSummendByPlay=true isSummendByPlay=true
} }
@ -121,27 +126,20 @@ function handleChannelMessage(message) {
} }
discordClient.user.client.voice.connections.forEach((element) => { discordClient.user.client.voice.connections.forEach((element) => {
let stream = `${jellyfinClientManager.getJellyfinClient().serverAddress()}/Audio/${itemID}/universal?UserId=${jellyfinClientManager.getJellyfinClient().getCurrentUserId()}&DeviceId=${jellyfinClientManager.getJellyfinClient().deviceId()}&MaxStreamingBitrate=${element.channel.bitrate.toString()}&Container=opus&AudioCodec=opus&api_key=${jellyfinClientManager.getJellyfinClient().accessToken()}&TranscodingContainer=ts&TranscodingProtocol=hls`; playbackmanager.startPlaying(element,itemID,isSummendByPlay);
setAudioDispatcher(element.play(stream));
element.on("error", (error) => {
console.error(error);
})
getAudioDispatcher().on("finish",()=>{
if(isSummendByPlay){
element.disconnect();
}
})
}) })
} }
playThis(); playThis();
} else if (message.content.startsWith(CONFIG["discord-prefix"] + 'stop')) { } else if (message.content.startsWith(CONFIG["discord-prefix"] + 'stop')) {
getAudioDispatcher().pause() if(isSummendByPlay){
setAudioDispatcher(undefined) if(discordClient.user.client.voice.connections.size > 0){
discordClient.user.client.voice.connections.forEach((element) => { playbackmanager.stop(discordClient.user.client.voice.connections.first());
element.disconnect(); }
}); }else{
playbackmanager.stop();
}
} else if (message.content.startsWith(CONFIG["discord-prefix"] + 'help')) { } else if (message.content.startsWith(CONFIG["discord-prefix"] + 'help')) {
const reply = new Discord.MessageEmbed() const reply = new Discord.MessageEmbed()

158
src/playbackmanager.js Normal file
View File

@ -0,0 +1,158 @@
const { default: fetch } = require('node-fetch');
const {
getAudioDispatcher,
setAudioDispatcher
} = require('./dispachermanager');
var currentPlayingItemId;
var progressInterval;
var isPaused;
const jellyfinClientManager = require('./jellyfinclientmanager');
function streamURLbuilder(itemID, bitrate) {
//so the server transcodes. Seems appropriate as it has the source file.
let supportedCodecs = "opus"
let 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`;
}
function startPlaying(voiceconnection, itemID, disconnectOnFinish) {
isPaused=false;
async function playasync() {
let url = streamURLbuilder(itemID, voiceconnection.channel.bitrate)
jellyfinClientManager.getJellyfinClient().reportPlaybackStart({ userID: `${jellyfinClientManager.getJellyfinClient().getCurrentUserId()}`, itemID: `${itemID}` })
currentPlayingItemId = itemID;
setAudioDispatcher(voiceconnection.play(url));
let time = await jellyfinClientManager.getJellyfinClient().getItem(jellyfinClientManager.getJellyfinClient().getCurrentUserId(),currentPlayingItemId)
async function asfg(){
jellyfinClientManager.getJellyfinClient().reportPlaybackProgress(getProgressPayload())
}
//progressInterval=setInterval(asfg,2000);
getAudioDispatcher().on("finish", () => {
if (disconnectOnFinish) {
stop(voiceconnection);
}else{
stop();
}
})
}
playasync().catch((rsn) => { console.log(rsn) });
}
/**
* @param {Object=} disconnectVoiceConnection - Optional The voice Connection do disconnect from
*/
function stop(disconnectVoiceConnection) {
isPaused=true;
if (disconnectVoiceConnection) {
disconnectVoiceConnection.disconnect()
}
jellyfinClientManager.getJellyfinClient().reportPlaybackStopped({userId: jellyfinClientManager.getJellyfinClient().getCurrentUserId(),itemId:currentPlayingItemId})
if(getAudioDispatcher())
getAudioDispatcher().destroy();
setAudioDispatcher(undefined);
clearInterval(progressInterval);
}
function pause() {
isPaused=true;
console.log('here paused is changed', isPaused);
jellyfinClientManager.getJellyfinClient().reportPlaybackProgress(getProgressPayload())
getAudioDispatcher().pause(true);
}
function resume() {
isPaused=false;
jellyfinClientManager.getJellyfinClient().reportPlaybackProgress(getProgressPayload())
getAudioDispatcher().resume();
}
function playPause() {
if (getAudioDispatcher().paused)
resume();
else
pause();
}
function getPostitionTicks(){
//this is very sketchy but i dont know how else to do it
return (getAudioDispatcher().streamTime - getAudioDispatcher().pausedTime)*10000;
}
function getPlayMethod(){
//TODO figure out how to figure this out
return 'Transcode';
}
function getRepeatMode(){
return 'RepeatNone';
}
function getPlaylistItemId(){
//as I curently dont support Playlists
return 'playlistItem0'
}
function getPlaySessionId(){
//really need to figure out what this is and how to get it
return 'ae2436edc6b91b11d72aeaa67f84e0ea';
}
function getNowPLayingQueue(){
return [{
Id: currentPlayingItemId,
//as I curently dont support Playlists
PlaylistItemId: getPlaylistItemId()
}]
}
function getCanSeek(){
return false;
}
function getIsMuted(){
return false;
}
function getVolumeLevel(){
return 100;
}
function getItemId(){
return currentPlayingItemId
}
function getIsPaused(){
//AudioDispacker Paused is to slow
if(isPaused == undefined){
isPaused=false;
}
return isPaused;
}
function getProgressPayload(){
let payload= {
CanSeek: getCanSeek(),
IsMuted: getIsMuted(),
IsPaused: getIsPaused(),
ItemId: getItemId(),
MediaSourceId: getItemId(),
NowPlayingQueue: getNowPLayingQueue(),
PlayMethod: getPlayMethod(),
PlaySessionId: getPlaySessionId(),
PlaylistItemId: getPlaylistItemId(),
PositionTicks: getPostitionTicks(),
RepeatMode: getRepeatMode(),
VolumeLevel: getVolumeLevel()
}
console.log(payload.IsPaused);
return payload
}
module.exports = {
startPlaying,
stop,
playPause,
resume,
pause
}