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

如何为基于ytdl-core的YouTube下载器添加起止时间功能?

解决指定起止时间下载YouTube视频片段的问题

问题根源分析

你的代码存在两个核心问题:

  • 前端参数传递格式错误,后端无法正确获取起止时间
  • ytdl-core仅负责下载完整视频流,本身不支持视频裁剪,需要借助FFmpeg实现片段截取

1. 修复前端参数传递

当前前端的URL拼接用了多个?,正确的多参数分隔符是&,同时你直接传递了DOM元素而非输入框的value值。修改后的前端代码:

var convertBtn = document.querySelector('.convert-button');
var URLinput = document.querySelector('.URL-input');
var startInput = document.querySelector('.startValue');
var endInput = document.querySelector('.endValue');

// 辅助函数:将HH:MM:SS格式转成秒数
function timeToSeconds(timeStr) {
    const parts = timeStr.split(':').map(Number);
    if (parts.length === 3) {
        return parts[0] * 3600 + parts[1] * 60 + parts[2];
    } else if (parts.length === 2) {
        return parts[0] * 60 + parts[1];
    }
    return parseInt(parts[0] || 0);
}

convertBtn.addEventListener('click', () => {
    const url = URLinput.value.trim();
    const startTime = timeToSeconds(startInput.value.trim());
    const endTime = timeToSeconds(endInput.value.trim());
    
    if (!url || isNaN(startTime) || isNaN(endTime) || endTime <= startTime) {
        alert('请输入有效的URL和时间参数');
        return;
    }
    
    sendURL(url, startTime, endTime);
});

function sendURL(url, startTime, endTime) {
    // 用&分隔多个查询参数,同时编码URL避免特殊字符问题
    window.location.href = `http://localhost:4000/download?URL=${encodeURIComponent(url)}&startTime=${startTime}&endTime=${endTime}`;
}

2. 后端集成FFmpeg实现裁剪

前置准备

  • 安装FFmpeg:确保你的系统已安装FFmpeg,可通过ffmpeg -version命令验证
  • 安装依赖库:
npm install fluent-ffmpeg

修改后端代码

利用fluent-ffmpeg处理ytdl-core的视频流,截取指定时间片段:

const express = require('express');
const cors = require('cors');
const ytdl = require('ytdl-core');
const ffmpeg = require('fluent-ffmpeg');
const app = express();

app.use(cors());
app.listen(4000, () => {
    console.log('Server Works !!! At port 4000');
});

app.get('/download', async (req, res) => {
    try {
        const { URL, startTime, endTime } = req.query;
        
        // 参数合法性校验
        if (!URL || isNaN(startTime) || isNaN(endTime) || parseInt(endTime) <= parseInt(startTime)) {
            return res.status(400).send('无效的参数');
        }

        // 验证YouTube URL有效性
        if (!ytdl.validateURL(URL)) {
            return res.status(400).send('无效的YouTube链接');
        }

        // 设置响应头,指定下载文件名
        res.header('Content-Disposition', 'attachment; filename="video-clip.mp4"');
        
        // 获取视频流并通过FFmpeg裁剪
        const videoStream = ytdl(URL, { format: 'mp4' });
        
        ffmpeg(videoStream)
            .setStartTime(startTime)
            .setDuration(parseInt(endTime) - parseInt(startTime))
            .outputFormat('mp4')
            .on('error', (err) => {
                console.error('FFmpeg处理错误:', err);
                res.status(500).send('视频处理失败');
            })
            .pipe(res);
            
    } catch (err) {
        console.error('服务器错误:', err);
        res.status(500).send('服务器内部错误');
    }
});

关键说明

  • FFmpeg的setStartTime接收秒数或时间格式字符串,setDuration需要传入片段的时长(结束时间-开始时间)
  • 前端的timeToSeconds函数将用户输入的时间格式统一转成秒数,避免格式兼容问题
  • 加入了多层参数校验,提升代码鲁棒性

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 01:45:22