2024最新YT-DLP使用demo网页端渲染

前提摘要

2024最新python使用yt-dlp
在这里插入图片描述

1.使用python的fastapi库和jinjia2库进行前端渲染

需要下载下面对应的python第三方库
pip install fastapi uvicorn python-multipart jinja2 yt-dlp

功能如下
使用YT-DLP,缓存文件到本地,预览文件信息

在这里插入图片描述
在这里插入图片描述

2.代码实现

1)目录结构

在这里插入图片描述

2)代码

style.css

body {
    font-family: Arial, sans-serif;
    margin: 0;
    padding: 20px;
    background-color: #f0f0f0;
}

.container {
    max-width: 800px;
    margin: 0 auto;
    background-color: white;
    padding: 20px;
    border-radius: 8px;
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

/* 添加 logo 相关样式 */
.logo {
    display: flex;
    justify-content: center;
    gap: 8px;
    margin-bottom: 20px;
}

.youtube-icon, .download-icon {
    width: 32px;  /* 调整图标大小 */
    height: 32px; /* 调整图标大小 */
}

.header {
    text-align: center;
    margin-bottom: 30px;
}

h1 {
    font-size: 24px;
    margin: 10px 0;
}

.subtitle {
    color: #666;
    margin-bottom: 20px;
}

form {
    margin: 20px 0;
}

.input-group {
    display: flex;
    gap: 10px;
}

input[type="text"] {
    flex: 1;
    padding: 10px;
    border: 1px solid #ddd;
    border-radius: 4px;
}

button {
    background-color: #007bff;
    color: white;
    padding: 10px 20px;
    border: none;
    border-radius: 4px;
    cursor: pointer;
}

button:hover {
    background-color: #0056b3;
}

.disclaimer {
    text-align: center;
    color: #666;
    font-size: 14px;
    margin: 20px 0;
}

.info-icon {
    color: #007bff;
    cursor: help;
}

.footer {
    text-align: center;
    margin-top: 30px;
    color: #666;
    font-size: 14px;
}

index.html

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>YouTube 视频下载器</title>
    <link rel="stylesheet" href="{{ url_for('static', path='style.css') }}">
</head>
<body>
    <div class="container">
        <div class="header">
            <div class="logo">
                <svg class="youtube-icon" viewBox="0 0 24 24">
                    <path fill="#FF0000" d="M23.498 6.186a3.016 3.016 0 0 0-2.122-2.136C19.505 3.545 12 3.545 12 3.545s-7.505 0-9.377.505A3.017 3.017 0 0 0 .502 6.186C0 8.07 0 12 0 12s0 3.93.502 5.814a3.016 3.016 0 0 0 2.122 2.136c1.871.505 9.376.505 9.376.505s7.505 0 9.377-.505a3.015 3.015 0 0 0 2.122-2.136C24 15.93 24 12 24 12s0-3.93-.502-5.814zM9.545 15.568V8.432L15.818 12l-6.273 3.568z"/>
                </svg>
                <svg class="download-icon" viewBox="0 0 24 24">
                    <path fill="#4285f4" d="M19 9h-4V3H9v6H5l7 7 7-7zM5 18v2h14v-2H5z"/>
                </svg>
            </div>
            <h1>YT-DLP-DEMO</h1>
            <p class="subtitle">YTDownload</p>
        </div>

        <form action="/download" method="POST">
            <div class="input-group">
                <input type="text" 
                       name="url" 
                       placeholder="https://www.youtube.com/watch?v=..." 
                       required>
                <button type="submit">下载</button>
            </div>
        </form>

        <div class="footer">
            <p>由 FastAPI 和 yt-dlp 提供技术支持</p>
        </div>
    </div>
</body>
</html> 

result.html

<!DOCTYPE html>
<html>
<head>
    <title>Download Result</title>
    <link rel="stylesheet" href="{{ url_for('static', path='style.css') }}">
</head>
<body>
    <div class="container">
        {% if success %}
            <div class="result-info">
                <div class="video-header">
                    <div class="video-details">
                        <h2>{{ video_info.title }}</h2>
                        <div class="meta-info">
                            <p><strong>作者:</strong> {{ video_info.author }}</p>
                            <p><strong>时长:</strong> {{ video_info.length }}</p>
                            <p><strong>观看次数:</strong> {{ '{:,}'.format(video_info.views) }}</p>
                        </div>
                    </div>
                </div>
                
                <div class="download-sections">
                    <div class="preview-section">
                        <h3>视频预览</h3>
                        <div class="preview-container">
                            <video controls>
                                <source src="{{ video_path }}" type="video/mp4">
                                您的浏览器不支持视频标签。
                            </video>
                        </div>
                        <a href="{{ video_path }}" class="download-button" download>
                            <span class="icon"></span> 下载视频
                        </a>
                    </div>
                    
                    <div class="preview-section">
                        <h3>音频预览</h3>
                        <div class="preview-container">
                            <audio controls>
                                <source src="{{ audio_path }}" type="audio/mp4">
                                您的浏览器不支持音频标签。
                            </audio>
                        </div>
                        <a href="{{ audio_path }}" class="download-button" download>
                            <span class="icon"></span> 下载音频
                        </a>
                    </div>
                </div>
            </div>
        {% else %}
            <div class="error-container">
                <h2>下载失败</h2>
                <p class="error-message">{{ error }}</p>
            </div>
        {% endif %}
        
        <a href="/" class="back-button">返回首页</a>
    </div>
</body>
</html> 

main.py

from fastapi import FastAPI, Request, Form
from fastapi.templating import Jinja2Templates
from fastapi.staticfiles import StaticFiles
from fastapi.responses import FileResponse
import yt_dlp
from pathlib import Path
import os

app = FastAPI()

# 配置静态文件和模板
app.mount("/static", StaticFiles(directory="static"), name="static")
templates = Jinja2Templates(directory="templates")

# 配置下载目录
VIDEO_DIR = Path("downloads/video")
AUDIO_DIR = Path("downloads/audio")
VIDEO_DIR.mkdir(parents=True, exist_ok=True)
AUDIO_DIR.mkdir(parents=True, exist_ok=True)

def download_youtube_video(url):
    try:
        # yt-dlp 基础配置
        common_opts = {
            'cookiefile': r'www.youtube.com_cookies.txt',
            'quiet': False,
            'no_warnings': False,
            'verbose': True,
            'proxy': 'http://127.0.0.1:10809',
            'socket_timeout': 30,
            'retries': 3,
            'nocheckcertificate': True,
            'prefer_insecure': True
        }

        # 视频下载选项
        video_opts = {
            **common_opts,
            'format': 'best[ext=mp4][height<=720]/best[height<=720]/best',
            'outtmpl': str(VIDEO_DIR / '%(title)s.%(ext)s'),
        }

        # 音频下载选项
        audio_opts = {
            **common_opts,
            'format': 'bestaudio[ext=m4a]/bestaudio',
            'outtmpl': str(AUDIO_DIR / '%(title)s.%(ext)s'),
        }

        # 获取视频信息
        with yt_dlp.YoutubeDL(common_opts) as ydl:
            info = ydl.extract_info(url, download=False)
            title = info['title']
            duration = info['duration']
            thumbnail = info['thumbnail']
            author = info.get('uploader', 'Unknown')
            views = info.get('view_count', 0)

        # 下载视频
        with yt_dlp.YoutubeDL(video_opts) as ydl:
            ydl.download([url])

        # 下载音频
        with yt_dlp.YoutubeDL(audio_opts) as ydl:
            ydl.download([url])

        # 获取下载后的文件路径
        video_file = next(VIDEO_DIR.glob(f"{title}.*"))
        audio_file = next(AUDIO_DIR.glob(f"{title}.*"))

        return {
            "status": "success",
            "title": title,
            "author": author,
            "duration": f"{duration // 60}:{duration % 60:02d}",
            "views": views,
            "thumbnail": thumbnail,
            "video_path": str(video_file.name),
            "audio_path": str(audio_file.name)
        }
    except Exception as e:
        return {"status": "error", "message": str(e)}

@app.get("/")
async def home(request: Request):
    return templates.TemplateResponse("index.html", {"request": request})

@app.post("/download")
async def download_video_route(request: Request, url: str = Form(...)):
    try:
        result = download_youtube_video(url)
        
        if result["status"] == "success":
            video_info = {
                "title": result["title"],
                "author": result["author"],
                "length": result["duration"],
                "views": result["views"],
                "thumbnail": result["thumbnail"]
            }
            
            return templates.TemplateResponse("result.html", {
                "request": request,
                "video_info": video_info,
                "video_path": f"/downloads/video/{result['video_path']}",
                "audio_path": f"/downloads/audio/{result['audio_path']}",
                "success": True
            })
        else:
            raise Exception(result["message"])
            
    except Exception as e:
        return templates.TemplateResponse("result.html", {
            "request": request,
            "error": str(e),
            "success": False
        })

# 配置下载目录的静态文件服务
app.mount("/downloads", StaticFiles(directory="downloads"), name="downloads") 

run.py

import uvicorn
import os

def check_directories():
    """确保必要的目录存在"""
    directories = [
        'static',
        'templates',
        'downloads',
        'downloads/video',
        'downloads/audio'
    ]
    for directory in directories:
        if not os.path.exists(directory):
            os.makedirs(directory)
            print(f"Created directory: {directory}")

if __name__ == "__main__":
    # 检查并创建必要的目录
    check_directories()
    
    # 配置并启动服务器
    uvicorn.run(
        "main:app", 
        host="127.0.0.1", 
        port=8000, 
        reload=True,
        reload_dirs=["templates", "static"],
        log_level="info"
    ) 

3)运行测试

命令端运行

pip install fastapi uvicorn python-multipart jinja2 yt-dlp

在这里插入图片描述

python run.py

在这里插入图片描述

3.项目下载地址

https://github.com/unkownc/python_demo/tree/main
在这里插入图片描述

<think>好的,用户想了解如何在Python使用yt-dlp进行视频下载或其他媒体处理操作。我需要根据提供的引用内容,特别是引用[1]、[2]、[3]中的信息,来构建一个清晰的中文回答。首先,用户需要安装yt-dlp库,引用[1]提到了使用pip安装的步骤,这里需要详细说明安装过程,包括可能的虚拟环境设置。然后,引用[2]提供了yt-dlp的GitHub地址,可以引导用户查看官方文档获取更多选项。接下来,用户可能需要基本的使用示例,比如下载视频、获取信息、选择格式等。同时,引用[3]提到了opencv-contrib-python的安装,但用户的问题主要集中在yt-dlp,所以可能暂时不需要涉及这部分,除非用户有后续处理视频的需求,比如用OpenCV处理下载的视频,这时候可以简要提及。此外,需要确保回答中的代码示例正确,并遵循用户给出的LaTeX格式要求,不过问题本身主要涉及代码,可能数学公式较少。另外,用户要求生成相关问题,我需要考虑用户可能感兴趣的扩展问题,比如高级参数、进度条集成、错误处理等。还要注意引用标识的正确添加,例如在提到安装步骤时引用[^1],在介绍项目背景时引用[^2]。最后,回答需要结构清晰,分步骤说明,确保用户能够逐步操作,同时保持回答的真实可靠,基于提供的引用内容。</think>### 如何在Python使用yt-dlp下载视频或处理媒体? #### 1. **安装yt-dlp库** - 使用conda或venv创建虚拟环境(推荐): ```bash conda create -n videodownload python=3.9 conda activate videodownload ``` - 通过pip安装yt-dlp: ```bash pip install yt-dlp ``` 这一步骤在引用中已明确说明。 #### 2. **基本视频下载** ```python import yt_dlp def download_video(url): ydl_opts = {} with yt_dlp.YoutubeDL(ydl_opts) as ydl: ydl.download([url]) download_video("https://www.youtube.com/watch?v=example") ``` - 此代码会下载指定URL的最高质量视频和音频(默认合并为MP4)[^2]。 #### 3. **自定义下载选项** ```python ydl_opts = { 'format': 'bestvideo[ext=mp4]+bestaudio[ext=m4a]/best[ext=mp4]/best', # 指定格式 'outtmpl': 'downloads/%(title)s.%(ext)s', # 输出路径模板 'merge_output_format': 'mp4', # 合并格式 'writethumbnail': True # 下载缩略图 } ``` - 支持200+参数,详见[官方文档](https://github.com/yt-dlp/yt-dlp)[^2]。 #### 4. **获取视频元数据** ```python def get_info(url): ydl_opts = {} with yt_dlp.YoutubeDL(ydl_opts) as ydl: info = ydl.extract_info(url, download=False) print(f"标题: {info['title']}") print(f"时长: {info['duration']}秒") ``` - 可用于分析视频信息后再决定是否下载。 #### 5. **批量下载与高级功能** ```python ydl_opts = { 'playlist_items': '1-10', # 下载播放列表前10个 'subtitleslangs': ['en'], # 下载英文字幕 'embedthumbnail': True # 将缩略图嵌入视频文件 } ``` - 支持播放列表、字幕、章节提取等功能。 #### 6. **结合其他库处理媒体** 若需进一步处理下载的视频(如剪辑、分析),可安装`opencv-python`: ```bash pip install opencv-contrib-python # 引用[^3] ``` ```python import cv2 cap = cv2.VideoCapture("downloaded_video.mp4") ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值