کتابخانه‌های پایتون

دانلود ویدیو از یوتیوب با پایتون و yt-dlp؛ آموزش کامل با کد

دانلود ویدیو از یوتیوب با پایتون و کتابخانه yt-dlp

🗓 آخرین به‌روزرسانی:

دانلود ویدیو با پایتون یکی از پرطرفدارترین پروژه‌های کوچک برای یادگیری کار با کتابخانه‌هاست. ابزار استاندارد این کار امروز yt-dlp است: کتابخانه و برنامه خط فرمان متن‌باز که از یوتیوب و صدها سایت دیگر پشتیبانی می‌کند. در این آموزش yt-dlp را نصب می‌کنیم، اطلاعات ویدیو را بدون دانلود می‌خوانیم، کیفیت را انتخاب می‌کنیم، فقط صدا را جدا می‌کنیم، پیشرفت دانلود را نمایش می‌دهیم و خطاهای رایج را رفع می‌کنیم.

⚖️ نکته مهم قانونی: فقط محتوایی را دانلود کنید که حق دانلود آن را دارید؛ مثلاً ویدیوهای خودتان، محتوای دارای مجوز آزاد (مثل Creative Commons) یا محتوایی که صاحب اثر اجازه داده است. قوانین استفاده یوتیوب دانلود بدون اجازه را محدود کرده است و انتشار دوباره محتوای دیگران می‌تواند نقض حق نشر باشد. این آموزش برای اهداف آموزشی و مدیریت محتوای خودتان است. 📚 این آموزش بخشی از آموزش جامع پایتون است.

کدها با پایتون 3.13.5 و yt-dlp 2026.08.19 اجرا شده‌اند. برای آزمودن دانلود بدون دانلود محتوای دیگران، یک ویدیوی آزمایشی سه‌ثانیه‌ای ساختیم و آن را از یک سرور محلی دانلود کردیم؛ yt-dlp همان روند را برای سایت‌های پشتیبانی‌شده اجرا می‌کند. خروجی‌ها واقعی‌اند.

فهرست مطالب
  1. yt-dlp چیست و چرا به‌جای youtube-dl؟
  2. نصب yt-dlp و ffmpeg
  3. گرفتن اطلاعات ویدیو بدون دانلود
  4. دانلود ویدیو با پایتون
  5. دانلود فقط صدا (MP3)
  6. دانلود پلی‌لیست و چند لینک
  7. نمایش درصد پیشرفت
  8. استفاده از خط فرمان
  9. رفع خطاهای رایج
  10. چه زمانی دانلود مجاز است؟
  11. ساختار یک اسکریپت دانلود تمیز
  12. ایده پروژه
  13. سوالات متداول
  14. آموزش‌های مرتبط

yt-dlp چیست و چرا به‌جای youtube-dl؟

yt-dlp انشعابی فعال از پروژه قدیمی youtube-dl است. سایت‌های ویدیویی مرتب ساختار صفحه‌هایشان را تغییر می‌دهند و ابزاری که به‌روز نشود، از کار می‌افتد. yt-dlp به‌طور مداوم به‌روزرسانی می‌شود، سرعت بهتری دارد، از انتخاب پیشرفته فرمت پشتیبانی می‌کند و هم در خط فرمان و هم به‌عنوان کتابخانه پایتون قابل استفاده است. اگر آموزش قدیمی‌ای دیدید که از youtube-dl یا pytube استفاده می‌کند، احتمال زیادی دارد که امروز کار نکند.

نصب yt-dlp و ffmpeg

داخل یک محیط مجازی دستور زیر را اجرا کنید. اگر با pip آشنا نیستید، آموزش نصب کتابخانه با pip را ببینید:

python -m pip install -U yt-dlp
import yt_dlp.version
print("yt-dlp", yt_dlp.version.__version__)

خروجی:

yt-dlp 2026.08.19

برای ادغام تصویر و صدای کیفیت بالا و تبدیل به MP3 به برنامه ffmpeg هم نیاز دارید. در ویندوز آن را از سایت رسمی ffmpeg دانلود و پوشه bin را به PATH اضافه کنید؛ در لینوکس با مدیر بسته (مثلاً sudo apt install ffmpeg) و در مک با Homebrew نصب کنید. بدون ffmpeg، yt-dlp فقط فرمت‌هایی را می‌گیرد که تصویر و صدا را با هم دارند.

گرفتن اطلاعات ویدیو بدون دانلود

قبل از دانلود، بهتر است اطلاعات ویدیو را ببینید. متد extract_info با download=False فقط اطلاعات را برمی‌گرداند؛ چیزی ذخیره نمی‌شود. در مثال زیر از اولین ویدیوی منتشرشده در یوتیوب استفاده کرده‌ایم:

from yt_dlp import YoutubeDL

url = "https://www.youtube.com/watch?v=jNQXAC9IVRw"
with YoutubeDL({"quiet": True, "no_warnings": True, "skip_download": True}) as ydl:
    info = ydl.extract_info(url, download=False)

print("title:", info["title"])
print("duration:", info["duration"], "s")
print("uploader:", info["uploader"])
print("has formats:", len(info["formats"]) > 0)

خروجی:

title: Me at the zoo
duration: 19 s
uploader: jawed
has formats: True

دیکشنری info ده‌ها کلید دارد: عنوان، مدت، تاریخ انتشار، توضیحات، تصویر بندانگشتی و فهرست فرمت‌ها. برای کار با دیکشنری‌ها این آموزش را ببینید و برای کلیدهایی که ممکن است نباشند از info.get("key") استفاده کنید تا خطای KeyError نگیرید.

فهرست کیفیت‌های موجود

هر ویدیو چندین فرمت دارد؛ بعضی فقط تصویر، بعضی فقط صدا و بعضی هر دو. کد زیر چند فرمت با بیشترین ارتفاع تصویر را نشان می‌دهد:

from yt_dlp import YoutubeDL

url = "https://www.youtube.com/watch?v=jNQXAC9IVRw"
with YoutubeDL({"quiet": True, "no_warnings": True}) as ydl:
    info = ydl.extract_info(url, download=False)

video = [f for f in info["formats"] if f.get("vcodec") not in (None, "none") and f.get("height")]
heights = sorted({f["height"] for f in video}, reverse=True)
print("available heights:", heights[:5])
audio = [f for f in info["formats"] if f.get("vcodec") == "none" and f.get("acodec") not in (None, "none")]
print("audio-only formats:", len(audio) > 0)

خروجی:

available heights: [240, 144]
audio-only formats: True

همین اطلاعات را در خط فرمان با yt-dlp -F URL هم می‌بینید.

دانلود ویدیو با پایتون

دانلود با متد download انجام می‌شود. با outtmpl الگوی نام فایل را تعیین می‌کنید و با progress_hooks تابعی می‌دهید که هنگام پیشرفت و پایان دانلود صدا زده می‌شود. این کد روی ویدیوی آزمایشی خودمان اجرا شده است (بخش اول کد فقط یک سرور محلی برای تست راه می‌اندازد):

import threading, functools
from http.server import ThreadingHTTPServer, SimpleHTTPRequestHandler
class Quiet(SimpleHTTPRequestHandler):
    def log_message(self, *args):
        pass
H = functools.partial(Quiet, directory="/tmp/ytt")
srv = ThreadingHTTPServer(("127.0.0.1", 8765), H)
threading.Thread(target=srv.serve_forever, daemon=True).start()

from yt_dlp import YoutubeDL

url = "http://127.0.0.1:8765/sample.mp4"  # our own test video

def hook(d):
    if d["status"] == "finished":
        print("finished:", d["filename"])

opts = {
    "outtmpl": "downloads/%(title)s.%(ext)s",
    "progress_hooks": [hook],
    "quiet": True,
    "noprogress": True,
}
with YoutubeDL(opts) as ydl:
    ydl.download([url])

import os
print(os.listdir("downloads"), os.path.getsize("downloads/sample.mp4"), "bytes")

خروجی:

finished: downloads/sample.mp4
['sample.mp4'] 14298 bytes

انتخاب کیفیت

کلید format مشخص می‌کند کدام فرمت دانلود شود. چند نمونه پرکاربرد:

  • "best": بهترین فرمتی که تصویر و صدا را با هم دارد.
  • "bv*+ba/b": بهترین تصویر و بهترین صدا را جدا می‌گیرد و با ffmpeg ادغام می‌کند (پیش‌فرض yt-dlp).
  • "bv*[height<=720]+ba/b[height<=720]": حداکثر کیفیت 720p؛ مناسب صرفه‌جویی در حجم اینترنت.
  • "worst": کم‌حجم‌ترین فرمت.
opts = {
    "format": "bv*[height<=720]+ba/b[height<=720]",
    "merge_output_format": "mp4",
    "outtmpl": "downloads/%(title)s [%(id)s].%(ext)s",
}

دانلود فقط صدا (MP3)

برای ذخیره فقط صدای یک پادکست یا سخنرانی که اجازه دانلودش را دارید، بهترین صدا را بگیرید و با پس‌پردازنده FFmpegExtractAudio به MP3 تبدیل کنید (ffmpeg لازم است):

opts = {
    "format": "bestaudio/best",
    "outtmpl": "audio/%(title)s.%(ext)s",
    "postprocessors": [{
        "key": "FFmpegExtractAudio",
        "preferredcodec": "mp3",
        "preferredquality": "192",
    }],
}
with YoutubeDL(opts) as ydl:
    ydl.download([url])

همین تبدیل را روی فایل آزمایشی خودمان بدون اینترنت امتحان کردیم تا مطمئن شویم پس‌پردازنده درست کار می‌کند:

import threading, functools
from http.server import ThreadingHTTPServer, SimpleHTTPRequestHandler
class Quiet(SimpleHTTPRequestHandler):
    def log_message(self, *args):
        pass
H = functools.partial(Quiet, directory="/tmp/ytt")
srv = ThreadingHTTPServer(("127.0.0.1", 8765), H)
threading.Thread(target=srv.serve_forever, daemon=True).start()

from yt_dlp import YoutubeDL
import os

opts = {"format": "best", "outtmpl": "audio/%(title)s.%(ext)s", "quiet": True, "noprogress": True,
        "postprocessors": [{"key": "FFmpegExtractAudio", "preferredcodec": "mp3"}]}
with YoutubeDL(opts) as ydl:
    ydl.download(["http://127.0.0.1:8765/sample_audio.mp4"])
print(os.listdir("audio"))

خروجی:

['sample_audio.mp3']

دانلود پلی‌لیست و چند لینک

اگر لینک یک پلی‌لیست را به download بدهید، yt-dlp همه ویدیوها را یکی‌یکی می‌گیرد. با playlist_items بازه را محدود کنید (مثلاً "1-5") و با %(playlist_index)s شماره را به نام فایل اضافه کنید. برای دانلود از فهرست لینک‌ها، آن‌ها را در یک فایل متنی بنویسید و لیستشان را به download بدهید؛ خواندن فایل را در این آموزش توضیح داده‌ایم. گزینه download_archive شناسه ویدیوهای دانلودشده را در یک فایل ثبت می‌کند تا در اجرای بعدی تکراری دانلود نشوند.

opts = {
    "outtmpl": "%(playlist_title)s/%(playlist_index)02d - %(title)s.%(ext)s",
    "playlist_items": "1-5",
    "download_archive": "done.txt",
    "ignoreerrors": True,
}

نمایش درصد پیشرفت

تابع hook در حین دانلود دیکشنری‌ای با وضعیت downloading و مقدارهای downloaded_bytes و total_bytes دریافت می‌کند. با آن می‌توانید درصد پیشرفت را خودتان چاپ کنید یا در یک رابط گرافیکی یا ربات تلگرام نشان دهید. منطق محاسبه را جدا تست کردیم:

def progress_text(d):
    if d["status"] == "downloading":
        total = d.get("total_bytes") or d.get("total_bytes_estimate")
        if total:
            return f"{d['downloaded_bytes'] / total:.0%}"
        return f"{d['downloaded_bytes']} bytes"
    return d["status"]

for d in [{"status": "downloading", "downloaded_bytes": 2_500_000, "total_bytes": 10_000_000},
          {"status": "downloading", "downloaded_bytes": 4096},
          {"status": "finished"}]:
    print(progress_text(d))

خروجی:

25%
4096 bytes
finished

استفاده از خط فرمان

yt-dlp بدون نوشتن کد هم کار می‌کند. چند دستور رایج:

yt-dlp URL                         # best quality
yt-dlp -F URL                      # list formats
yt-dlp -f "bv*[height<=720]+ba" URL
yt-dlp -x --audio-format mp3 URL   # audio only
yt-dlp -U                          # update yt-dlp

رفع خطاهای رایج

ERROR: Unsupported URL

آدرس متعلق به سایتی نیست که yt-dlp پشتیبانی می‌کند، یا آدرس صفحه اشتباه کپی شده است. لینک کامل ویدیو را بدهید و yt-dlp را به‌روز کنید.

دانلود ناگهان کار نمی‌کند یا خطای استخراج می‌دهد

سایت‌ها مدام تغییر می‌کنند. اولین قدم همیشه به‌روزرسانی است: python -m pip install -U yt-dlp. اگر مشکل ماند، پیام خطا را در بخش Issues مخزن رسمی پروژه جستجو کنید.

ffmpeg not found

برای ادغام یا تبدیل صدا ffmpeg لازم است. آن را نصب کنید و مطمئن شوید دستور ffmpeg -version در ترمینال کار می‌کند؛ یا مسیرش را با گزینه ffmpeg_location بدهید.

HTTP Error 403 یا درخواست تأیید ورود

بعضی ویدیوها محدودیت سنی، منطقه‌ای یا خصوصی‌اند. برای ویدیوهای خودتان می‌توانید از ورود به حساب از طریق کوکی‌های مرورگر استفاده کنید، اما برای دور زدن محدودیت محتوای دیگران از این روش استفاده نکنید. اگر شبکه شما به سرورهای سایت مقصد دسترسی پایدار ندارد، خطاهای اتصال هم طبیعی است.

ModuleNotFoundError: No module named yt_dlp

کتابخانه در مفسر دیگری نصب شده است؛ نام ماژول در import با زیرخط (yt_dlp) و نام پکیج در pip با خط تیره (yt-dlp) است. راهنمای کامل در رفع ModuleNotFoundError.

چه زمانی دانلود مجاز است؟

پیش از نوشتن هر ابزار دانلود، این سؤال را از خودتان بپرسید: «آیا اجازه دارم این فایل را نگه دارم؟» چند موقعیت رایج که معمولاً مجاز است: پشتیبان‌گیری از ویدیوهایی که خودتان ساخته و در کانال خودتان منتشر کرده‌اید؛ محتوایی که صاحب آن صراحتاً با مجوزی مثل Creative Commons اجازه بازاستفاده داده است؛ و فایل‌هایی که سازنده برای دانلود عمومی منتشر کرده است. در مقابل، دانلود فیلم، سریال، موسیقی یا دوره‌های آموزشی پولی دیگران و انتشار دوباره آن‌ها، حتی بدون کسب درآمد، می‌تواند نقض حق نشر باشد و به سازنده محتوا ضرر می‌زند.

یوتیوب برای تماشای آفلاین، قابلیت رسمی دانلود در برنامه خودش را در بعضی حساب‌ها ارائه می‌دهد؛ اگر فقط می‌خواهید ویدیویی را بعداً بدون اینترنت ببینید، اول همان گزینه رسمی را بررسی کنید. ارزش آموزشی این پروژه برای برنامه‌نویس در یادگیری کار با کتابخانه، دیکشنری‌های تودرتو، تابع‌های callback و مدیریت خطاست؛ این مهارت‌ها را می‌توانید کاملاً روی محتوای مجاز و فایل‌های آزمایشی خودتان تمرین کنید، همان‌طور که ما در این آموزش انجام دادیم.

ساختار یک اسکریپت دانلود تمیز

وقتی اسکریپت بزرگ‌تر شد، تنظیمات را در یک دیکشنری جدا و در ابتدای فایل نگه دارید، مسیر پوشه خروجی را با pathlib بسازید و همه دانلودها را داخل بلوک try قرار دهید تا خطای یک لینک کل برنامه را متوقف نکند. اطلاعات هر دانلود موفق، مثل شناسه، عنوان و تاریخ، را در یک فایل JSON ثبت کنید تا بعداً بتوانید گزارش بگیرید. آموزش‌های مدیریت خطا و کار با JSON برای این بخش کاربردی‌اند.

ایده پروژه

  • یک اسکریپت بایگانی که هر هفته ویدیوهای جدید کانال خودتان را برای پشتیبان دانلود کند.
  • یک ربات اتوماسیون که لینک را بگیرد و فقط اطلاعات و تصویر بندانگشتی ویدیو را برگرداند.
  • یک ابزار که مدت کل ویدیوهای یک پلی‌لیست را حساب کند؛ بدون دانلود و فقط با extract_info.

📌 همچنین بخوانید: رسم نمودار در پایتون با Matplotlib

سوالات متداول

آیا دانلود ویدیو از یوتیوب قانونی است؟

فقط وقتی حق آن را دارید؛ مثل ویدیوهای خودتان، محتوای دارای مجوز آزاد یا با اجازه صاحب اثر. قوانین یوتیوب دانلود بدون اجازه را محدود کرده و بازنشر محتوای دیگران ممکن است نقض حق نشر باشد.

yt-dlp بهتر است یا pytube؟

yt-dlp فعال‌تر نگهداری می‌شود، از صدها سایت پشتیبانی می‌کند و در برابر تغییرات یوتیوب سریع‌تر به‌روز می‌شود؛ برای همین امروز گزینه پیشنهادی است.

چرا برای yt-dlp به ffmpeg نیاز دارم؟

کیفیت‌های بالا تصویر و صدا را جدا ارائه می‌دهند و ffmpeg آن‌ها را ادغام می‌کند. تبدیل به MP3 هم با ffmpeg انجام می‌شود.

چطور فقط صدای ویدیو را بگیرم؟

از format برابر bestaudio و پس‌پردازنده FFmpegExtractAudio با preferredcodec برابر mp3 استفاده کنید، یا در خط فرمان yt-dlp -x –audio-format mp3 را بزنید.

آموزش‌های مرتبط

آموزش‌های تازه، کد آماده و رفع خطاهر هفته در کانال Dev Source؛ رایگان.

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *