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

为何yt-dlp命令行可截取视频,Python库却下载完整视频?

问题

命令行执行yt-dlp https://www.youtube.com/watch?v=MtN1YnoL46Q --download-sections "*00:02:05-00:02:10" --force-keyframes-at-cuts能正常下载指定视频片段,但用yt-dlp的Python库开发Flask API时,配置了对应的参数却还是下载完整视频。需求是直接截取视频返回,不想用FFmpeg后期裁剪,求排查代码问题。

代码如下:

from flask import Flask, make_response, request
import yt_dlp
from flask_cors import CORS

app = Flask(__name__, static_folder='static')

CORS(app, expose_headers=['Filename'])
 
@app.route("/downloadpart/", methods=['POST'])
def download_cut():
    if request.method == 'POST':
        url = request.form.get('link')  
        ydl_opts = {'format': 'best',
                    'download_sections' : "*00:02:05-00:02:10", 
                    'force_keyframes_at_cuts' : True,
                    }
        try:
            with yt_dlp.YoutubeDL(ydl_opts) as ydl:
                info_dict = ydl.extract_info(url, download=False)
                video_url = info_dict['url']
                video_data = ydl.urlopen(video_url).read()
                headers = {
                    'Content-Type': 'video/mp4',
                }
                return make_response(video_data, 200, headers)
        except Exception as e:
            return make_response(e)
    return make_response("Invalid request", 400)


if __name__ == '__main__':
    #app.run(debug=True) 
    app.run(debug=False, host='0.0.0.0', port=5000) 

问题原因

你代码的核心问题是绕开了yt-dlp的片段裁剪流程:

  • extract_info(url, download=False)只负责提取视频元数据和原始下载链接,不会触发任何裁剪操作
  • 后续你直接通过原始视频URL下载了完整视频,download_sections和force_keyframes_at_cuts这两个参数根本没机会生效——它们是yt-dlp在下载阶段才会执行的处理逻辑,不是提取信息阶段的。

解决方案

要让裁剪参数生效,必须让yt-dlp完整执行下载+裁剪流程,然后捕获处理后的视频内容返回。下面是修正后的代码,通过将yt-dlp的输出导向内存缓冲区来实现:

from flask import Flask, make_response, request
import yt_dlp
from flask_cors import CORS
import io
import sys

app = Flask(__name__, static_folder='static')

CORS(app, expose_headers=['Filename'])
 
@app.route("/downloadpart/", methods=['POST'])
def download_cut():
    if request.method == 'POST':
        url = request.form.get('link')  
        ydl_opts = {
            'format': 'best',
            'download_sections': "*00:02:05-00:02:10", 
            'force_keyframes_at_cuts': True,
            'quiet': True,          # 关闭日志,避免干扰视频内容
            'no_warnings': True,
            'outtmpl': '-',         # 将处理后的视频输出到stdout
            'noplaylist': True,     # 确保只处理单个视频
        }
        try:
            output_buffer = io.BytesIO()
            # 临时重定向stdout到缓冲区
            old_stdout = sys.stdout
            sys.stdout = output_buffer

            with yt_dlp.YoutubeDL(ydl_opts) as ydl:
                ydl.download([url])

            # 恢复stdout并读取缓冲区内容
            sys.stdout = old_stdout
            output_buffer.seek(0)
            video_data = output_buffer.read()

            headers = {
                'Content-Type': 'video/mp4',
                'Content-Disposition': 'attachment; filename="cut_video.mp4"'
            }
            return make_response(video_data, 200, headers)
        except Exception as e:
            return make_response(str(e), 500)
    return make_response("Invalid request", 400)


if __name__ == '__main__':
    app.run(debug=False, host='0.0.0.0', port=5000) 

关键改动说明

  1. 移除了extract_info直接拿原始链接的逻辑,改用ydl.download([url])让yt-dlp完整执行下载+裁剪
  2. 设置outtmpl: '-'让处理后的视频输出到标准输出,再通过内存缓冲区捕获内容
  3. 添加quiet和no_warnings避免日志内容混入视频数据
  4. 恢复标准输出,避免影响后续程序运行

这样就能让download_sections和force_keyframes_at_cuts参数正常生效,直接返回裁剪后的视频片段,不需要额外用FFmpeg后期处理。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 12:10:20