You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在基于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

  1. 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.
  2. Safe In-Page Playback: We use YouTube's official embed URL, which is designed for in-page playback and avoids cross-origin issues.
  3. 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-core installed (run npm update ytdl-core), since YouTube occasionally changes its API and older versions may break.
  • The cors middleware already handles cross-origin requests between your front-end and backend, so you won't run into CORS errors.

内容的提问来源于stack exchange,提问作者Emiel VdV

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 16:33:12