当前位置: 首页 > news >正文

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

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

  • 前提摘要
  • 1.使用python的fastapi库和jinjia2库进行前端渲染
  • 2.代码实现
    • 1)目录结构
    • 2)代码
      • style.css
      • index.html
      • result.html
      • main.py
      • run.py
    • 3)运行测试
      • 命令端运行
  • 3.项目下载地址

前提摘要

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 osapp = 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 osdef 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
在这里插入图片描述

相关文章:

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

2024最新YT-DLP使用demo网页端渲染 前提摘要1.使用python的fastapi库和jinjia2库进行前端渲染2.代码实现1&#xff09;目录结构2&#xff09;代码style.cssindex.htmlresult.htmlmain.pyrun.py 3&#xff09;运行测试命令端运行 3.项目下载地址 前提摘要 2024最新python使用yt…...

《第十部分》1.STM32之通信接口《精讲》之IIC通信---介绍

经过近一周的USART学习&#xff0c;我深刻体会到通信对单片机的重要性。它就像人类的手脚和大脑&#xff0c;只有掌握了通信技术&#xff0c;单片机才能与外界交互&#xff0c;展现出丰富多彩的功能&#xff0c;变得更加强大和实用。 单片机最基础的“语言”是二进制。可惜&am…...

wireshark使用lua解析自定义协议

wireshark解析自定义协议 1.自定义的lua放入路径2.修改init.lua2.1 开启lua2.2 init.lua文件最后加入自己的lua文件位置&#xff0c;这里需要确保与自己的文件名相同 3.编写lua4.编写c抓包5.wireshark添加自定义协议如何加调试信息 1.自定义的lua放入路径 一般是自己软件的安装…...

(Keil)MDK-ARM各种优化选项详细说明、实际应用及拓展内容

参考 MDK-ARM各种优化选项详细说明、实际应用及拓展内容 本文围绕MDK-ARM优化选项,以及相关拓展知识(微库、实际应用、调试)进行讲述,希望对你今后开发项目有所帮助。 1 总述 我们所指的优化,主要两方面: 1.代码大小(Size) 2.代码性能(运行时间) 在MDK-ARM中,优…...

Qt实现可拖拽的矩形

之前项目上需要用Qt来绘制可拖拽改变形状的矩形。看了Qt Graphics相关的内容&#xff0c;虽然对Qt怎么添加图元的有了些了解&#xff0c;但是具体如何实现拖拽效果&#xff0c;一时也没有什么好的想法。还好网上有人分享的例子&#xff0c;很受启发。后来又回顾了一下这部分的代…...

CentOS:A服务器主动给B服务器推送(上传),B服务器下载A服务器文件(下载)

Linux:常识(bash: ip command not found )_bash: ip: command not found-CSDN博客 rsync 中断后先判断程序是否自动重连:ps aux | grep rsync 查看目录/文件是否被使用(查询线程占用):lsof /usr/local/bin/mongodump/.B_database1.6uRCTp 场景:MongoDB中集合非常大需要…...

Oracle 执行计划查看方法汇总及优劣对比

在 Oracle 数据库中&#xff0c;查看执行计划是优化 SQL 语句性能的重要工具。以下是几种常用的查看执行计划的方法及其优劣比较&#xff1a; 1. 使用 EXPLAIN PLAN FOR 和 DBMS_XPLAN.DISPLAY 方法 执行 EXPLAIN PLAN FOR 语句&#xff1a; EXPLAIN PLAN FOR SELECT * FROM …...

TCL大数据面试题及参考答案

Mysql 索引失效的场景 对索引列进行运算或使用函数:当在索引列上进行数学运算、函数操作等,索引可能失效。例如,在存储年龄的列上建立了索引,若查询语句是 “SELECT * FROM table WHERE age + 1 = 20”,这里对索引列 age 进行了加法运算,数据库会放弃使用索引而进行全表扫…...

九、FOC原理详解

1、FOC简介 FOC&#xff08;field-oriented control&#xff09;为磁场定向控制&#xff0c;又称为矢量控制&#xff08;vectorcontrol&#xff09;&#xff0c;是目前无刷直流电机&#xff08;BLDC&#xff09;和永磁同步电机&#xff08;PMSM&#xff09;高效控制的最佳选择…...

vue页面成绩案例(for渲染表格/删除/添加/统计总分/平均分/不及格显红色/输入内容去首尾空格trim/输入内容转数字number)

1.使用v-if 和v-else 完成<tbody>标签的条件渲染 2.v-for完成列表渲染 3.:class完成分数标红的条件控制 删哪个就传哪个的id&#xff0c;基于这个id去过滤掉相同id的项&#xff0c;把剩下的项返回 a标签的默认点击事件会跳转 这里要禁止默认事件 即使用click.provent 就…...

STM32编程小工具FlyMcu和STLINK Utility 《通俗易懂》破解

FlyMcu FlyMcu 模拟仿真软件是一款用于 STM32 芯片 ISP 串口烧录程序的专用工具&#xff0c;免费&#xff0c;且较为非常容易下手&#xff0c;好用便捷。 注意&#xff1a;STM32 芯片的 ISP 下载&#xff0c;只能使用串口1&#xff08;USART1&#xff09;&#xff0c;对应的串口…...

Centos使用docker搭建Graylog日志平台

日志管理系统有很多&#xff0c;比如ELK,Graylog&#xff0c;LokiGrafanaPromtail 适用场景&#xff1a; 1.如果需求复杂&#xff0c;服务器资源不受限制&#xff0c;推荐使用ELK&#xff08;Logstash Elasticsearch Kibana&#xff09;方案&#xff1b; 2.如果需求仅是将…...

自定义 Kafka 脚本 kf-use.sh 的解析与功能与应用示例

Kafka&#xff1a;分布式消息系统的核心原理与安装部署-CSDN博客 自定义 Kafka 脚本 kf-use.sh 的解析与功能与应用示例-CSDN博客 Kafka 生产者全面解析&#xff1a;从基础原理到高级实践-CSDN博客 Kafka 生产者优化与数据处理经验-CSDN博客 Kafka 工作流程解析&#xff1a…...

【SQL】【数据库】语句翻译例题

SQL自然语言到SQL翻译知识点 以下是将自然语言转化为SQL语句的所有相关知识点&#xff0c;分门别类详细列出&#xff0c;并结合技巧说明。 1. 数据库操作 创建数据库 自然语言&#xff1a;创建一个名为“TestDB”的数据库。 CREATE DATABASE TestDB;技巧&#xff1a;识别**“创…...

linux基本命令2

7. 文件查找和搜索 (继续) find — 查找文件 find /path/to/search -name "file_name" # 根据名称查找文件 find /path/to/search -type f # 查找所有普通文件 find /path/to/search -type d # 查找所有目录 find /path/to/search -name "*.txt" # 查找…...

Spring Boot项目集成Redisson 原始依赖与 Spring Boot Starter 的流程

Redisson 是一个高性能的 Java Redis 客户端&#xff0c;提供了丰富的分布式工具集&#xff0c;如分布式锁、Map、Queue 等&#xff0c;帮助开发者简化 Redis 的操作。在集成 Redisson 到项目时&#xff0c;开发者通常有两种选择&#xff1a; 使用 Redisson 原始依赖。使用 Re…...

Git命令使用与原理详解

1.仓库 # 在当前目录新建一个Git代码库 $ git init ​ # 新建一个目录&#xff0c;将其初始化为Git代码库 $ git init [project-name] ​ # 下载一个项目和它的整个代码历史 $ git clone [url]2.配置 # 显示当前的Git配置 $ git config --list ​ # 编辑Git配置文件 $ git co…...

Linux:自定义Shell

本文旨在通过自己完成一个简单的Shell来帮助理解命令行Shell这个程序。 目录 一、输出“提示” 二、获取输入 三、切割字符串 四、执行指令 1.子进程替换 2.内建指令 一、输出“提示” 这个项目基于虚拟机Ubuntu22.04.5实现。 打开终端界面如图所示。 其中。 之前&#x…...

vue项目中中怎么获取环境变量

在 Vue 项目中&#xff0c;有几种获取环境变量的方法。最常用的是通过 import.meta.env 来访问。 1.首先在项目根目录创建环境变量文件&#xff1a; .env # 所有环境都会加载 .env.development # 开发环境 .env.production # 生产环境2.在环境变量文件…...

C#里怎么样使用正则表达式?

C#里怎么样使用正则表达式? 正则表达式是由普通字符(如英文字母)以及特殊字符(也称为元字符)组成的一种文字模式 这种文字模式可用于检查字符串的值是否满足一定的规则,例如: 验证输入的邮箱是否合法 输入的身份证号码是否合法 输入的用户名是否满足条件等 也可以…...

论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(二)

HoST框架核心实现方法详解 - 论文深度解读(第二部分) 《Learning Humanoid Standing-up Control across Diverse Postures》 系列文章: 论文深度解读 + 算法与代码分析(二) 作者机构: 上海AI Lab, 上海交通大学, 香港大学, 浙江大学, 香港中文大学 论文主题: 人形机器人…...

JavaScript 中的 ES|QL:利用 Apache Arrow 工具

作者&#xff1a;来自 Elastic Jeffrey Rengifo 学习如何将 ES|QL 与 JavaScript 的 Apache Arrow 客户端工具一起使用。 想获得 Elastic 认证吗&#xff1f;了解下一期 Elasticsearch Engineer 培训的时间吧&#xff01; Elasticsearch 拥有众多新功能&#xff0c;助你为自己…...

深入浅出:JavaScript 中的 `window.crypto.getRandomValues()` 方法

深入浅出&#xff1a;JavaScript 中的 window.crypto.getRandomValues() 方法 在现代 Web 开发中&#xff0c;随机数的生成看似简单&#xff0c;却隐藏着许多玄机。无论是生成密码、加密密钥&#xff0c;还是创建安全令牌&#xff0c;随机数的质量直接关系到系统的安全性。Jav…...

Element Plus 表单(el-form)中关于正整数输入的校验规则

目录 1 单个正整数输入1.1 模板1.2 校验规则 2 两个正整数输入&#xff08;联动&#xff09;2.1 模板2.2 校验规则2.3 CSS 1 单个正整数输入 1.1 模板 <el-formref"formRef":model"formData":rules"formRules"label-width"150px"…...

Mobile ALOHA全身模仿学习

一、题目 Mobile ALOHA&#xff1a;通过低成本全身远程操作学习双手移动操作 传统模仿学习&#xff08;Imitation Learning&#xff09;缺点&#xff1a;聚焦与桌面操作&#xff0c;缺乏通用任务所需的移动性和灵活性 本论文优点&#xff1a;&#xff08;1&#xff09;在ALOHA…...

算法笔记2

1.字符串拼接最好用StringBuilder&#xff0c;不用String 2.创建List<>类型的数组并创建内存 List arr[] new ArrayList[26]; Arrays.setAll(arr, i -> new ArrayList<>()); 3.去掉首尾空格...

Python ROS2【机器人中间件框架】 简介

销量过万TEEIS德国护膝夏天用薄款 优惠券冠生园 百花蜂蜜428g 挤压瓶纯蜂蜜巨奇严选 鞋子除臭剂360ml 多芬身体磨砂膏280g健70%-75%酒精消毒棉片湿巾1418cm 80片/袋3袋大包清洁食品用消毒 优惠券AIMORNY52朵红玫瑰永生香皂花同城配送非鲜花七夕情人节生日礼物送女友 热卖妙洁棉…...

智能AI电话机器人系统的识别能力现状与发展水平

一、引言 随着人工智能技术的飞速发展&#xff0c;AI电话机器人系统已经从简单的自动应答工具演变为具备复杂交互能力的智能助手。这类系统结合了语音识别、自然语言处理、情感计算和机器学习等多项前沿技术&#xff0c;在客户服务、营销推广、信息查询等领域发挥着越来越重要…...

Go 语言并发编程基础:无缓冲与有缓冲通道

在上一章节中&#xff0c;我们了解了 Channel 的基本用法。本章将重点分析 Go 中通道的两种类型 —— 无缓冲通道与有缓冲通道&#xff0c;它们在并发编程中各具特点和应用场景。 一、通道的基本分类 类型定义形式特点无缓冲通道make(chan T)发送和接收都必须准备好&#xff0…...

Python Ovito统计金刚石结构数量

大家好,我是小马老师。 本文介绍python ovito方法统计金刚石结构的方法。 Ovito Identify diamond structure命令可以识别和统计金刚石结构,但是无法直接输出结构的变化情况。 本文使用python调用ovito包的方法,可以持续统计各步的金刚石结构,具体代码如下: from ovito…...