mirror of
https://github.com/MasterAcnolo/Freedom-Loader.git
synced 2026-07-29 18:25:47 +02:00
Informations Vidéo
This commit is contained in:
21
README.md
21
README.md
@@ -1,2 +1,23 @@
|
|||||||
# MP3 Downloader
|
# MP3 Downloader
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
### 1. Clônage du Repositories
|
||||||
|
|
||||||
|
```
|
||||||
|
git clone https://github.com/MasterAcnolo/MP3-Downloader
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Installation des dépendances
|
||||||
|
|
||||||
|
```
|
||||||
|
npm install express
|
||||||
|
```
|
||||||
|
|
||||||
|
## Pour lancer le serveur
|
||||||
|
|
||||||
|
```
|
||||||
|
node server/server.js
|
||||||
|
```
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
|
|
||||||
<form action="/download" method="POST">
|
<form action="/download" method="POST">
|
||||||
<input name="url" placeholder="URL YouTube">
|
<input name="url" placeholder="URL YouTube" id="UrlInput">
|
||||||
<input type="checkbox" name="audioOnly" value="1"> MP3 seulement
|
<input type="checkbox" name="audioOnly" value="1"> MP3 seulement
|
||||||
<select name="quality">
|
<select name="quality">
|
||||||
<option value="best">Meilleure qualité</option>
|
<option value="best">Meilleure qualité</option>
|
||||||
@@ -24,5 +24,9 @@
|
|||||||
être l'espèce de "canal" attribué a ça. Ca va faire que si jamais on veut ensuite recup
|
être l'espèce de "canal" attribué a ça. Ca va faire que si jamais on veut ensuite recup
|
||||||
les infos du form, il faut aller sur ce canal précis (/download). La méthode POST dit
|
les infos du form, il faut aller sur ce canal précis (/download). La méthode POST dit
|
||||||
que l'on envoie des données.-->
|
que l'on envoie des données.-->
|
||||||
|
|
||||||
|
<div id="videoInfo" style="margin-top: 20px;"></div>
|
||||||
|
|
||||||
|
<script src="script/fetchinfo.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
73
public/script/fetchinfo.js
Normal file
73
public/script/fetchinfo.js
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
const urlInput = document.getElementById("UrlInput"); // Récupère le champ input où l'utilisateur entre l'URL
|
||||||
|
const infoDiv = document.getElementById("videoInfo"); // Récupère la div où on affichera les infos
|
||||||
|
|
||||||
|
let lastFetchedUrl = ""; // Pour éviter de refaire plusieurs requêtes pour la même URL
|
||||||
|
|
||||||
|
// On écoute chaque changement dans le champ URL
|
||||||
|
urlInput.addEventListener("input", async () => {
|
||||||
|
const url = urlInput.value; // On prend la valeur actuelle du champ
|
||||||
|
|
||||||
|
// Si pas d'URL, ou URL trop courte, ou déjà traitée, on sort
|
||||||
|
if (!url || url.length < 5 || url === lastFetchedUrl) return;
|
||||||
|
|
||||||
|
lastFetchedUrl = url; // On mémorise l'URL traitée
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Envoi d'une requête POST vers le backend /info avec l'URL dans le corps
|
||||||
|
const res = await fetch("/info", {
|
||||||
|
method: "POST",
|
||||||
|
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
||||||
|
body: new URLSearchParams({ url }) // Encode l'URL au format x-www-form-urlencoded
|
||||||
|
});
|
||||||
|
|
||||||
|
// Si la réponse n'est pas OK (erreur 4xx ou 5xx)
|
||||||
|
if (!res.ok) {
|
||||||
|
infoDiv.innerHTML = "❌ Impossible de récupérer les infos."; // Message d'erreur utilisateur
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// On récupère la réponse JSON (les infos de la vidéo)
|
||||||
|
const data = await res.json();
|
||||||
|
|
||||||
|
// Formatage de la durée en minutes et secondes (ex: 4m 35s)
|
||||||
|
const minutes = Math.floor(data.duration / 60);
|
||||||
|
const seconds = data.duration % 60;
|
||||||
|
const durationStr = `${minutes}m ${seconds.toString().padStart(2, '0')}s`;
|
||||||
|
|
||||||
|
// Formatage de la date d'upload depuis YYYYMMDD vers JJ/MM/AAAA
|
||||||
|
const date = data.upload_date || "";
|
||||||
|
const readableDate = date
|
||||||
|
? `${date.slice(6, 8)}/${date.slice(4, 6)}/${date.slice(0, 4)}`
|
||||||
|
: "Inconnue";
|
||||||
|
|
||||||
|
// Taille estimée en Mo, ou "Inconnue" si pas dispo
|
||||||
|
const sizeMB = data.filesize_approx
|
||||||
|
? (data.filesize_approx / (1024 * 1024)).toFixed(2) + " Mo"
|
||||||
|
: "Inconnue";
|
||||||
|
|
||||||
|
// Catégories en chaîne séparée par des virgules, ou "Non spécifiées"
|
||||||
|
const categories = data.categories
|
||||||
|
? data.categories.join(", ")
|
||||||
|
: "Non spécifiées";
|
||||||
|
|
||||||
|
// Mise à jour du contenu HTML de la div avec toutes les infos formatées
|
||||||
|
infoDiv.innerHTML = `
|
||||||
|
<h3>${data.title}</h3>
|
||||||
|
<img src="${data.thumbnail}" width="320">
|
||||||
|
<ul>
|
||||||
|
<li><strong>Durée :</strong> ${durationStr}</li>
|
||||||
|
<li><strong>Uploader :</strong> ${data.uploader || "Inconnu"}</li>
|
||||||
|
<li><strong>Date d’upload :</strong> ${readableDate}</li>
|
||||||
|
<li><strong>Vues :</strong> ${data.view_count?.toLocaleString() || "?"}</li>
|
||||||
|
<li><strong>Likes :</strong> ${data.like_count?.toLocaleString() || "?"}</li>
|
||||||
|
<li><strong>URL :</strong> <a href="${data.webpage_url}" target="_blank">${data.webpage_url}</a></li>
|
||||||
|
<li><strong>Channel :</strong> <a href="${data.channel_url}" target="_blank">${data.channel_url}</a></li>
|
||||||
|
<li><strong>Taille estimée :</strong> ${sizeMB}</li>
|
||||||
|
<li><strong>Catégories :</strong> ${categories}</li>
|
||||||
|
</ul>
|
||||||
|
`;
|
||||||
|
} catch (e) {
|
||||||
|
// Si une erreur survient lors de la récupération ou du parsing
|
||||||
|
infoDiv.innerHTML = "❌ Erreur lors de la récupération.";
|
||||||
|
}
|
||||||
|
});
|
||||||
@@ -9,6 +9,8 @@ if (!fs.existsSync("downloads")) { // Si jamais il n'y a pas de dossier download
|
|||||||
fs.mkdirSync("downloads"); // On le crée
|
fs.mkdirSync("downloads"); // On le crée
|
||||||
}
|
}
|
||||||
|
|
||||||
|
app.use(express.static("public")); // Ca c'est pour ouvrir le serveur, comme ça plus besoin d'utiliser live server
|
||||||
|
|
||||||
app.post("/download", (req, res) => {
|
app.post("/download", (req, res) => {
|
||||||
const options = {
|
const options = {
|
||||||
url: req.body.url,
|
url: req.body.url,
|
||||||
@@ -56,6 +58,26 @@ app.post("/download", (req, res) => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
app.post("/info", (req,res) =>{
|
||||||
|
|
||||||
|
const url = req.body.url;
|
||||||
|
if (!url) return res.status(400).send("❌ URL manquante");
|
||||||
|
|
||||||
|
const command = `yt-dlp --dump-json "${url}"`;
|
||||||
|
|
||||||
|
exec(command, (error, stdout, stderr) => {
|
||||||
|
if (error) {
|
||||||
|
return res.status(500).send("❌ Impossible de récupérer les infos.");
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const info = JSON.parse(stdout);
|
||||||
|
res.json(info);
|
||||||
|
} catch (e) {
|
||||||
|
res.status(500).send("❌ JSON illisible.");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
app.listen(8080, () => {
|
app.listen(8080, () => {
|
||||||
console.log("🟢 Serveur prêt sur http://localhost:8080");
|
console.log("🟢 Serveur prêt sur http://localhost:8080");
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user