Compare commits

...

2 Commits

Author SHA1 Message Date
0f0f263c98 Version 1.3.0 - Ajout de Docker
Some checks failed
Deployment Pipeline / deploy (push) Has been cancelled
2025-10-04 17:28:58 +02:00
ca4a20a1b2 Version 1.3.0 - Ajout de Docker 2025-10-04 17:28:50 +02:00
7 changed files with 2439 additions and 1427 deletions

19
Dockerfile Normal file
View File

@@ -0,0 +1,19 @@
FROM node:lts-alpine
# Crée un dossier de travail
WORKDIR /app
# Copie package.json et package-lock.json
COPY package*.json ./
# Installe les dépendances
RUN npm install
# Copie le code source (mais pas le dossier data, qui sera monté en volume)
COPY . .
# Expose le port backend
EXPOSE 4000
# Commande de démarrage
CMD ["node", "src/utils/main.js"]

16
docker-compose.yml Normal file
View File

@@ -0,0 +1,16 @@
version: "3.9"
services:
subsonics-backend:
build:
context: . # dossier backend
dockerfile: Dockerfile
container_name: subsonics-backend
ports:
- "4000:4000"
volumes:
- subsonics-backend-data:/app/data
restart: unless-stopped
volumes:
subsonics-backend-data:

3707
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
{ {
"name": "chopin-backend", "name": "chopin-backend",
"version": "1.2.0", "version": "1.3.0",
"description": "Discord Bot for music - Fetching everywhere !", "description": "Discord Bot for music - Fetching everywhere !",
"main": "src/main.js", "main": "src/main.js",
"nodemonConfig": { "nodemonConfig": {
@@ -30,16 +30,19 @@
"ffprobe-static": "^3.1.0", "ffprobe-static": "^3.1.0",
"fluent-ffmpeg": "^2.1.3", "fluent-ffmpeg": "^2.1.3",
"googleapis": "^149.0.0", "googleapis": "^149.0.0",
"https-proxy-agent": "^7.0.6",
"libsodium-wrappers": "^0.7.15", "libsodium-wrappers": "^0.7.15",
"loguix": "^1.4.2", "loguix": "^1.4.2",
"mime-types": "^3.0.1", "mime-types": "^3.0.1",
"nodemon": "^3.1.10", "nodemon": "^3.1.10",
"pm2": "^5.4.3", "pm2": "^6.0.11",
"socket.io": "^4.8.1", "socket.io": "^4.8.1",
"soundcloud.ts": "^0.6.3", "soundcloud.ts": "^0.6.3",
"spotify-web-api-node": "^5.0.2", "spotify-web-api-node": "^5.0.2",
"undici": "^7.16.0",
"uuid": "^11.1.0", "uuid": "^11.1.0",
"webmetrik": "^0.1.4", "webmetrik": "^0.1.4",
"youtubei.js": "^15.1.1",
"yt-search": "^2.13.1", "yt-search": "^2.13.1",
"ytfps": "^1.2.0" "ytfps": "^1.2.0"
} }

View File

@@ -1,46 +1,91 @@
const {createAudioResource, VoiceConnectionStatus, createAudioPlayer, StreamType} = require('@discordjs/voice'); const { LogType } = require('loguix');
const {LogType} = require('loguix') const clog = new LogType("Youtube-Stream");
const clog = new LogType("Youtube-Stream")
const ytdl = require('@distube/ytdl-core')
const { __glob } = require('../../utils/GlobalVars'); const { __glob } = require('../../utils/GlobalVars');
const { Innertube, UniversalCache, ClientType } = require('youtubei.js');
const fs = require('fs'); const fs = require('fs');
const { ProxyAgent } = require('undici');
async function getStream(song) { async function getStream(song) {
try {
// Lire et formater les cookies comme chaîne
const cookiesArr = JSON.parse(fs.readFileSync(__glob.COOKIES, 'utf-8'));
const cookieStr = cookiesArr.map(cookie => `${cookie.name}=${cookie.value}`).join('; ');
// FIXME: Change youtube provider // Lire et préparer le proxy
const proxy = JSON.parse(fs.readFileSync(__glob.PROXY, 'utf-8'));
const proxyAgent = new ProxyAgent(proxy.uri);
try {
const headers = { console.log(`Tentative de récupération pour: ${song.title || song.url}`);
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) ' +
'AppleWebKit/537.36 (KHTML, like Gecko) ' +
'Chrome/116.0.5845.97 Safari/537.36',
'Accept-Language': 'en-US,en;q=0.9'
};
var cookies = await JSON.parse(await fs.readFileSync(__glob.COOKIES, 'utf-8')); // Création de l'instance Innertube avec les bons paramètres
const proxy = await JSON.parse(await fs.readFileSync(__glob.PROXY, 'utf-8')); const youtube = await Innertube.create({
const agent = ytdl.createProxyAgent(proxy, cookies) cookie: cookieStr,
let stream = ytdl(song.url, { player_id: '0004de42',
quality: 'highestaudio', user_agent: `Mozilla/5.0 (Macintosh; Intel Mac OS X 15_0) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.0 Safari/605.1.15`,
highWaterMark: 1 << 30, client_type: ClientType.WEB,
liveBuffer: 20000, retrieve_player: true,
dlChunkSize: 0, device_category: 'desktop',
bitrate: 128, enable_session_cache: true,
requestOptions: { generate_session_locally: true,
headers: headers, // fetch: (url, options) => fetch(url, { ...options, agent: proxyAgent })
}, });
agent: agent,
});
return stream // Récupérer les infos vidéo
const videoInfo = await youtube.getInfo(song.id);
} catch(e) {
clog.error("Erreur lors de la récupération du stream : " + song.title)
clog.error(e)
if (!videoInfo) {
throw new Error('Impossible de récupérer les informations de la vidéo');
}
console.log('Informations vidéo récupérées:', videoInfo.basic_info?.title);
// Vérifier la disponibilité de la lecture
if (videoInfo.playability_status?.status !== 'OK') {
console.log('Statut de lecture:', videoInfo.playability_status?.status);
console.log('Raison:', videoInfo.playability_status?.reason);
}
// Recherche des formats audio adaptatifs
let audioFormats = videoInfo.streaming_data?.adaptive_formats?.filter(
format => format.mime_type?.includes('audio')
) || [];
if (audioFormats.length === 0) {
// Si pas de formats adaptatifs, chercher dans les formats classiques
const basicFormats = videoInfo.streaming_data?.formats?.filter(
format => format.mime_type?.includes('audio')
) || [];
if (basicFormats.length === 0) {
throw new Error('Aucun format audio trouvé');
}
audioFormats.push(...basicFormats);
}
// Sélection du format audio de meilleure qualité
const bestAudio = audioFormats.reduce((prev, current) =>
(prev.bitrate || 0) > (current.bitrate || 0) ? prev : current
);
console.log('Format sélectionné:', bestAudio.mime_type, bestAudio.bitrate);
// Télécharger le stream audio
const stream = await videoInfo.download(bestAudio.itag, {
// fetch via ton proxy si nécessaire
headers: {
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 15_0) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.0 Safari/605.1.15',
'Cookie': cookieStr
}
});
console.log(stream)
return stream; // cest un ReadableStream prêt à être pipé
} catch (e) {
clog.error("Erreur lors de la récupération du stream : " + (song.title || song.url));
clog.error('Détails:', e.message);
} }
} }
module.exports = { getStream };
module.exports = {getStream}

View File

@@ -283,6 +283,7 @@ class Player {
} }
async setDuration(duration) { async setDuration(duration) {
//FIXME: SET DURATION FONCTIONNE TRES LENTEMENT //FIXME: SET DURATION FONCTIONNE TRES LENTEMENT
if (this.checkConnection()) return; if (this.checkConnection()) return;
if (this.queue.current == null) return; if (this.queue.current == null) return;

View File

@@ -447,7 +447,6 @@ async function setFullBan(id) {
} }
} }
function deleteAccount(id) { function deleteAccount(id) {
const user = getUserById(id); const user = getUserById(id);
if (user) { if (user) {