如何在基于Express的YouTube视频下载器前端HTML页面中展示YouTube视频
Hey there! Awesome that your YouTube downloader is up and running smoothly. Let's walk through how to add a video preview right in your front-end HTML page—no database required, just using Node.js and Express like you wanted:
Step 1: Update Your Backend (Server.js)
First, we'll add a new endpoint to fetch video metadata (like title, thumbnail, and embed URL) from YouTube using ytdl-core. This lets us grab everything we need to display the video without storing anything long-term:
const express = require("express"); const cors = require("cors"); const ytdl = require("ytdl-core"); const app = express(); app.use(cors()); app.listen(4000, () => { console.log("Server is working at port 4000 !!"); }); // New endpoint to fetch video info for preview app.get("/get-video-info", async (req, res) => { try { const url = req.query.URL; if (!ytdl.validateURL(url)) { return res.status(400).json({ error: "Invalid YouTube URL" }); } const videoInfo = await ytdl.getInfo(url); // Extract only the data we need for the front-end const previewData = { title: videoInfo.videoDetails.title, // Grab the largest available thumbnail thumbnail: videoInfo.videoDetails.thumbnails.at(-1).url, // Use YouTube's official embed URL for safe in-page playback embedUrl: `https://www.youtube.com/embed/${videoInfo.videoDetails.videoId}` }; res.json(previewData); } catch (err) { res.status(500).json({ error: "Failed to load video details" }); } }); // Keep your existing download endpoint unchanged app.get("/download", (req, res) => { const url = req.query.URL; res.header("Content-Disposition", 'attachment; filename="video.mp4"'); ytdl(url, { format: "mp4" }).pipe(res); })
Step 2: Modify Your Front-End (Index.html)
Add a section to display the video preview, title, and a dedicated download button. We'll hide this section by default and show it only after we fetch valid video data:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>YouTube Video Downloader</title> <style> .video-preview-section { margin-top: 2rem; display: none; /* Hidden until we have video data */ } .video-frame { width: 560px; height: 315px; border: none; } .video-title { margin: 1rem 0; font-size: 1.2rem; } .URL-input { padding: 0.5rem; width: 300px; } button { padding: 0.5rem 1rem; margin-left: 0.5rem; cursor: pointer; } </style> </head> <body> <h1>My Own YouTube Downloader</h1> <input class="URL-input" type="text" placeholder="Enter YouTube URL..."> <button class="load-video-btn">Load Video</button> <!-- Video preview section --> <div class="video-preview-section"> <iframe class="video-frame" src="" allowfullscreen></iframe> <h2 class="video-title"></h2> <button class="download-btn">Download Video</button> </div> <script src="script.js"></script> </body> </html>
Step 3: Update Front-End Logic (Script.js)
Replace your existing script to first fetch video info, render the preview, and only then enable the download option. We'll add basic error handling for invalid URLs or server issues:
const loadBtn = document.querySelector(".load-video-btn"); const urlInput = document.querySelector(".URL-input"); const previewSection = document.querySelector(".video-preview-section"); const videoFrame = document.querySelector(".video-frame"); const videoTitle = document.querySelector(".video-title"); const downloadBtn = document.querySelector(".download-btn"); loadBtn.addEventListener("click", async () => { const url = urlInput.value.trim(); if (!url) { alert("Please enter a valid YouTube URL first!"); return; } try { // Fetch video info from our backend const response = await fetch(`http://localhost:4000/get-video-info?URL=${encodeURIComponent(url)}`); const data = await response.json(); if (response.ok) { // Show the preview section and populate data previewSection.style.display = "block"; videoFrame.src = data.embedUrl; videoTitle.textContent = data.title; // Bind download action to the button downloadBtn.onclick = () => { window.location.href = `http://localhost:4000/download?URL=${encodeURIComponent(url)}`; }; } else { alert(data.error || "Something went wrong loading the video."); } } catch (err) { alert("Couldn't connect to the server. Make sure it's running on port 4000!"); console.error(err); } });
How This Works
- No Database Needed: We fetch video data in real-time directly from YouTube using
ytdl-core, so there's no need to store anything permanently. - Safe In-Page Playback: We use YouTube's official embed URL, which is designed for in-page playback and avoids cross-origin issues.
- Separate Actions: Users first load the video preview, then choose to download it—making the flow more intuitive.
Quick Notes
- Make sure you have the latest version of
ytdl-coreinstalled (runnpm update ytdl-core), since YouTube occasionally changes its API and older versions may break. - The
corsmiddleware already handles cross-origin requests between your front-end and backend, so you won't run into CORS errors.
内容的提问来源于stack exchange,提问作者Emiel VdV

