3208 字
16 分钟
使用yt-dlp下载互联网上的任何音视频 | FFmpeg | Python
2026-04-13
--
基于pip中的yt-dlp工具包打造的快速获取音频(AAC编码m4a)、视频(H.264编码mp4)脚本。

相关链接#

  • yt-dlp — 视频下载核心(上游仓库)
  • ffmpeg — 视频合并与转码

yt-dlp 实用工具集#

基于 yt-dlp 封装的 Python 脚本工具集,提供一键下载、自动转码功能。

脚本说明#

依赖#

  • Python 3.10+
  • FFmpeg

安装 yt-dlp 完整版:

Terminal window
pip install "yt-dlp[default]"

quick_grab.py — 快速获取视频#

下载任意网站视频,自动确保输出为 H.264 + AAC 的 MP4 文件。

特性:

  • 自动检测并使用 GPU 硬件加速(NVIDIA NVENC / AMD AMF / Intel QSV),无 GPU 回退 CPU
  • 探测源视频码率,按源码率匹配目标画质,避免转码后文件暴涨
  • 支持断点续传,网络中断后重新运行可从上次位置继续
  • 内置失败重试(10 次重试 + 指数退避)

基本用法:

Terminal window
# 下载最高画质(自动转码为 H.264 MP4)
python quick_grab.py "https://www.youtube.com/watch?v=VIDEO_ID"
# 指定输出目录
python quick_grab.py "URL" -d D:/Downloads
# 下载 720P
python quick_grab.py "URL" -q 720
# 仅下载音频
python quick_grab.py "URL" --audio
# 下载中英字幕
python quick_grab.py "URL" --subtitle
# 下载整个播放列表
python quick_grab.py "URL" --playlist
# 自定义编码质量(CRF 越小质量越高,默认 23)
python quick_grab.py "URL" --crf 18 --preset slow
# 强制使用 CPU 编码(禁用 GPU 加速)
python quick_grab.py "URL" --no-gpu
# 指定输出文件名
python quick_grab.py "URL" -o "my_video.mp4"

转码流程:

  1. yt-dlp 下载视频(自动合并视频+音频流)
  2. ffprobe 检测编码格式
  3. 如果已经是 H.264 + AAC + MP4 → 跳过(无需转码)
  4. 如果编码正确但容器非 MP4 → 仅 remux(无损,极快)
  5. 如果需要转码 → 自动探测源码率,按源码率匹配目标画质:
    • NVENC-rc vbr -cq -b:v {源码率}k -maxrate {源码率}k
    • AMF/QSV:类似 VBR 码率控制
    • CPU:高码率用 -b:v 码率模式,低/未知码率用 -crf 质量模式
    • 低码率(< 2000k)自动降低 CRF 至 20 以保画质

quick_audio.py — 快速获取音频#

下载任意网站音频,转为 AAC 编码的 M4A 文件,兼容 iPhone / Android / Windows / Mac / 车载等所有主流播放器。

基本用法:

Terminal window
# 下载音频,输出 AAC/M4A (192kbps)
python quick_audio.py "https://www.youtube.com/watch?v=VIDEO_ID"
# 指定输出目录
python quick_audio.py "URL" -d D:/Downloads
# 320kbps 高音质
python quick_audio.py "URL" -b 320
# 输出 MP3 格式(兼容极老旧设备)
python quick_audio.py "URL" --mp3
# 下载整个播放列表的音频
python quick_audio.py "URL" --playlist

脚本内容#

quick_grab.py#

"""
快速获取 - 使用 yt-dlp 下载任意网站视频,确保输出 H.264 + AAC MP4
ffmpeg 调用链:
1. yt-dlp 内部调用 ffmpeg 合并分离的视频/音频流 (自动, -c copy)
2. 脚本调用 ffprobe 检测编码格式
3. 自动检测 GPU (NVIDIA NVENC), 优先使用硬件加速转码
4. 如需转码, 有 GPU 时用 h264_nvenc, 无 GPU 时用 libx264 + aac
5. 如编码已正确但容器非 mp4, 仅做 remux (-c copy 到 mp4 容器)
用法:
python quick_grab.py <URL>
python quick_grab.py <URL> -d D:/Downloads
python quick_grab.py <URL> --audio
python quick_grab.py <URL> -q 720
python quick_grab.py <URL> --crf 18 --preset slow # 高质量转码
"""
import argparse
import io
import os
import subprocess
import sys
# Fix Windows console encoding
if sys.platform == "win32":
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding="utf-8", errors="replace")
sys.stderr = io.TextIOWrapper(sys.stderr.buffer, encoding="utf-8", errors="replace")
# ---------------------------------------------------------------------------
# ffmpeg / ffprobe helpers
# ---------------------------------------------------------------------------
def probe_codecs(filepath: str) -> tuple[str, str]:
"""用 ffprobe 检测视频和音频编码格式"""
result = subprocess.run(
["ffprobe", "-v", "error",
"-show_entries", "stream=codec_type,codec_name",
"-of", "csv=p=0", filepath],
capture_output=True, text=True, timeout=10,
encoding="utf-8", errors="replace",
)
vcodec = acodec = "none"
for line in result.stdout.strip().split("\n"):
# ffprobe csv=p=0 输出格式: codec_name,codec_type (如 "h264,video")
parts = line.strip().split(",")
if len(parts) == 2:
cname, ctype = parts
if ctype == "video":
vcodec = cname
elif ctype == "audio":
acodec = cname
return vcodec, acodec
def remux_to_mp4(input_path: str) -> bool:
"""仅更换容器为 mp4 (不重新编码, 极快)"""
output_path = os.path.splitext(input_path)[0] + ".mp4"
if input_path == output_path:
return True
cmd = [
"ffmpeg", "-i", input_path,
"-c", "copy", "-movflags", "+faststart",
"-y", output_path,
]
result = subprocess.run(cmd)
if result.returncode == 0 and os.path.isfile(output_path):
os.remove(input_path)
return True
if os.path.isfile(output_path):
os.remove(output_path)
return False
def _detect_nvenc() -> bool:
"""检测 ffmpeg 是否支持 NVIDIA NVENC 硬件编码"""
try:
result = subprocess.run(
["ffmpeg", "-hide_banner", "-encoders"],
capture_output=True, text=True, timeout=10,
encoding="utf-8", errors="replace",
)
return "h264_nvenc" in result.stdout
except (FileNotFoundError, subprocess.TimeoutExpired):
return False
def _detect_hardware_encoder() -> str:
"""检测可用的硬件编码器, 返回编码器名称 (h264_nvenc / h264_amf / h264_qsv / libx264)"""
try:
result = subprocess.run(
["ffmpeg", "-hide_banner", "-encoders"],
capture_output=True, text=True, timeout=10,
encoding="utf-8", errors="replace",
)
for enc in ("h264_nvenc", "h264_amf", "h264_qsv"):
if enc in result.stdout:
return enc
except (FileNotFoundError, subprocess.TimeoutExpired):
pass
return "libx264"
def _probe_source_bitrate(filepath: str) -> int:
"""获取源视频流码率 (kbps), 获取失败返回 0"""
# 优先从流信息获取
try:
result = subprocess.run(
["ffprobe", "-v", "error",
"-select_streams", "v:0",
"-show_entries", "stream=bit_rate",
"-of", "csv=p=0", filepath],
capture_output=True, text=True, timeout=10,
encoding="utf-8", errors="replace",
)
br = result.stdout.strip()
if br and br not in ("N/A", ""):
return int(br) // 1000 # bps → kbps
except (FileNotFoundError, subprocess.TimeoutExpired, ValueError):
pass
# 回退: 从文件大小 × 时长估算
try:
result = subprocess.run(
["ffprobe", "-v", "error",
"-show_entries", "format=duration",
"-of", "csv=p=0", filepath],
capture_output=True, text=True, timeout=10,
encoding="utf-8", errors="replace",
)
duration = float(result.stdout.strip())
file_size = os.path.getsize(filepath)
return int(file_size * 8 / duration * 0.85 / 1000) # 视频约占85%
except (FileNotFoundError, subprocess.TimeoutExpired, ValueError, OSError):
return 0
def transcode(input_path: str, crf: int = 23, preset: str = "medium",
use_gpu: bool = True) -> bool:
"""转码为 H.264 + AAC MP4 (参考源码率匹配画质, 优先硬件加速)"""
base, ext = os.path.splitext(input_path)
output_path = base + "_h264_tmp.mp4"
# 探测源视频码率
source_kbps = _probe_source_bitrate(input_path)
# CRF 根据源码率调整: 低码率用更高质量
crf_value = 20 if 0 < source_kbps < 2000 else crf
# 缓冲区 = 码率 × 2
buf_kbps = source_kbps * 2 if source_kbps > 0 else 0
# 选择编码器
encoder = _detect_hardware_encoder() if use_gpu else "libx264"
# --- NVENC ---
if encoder == "h264_nvenc":
_preset_map = {
"ultrafast": "p1", "superfast": "p1", "veryfast": "p2",
"faster": "p3", "fast": "p4", "medium": "p4",
"slow": "p5", "slower": "p7", "veryslow": "p7",
}
nvenc_preset = _preset_map.get(preset, "p4")
if source_kbps > 0:
print(f" [GPU/NVENC] 源码率: {source_kbps}k | 目标: {source_kbps}k | cq={crf_value} | preset={nvenc_preset}")
cmd = [
"ffmpeg", "-i", input_path,
"-c:v", "h264_nvenc", "-preset", nvenc_preset,
"-rc", "vbr", "-cq", str(crf_value),
"-b:v", f"{source_kbps}k", "-maxrate", f"{source_kbps}k", "-bufsize", f"{buf_kbps}k",
"-c:a", "aac", "-b:a", "192k",
"-movflags", "+faststart", "-y", output_path,
]
else:
print(f" [GPU/NVENC] 未知源码率 | cq={crf_value} | preset={nvenc_preset}")
cmd = [
"ffmpeg", "-i", input_path,
"-c:v", "h264_nvenc", "-preset", nvenc_preset,
"-rc", "vbr", "-cq", str(crf_value),
"-c:a", "aac", "-b:a", "192k",
"-movflags", "+faststart", "-y", output_path,
]
# --- AMD AMF ---
elif encoder == "h264_amf":
if source_kbps > 0:
print(f" [GPU/AMF] 源码率: {source_kbps}k | 目标: {source_kbps}k")
cmd = [
"ffmpeg", "-i", input_path,
"-c:v", "h264_amf", "-quality", "speed", "-rc", "vbr",
"-b:v", f"{source_kbps}k", "-maxrate", f"{source_kbps}k", "-bufsize", f"{buf_kbps}k",
"-c:a", "aac", "-b:a", "192k",
"-movflags", "+faststart", "-y", output_path,
]
else:
print(f" [GPU/AMF] 未知源码率")
cmd = [
"ffmpeg", "-i", input_path,
"-c:v", "h264_amf", "-quality", "speed", "-rc", "vbr",
"-c:a", "aac", "-b:a", "192k",
"-movflags", "+faststart", "-y", output_path,
]
# --- Intel QSV ---
elif encoder == "h264_qsv":
if source_kbps > 0:
print(f" [GPU/QSV] 源码率: {source_kbps}k | 目标: {source_kbps}k | quality={crf_value}")
cmd = [
"ffmpeg", "-i", input_path,
"-c:v", "h264_qsv", "-preset", "medium",
"-b:v", f"{source_kbps}k", "-maxrate", f"{source_kbps}k", "-bufsize", f"{buf_kbps}k",
"-global_quality", str(crf_value),
"-c:a", "aac", "-b:a", "192k",
"-movflags", "+faststart", "-y", output_path,
]
else:
print(f" [GPU/QSV] 未知源码率 | quality={crf_value}")
cmd = [
"ffmpeg", "-i", input_path,
"-c:v", "h264_qsv", "-preset", "medium",
"-global_quality", str(crf_value),
"-c:a", "aac", "-b:a", "192k",
"-movflags", "+faststart", "-y", output_path,
]
# --- CPU libx264 ---
else:
if source_kbps > 0 and source_kbps >= 2000:
print(f" [CPU/x264] 源码率: {source_kbps}k | 目标: {source_kbps}k | preset={preset}")
cmd = [
"ffmpeg", "-i", input_path,
"-c:v", "libx264", "-preset", preset,
"-b:v", f"{source_kbps}k", "-maxrate", f"{source_kbps}k", "-bufsize", f"{buf_kbps}k",
"-c:a", "aac", "-b:a", "192k",
"-movflags", "+faststart", "-y", output_path,
]
else:
print(f" [CPU/x264] 未知/低码率 | crf={crf_value} | preset={preset}")
cmd = [
"ffmpeg", "-i", input_path,
"-c:v", "libx264", "-preset", preset, "-crf", str(crf_value),
"-c:a", "aac", "-b:a", "192k",
"-movflags", "+faststart", "-y", output_path,
]
result = subprocess.run(cmd)
if result.returncode == 0 and os.path.isfile(output_path):
os.replace(output_path, base + ".mp4")
# 清理原始文件 (如果扩展名不同)
original = input_path
if os.path.isfile(original) and original != base + ".mp4":
os.remove(original)
return True
if os.path.isfile(output_path):
os.remove(output_path)
return False
# ---------------------------------------------------------------------------
# yt-dlp helpers
# ---------------------------------------------------------------------------
def _progress_hook(d: dict):
"""yt-dlp 下载进度回调"""
if d["status"] == "downloading":
pct = d.get("_percent_str", "?")
spd = d.get("_speed_str", "?")
eta = d.get("_eta_str", "?")
print(f"\r 下载中: {pct} | 速度: {spd} | 剩余: {eta}", end="", flush=True)
elif d["status"] == "finished":
print("\n 下载完成,正在合并...")
def _find_output_file(ydl, info: dict) -> str | None:
"""根据 yt-dlp info 定位实际输出文件"""
expected = ydl.prepare_filename(info)
if os.path.isfile(expected):
return expected
# 合并后扩展名可能变为 mp4
base, _ = os.path.splitext(expected)
for ext in (".mp4", ".mkv", ".webm", ".ts"):
if os.path.isfile(base + ext):
return base + ext
return None
# ---------------------------------------------------------------------------
# 主流程
# ---------------------------------------------------------------------------
def grab(url: str, output_dir: str = ".", output_name: str | None = None,
audio_only: bool = False, quality: int | None = None,
playlist: bool = False, subtitle: bool = False,
crf: int = 23, preset: str = "medium", use_gpu: bool = True) -> int:
"""下载视频并确保 H.264 + AAC MP4 输出"""
try:
import yt_dlp
except ImportError:
print("错误: 未安装 yt-dlp,请先执行 pip install yt-dlp")
return 1
os.makedirs(output_dir, exist_ok=True)
outtmpl = (os.path.join(output_dir, output_name) if output_name
else os.path.join(output_dir, "%(title)s.%(ext)s"))
ydl_opts: dict = {
"outtmpl": outtmpl,
"progress_hooks": [_progress_hook],
# 断点续传 & 重试
"continuedl": True,
"retries": 10,
"fragment_retries": 10,
"file_access_retries": 10,
"retry_sleep_functions": {"http": 5, "fragment": 5, "file_access": 3},
}
# 格式选择
if audio_only:
ydl_opts["format"] = "bestaudio/best"
ydl_opts["postprocessors"] = [{
"key": "FFmpegExtractAudio",
"preferredcodec": "best",
}]
elif quality:
ydl_opts["format"] = (
f"bestvideo[height<={quality}]+bestaudio"
f"/best[height<={quality}]/best"
)
ydl_opts["merge_output_format"] = "mp4"
else:
ydl_opts["format"] = "bestvideo+bestaudio/best"
ydl_opts["merge_output_format"] = "mp4"
if not playlist:
ydl_opts["noplaylist"] = True
if subtitle:
ydl_opts["writesubs"] = True
ydl_opts["writeautomaticsub"] = True
ydl_opts["subtitleslangs"] = ["zh", "en"]
print(f"\n正在获取: {url}\n")
with yt_dlp.YoutubeDL(ydl_opts) as ydl:
info = ydl.extract_info(url, download=True)
if info is None:
print("错误: 无法获取视频信息")
return 1
# --- 后处理: 确保 H.264 + AAC MP4 ---
if audio_only:
print("\n音频模式,跳过视频编码检查。")
else:
# 收集所有需要检查的文件
if "entries" in info:
entries = [e for e in info["entries"] if e]
else:
entries = [info]
print("\n[ 编码检查 ]")
for entry in entries:
filepath = _find_output_file(ydl, entry)
if not filepath:
continue
vcodec, acodec = probe_codecs(filepath)
name = os.path.basename(filepath)
print(f" {name}")
print(f" 视频编码: {vcodec} | 音频编码: {acodec}")
is_h264 = vcodec == "h264"
is_aac = acodec in ("aac", "none")
is_mp4 = filepath.lower().endswith(".mp4")
if is_h264 and is_aac and is_mp4:
print(" ✓ 已是 H.264 + AAC MP4,跳过")
elif is_h264 and is_aac and not is_mp4:
print(" → 编码正确,封装为 MP4...")
if remux_to_mp4(filepath):
print(" ✓ 封装完成 (remux, 无损)")
else:
print(" ✗ 封装失败,保留原始文件")
else:
print(f" → 需要转码 ({vcodec}/{acodec} → h264/aac)...")
if transcode(filepath, crf=crf, preset=preset, use_gpu=use_gpu):
print(" ✓ 转码完成")
else:
print(" ✗ 转码失败,保留原始文件")
print("\n全部完成!")
return 0
def main():
p = argparse.ArgumentParser(
description="快速获取 - 下载任意网站视频 (H.264 + AAC MP4)",
)
p.add_argument("url", help="视频 URL")
p.add_argument("-o", "--output", help="输出文件名")
p.add_argument("-d", "--output-dir", default=".", help="输出目录 (默认: 当前目录)")
p.add_argument("-a", "--audio", action="store_true", help="仅下载音频")
p.add_argument("-q", "--quality", type=int, help="最高分辨率 (如 720, 1080)")
p.add_argument("-p", "--playlist", action="store_true", help="下载整个播放列表")
p.add_argument("-s", "--subtitle", action="store_true", help="下载字幕")
p.add_argument("--crf", type=int, default=23,
help="H.264 CRF 质量值 (默认: 23, 范围 0-51, 越小质量越高)")
p.add_argument("--preset", default="medium",
choices=["ultrafast", "superfast", "veryfast", "faster",
"fast", "medium", "slow", "slower", "veryslow"],
help="编码速度预设 (默认: medium)")
p.add_argument("--no-gpu", action="store_true",
help="禁用 GPU 加速, 强制使用 CPU 软编码")
args = p.parse_args()
sys.exit(grab(
url=args.url,
output_dir=args.output_dir,
output_name=args.output,
audio_only=args.audio,
quality=args.quality,
playlist=args.playlist,
subtitle=args.subtitle,
crf=args.crf,
preset=args.preset,
use_gpu=not args.no_gpu,
))
if __name__ == "__main__":
main()

quick_audio.py#

"""
快速获取音频 - 使用 yt-dlp 下载任意网站音频,转为 AAC 编码的 M4A 文件
输出 M4A (AAC) — 兼容 iPhone / Android / Windows / Mac / 车载 / 所有主流播放器。
可选 --mp3 输出 MP3 格式以兼容极老旧设备。
用法:
python quick_audio.py <URL>
python quick_audio.py <URL> -d D:/Downloads
python quick_audio.py <URL> -b 320 # 320kbps 高音质
python quick_audio.py <URL> --mp3 # 输出 MP3 格式
"""
import argparse
import io
import os
import subprocess
import sys
# Fix Windows console encoding
if sys.platform == "win32":
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding="utf-8", errors="replace")
sys.stderr = io.TextIOWrapper(sys.stderr.buffer, encoding="utf-8", errors="replace")
# ---------------------------------------------------------------------------
# helpers
# ---------------------------------------------------------------------------
def _progress_hook(d: dict):
"""yt-dlp 下载进度回调"""
if d["status"] == "downloading":
pct = d.get("_percent_str", "?")
spd = d.get("_speed_str", "?")
eta = d.get("_eta_str", "?")
print(f"\r 下载中: {pct} | 速度: {spd} | 剩余: {eta}", end="", flush=True)
elif d["status"] == "finished":
print("\n 下载完成,正在处理音频...")
def _find_file(ydl, info: dict) -> str | None:
"""定位 yt-dlp 实际输出的文件"""
expected = ydl.prepare_filename(info)
if os.path.isfile(expected):
return expected
base, _ = os.path.splitext(expected)
for ext in (".m4a", ".mp3", ".ogg", ".opus", ".webm", ".wav", ".flac", ".wma", ".aac"):
if os.path.isfile(base + ext):
return base + ext
return None
def _probe_audio_codec(filepath: str) -> str:
"""检测音频编码格式"""
result = subprocess.run(
["ffprobe", "-v", "error",
"-select_streams", "a:0",
"-show_entries", "stream=codec_name",
"-of", "csv=p=0", filepath],
capture_output=True, text=True, timeout=10,
encoding="utf-8", errors="replace",
)
return result.stdout.strip() or "unknown"
def _convert(input_path: str, bitrate: int = 192, output_mp3: bool = False) -> bool:
"""转码音频为 AAC/M4A 或 MP3"""
base, _ = os.path.splitext(input_path)
target_ext = ".mp3" if output_mp3 else ".m4a"
output_path = base + "_tmp" + target_ext
if output_mp3:
codec = "libmp3lame"
quality_arg = ["-b:a", f"{bitrate}k"]
print(f" → 转码为 MP3 ({bitrate}kbps)...")
else:
codec = "aac"
quality_arg = ["-b:a", f"{bitrate}k"]
print(f" → 转码为 AAC/M4A ({bitrate}kbps)...")
cmd = [
"ffmpeg", "-i", input_path,
"-c:a", codec, *quality_arg,
"-movflags", "+faststart",
"-y", output_path,
]
result = subprocess.run(cmd)
if result.returncode == 0 and os.path.isfile(output_path):
final_path = base + target_ext
os.replace(output_path, final_path)
# 清理原始文件
if os.path.isfile(input_path) and input_path != final_path:
os.remove(input_path)
return True
if os.path.isfile(output_path):
os.remove(output_path)
return False
# ---------------------------------------------------------------------------
# 主流程
# ---------------------------------------------------------------------------
def grab_audio(url: str, output_dir: str = ".", output_name: str | None = None,
bitrate: int = 192, playlist: bool = False,
output_mp3: bool = False) -> int:
"""下载音频并转为 AAC/M4A 或 MP3"""
try:
import yt_dlp
except ImportError:
print("错误: 未安装 yt-dlp,请先执行 pip install yt-dlp")
return 1
os.makedirs(output_dir, exist_ok=True)
target_ext = ".mp3" if output_mp3 else ".m4a"
outtmpl = (os.path.join(output_dir, output_name) if output_name
else os.path.join(output_dir, "%(title)s.%(ext)s"))
ydl_opts: dict = {
"outtmpl": outtmpl,
"format": "bestaudio/best",
"progress_hooks": [_progress_hook],
# 断点续传 & 重试
"continuedl": True,
"retries": 10,
"fragment_retries": 10,
"file_access_retries": 10,
"retry_sleep_functions": {"http": 5, "fragment": 5, "file_access": 3},
}
if not playlist:
ydl_opts["noplaylist"] = True
target_format = "MP3" if output_mp3 else "AAC/M4A"
print(f"\n正在获取音频 ({target_format}, {bitrate}kbps): {url}\n")
with yt_dlp.YoutubeDL(ydl_opts) as ydl:
info = ydl.extract_info(url, download=True)
if info is None:
print("错误: 无法获取音频信息")
return 1
# 收集条目
if "entries" in info:
entries = [e for e in info["entries"] if e]
else:
entries = [info]
# 目标编码
target_codec = "mp3" if output_mp3 else "aac"
print(f"\n[ 音频检查 ]")
for entry in entries:
filepath = _find_file(ydl, entry)
if not filepath:
print(f" ⚠ 未找到文件: {entry.get('title', '?')}")
continue
name = os.path.basename(filepath)
codec = _probe_audio_codec(filepath)
_, ext = os.path.splitext(filepath)
is_target = (codec == target_codec and ext.lower() == target_ext)
print(f" {name}")
print(f" 编码: {codec}")
if is_target:
print(f" ✓ 已是目标格式 ({target_codec}{target_ext}),跳过")
else:
_convert(filepath, bitrate=bitrate, output_mp3=output_mp3)
print(f" ✓ 转码完成 → {target_codec}{target_ext}")
print("\n全部完成!")
return 0
def main():
p = argparse.ArgumentParser(
description="快速获取音频 - 下载任意网站音频 (AAC/M4A 或 MP3)",
)
p.add_argument("url", help="音频/视频 URL")
p.add_argument("-d", "--output-dir", default=".", help="输出目录 (默认: 当前目录)")
p.add_argument("-o", "--output", help="输出文件名")
p.add_argument("-b", "--bitrate", type=int, default=192,
help="音频码率 kbps (默认: 192, 建议: 128/192/256/320)")
p.add_argument("-p", "--playlist", action="store_true", help="下载整个播放列表")
p.add_argument("--mp3", action="store_true",
help="输出 MP3 格式 (默认: AAC/M4A)")
args = p.parse_args()
sys.exit(grab_audio(
url=args.url,
output_dir=args.output_dir,
output_name=args.output,
bitrate=args.bitrate,
playlist=args.playlist,
output_mp3=args.mp3,
))
if __name__ == "__main__":
main()

个人脚本仓库#

RolinShmily
/
SrP-Scripts
Waiting for api.github.com...
00K
0K
0K
Waiting...

如果觉得有用,欢迎给个 Star!如果有问题或建议,欢迎提 Issue 或 PR。

这篇文章是否对你有帮助?

发现错误或想要改进这篇文章?

文章修订历史 (5 次)

查看变更记录
2026-04-18 4ad2695

CMS:Update Posts “2026-04-16-yt-dlp”

2026-04-17 b3d3f6f

CMS:Update Posts “2026-04-16-yt-dlp”

2026-04-17 d3cd482

CMS:Update Posts “2026-04-16-yt-dlp”

2026-04-16 c2a143d

CMS:Update Posts “2026-04-16-yt-dlp”

2026-04-16 ec1b824

CMS:Create Posts “2026-04-16-yt-dlp”

使用yt-dlp下载互联网上的任何音视频 | FFmpeg | Python
https://blog.srprolin.top/posts/2026-04-16-yt-dlp/
作者
RoL1n
发布于
2026-04-13
许可协议
CC BY-NC-SA 4.0

目录
  1. 1
    相关链接
  2. 2
    yt-dlp 实用工具集
  3. 3
    脚本说明
  4. 4
    脚本内容
  5. 5
    个人脚本仓库