فعالسازی NVIDIA Hardware Transcoding در Jellyfin Docker
با استفاده از NVIDIA Container Toolkit و تنظیمات Docker Compose، شتابدهنده سختافزاری NVENC و NVDEC را در Jellyfin فعال کنید. با دستور nvidia-smi صحت عملکرد را بررسی کنید.
آنچه میسازید
ترنسکد سختافزاری Jellyfin روی پردازنده گرافیکی NVIDIA شامل چهار مرحله با ترتیب ثابت است و تنها مرحله آخر در داخل Jellyfin انجام میشود. کانتینر نمیتواند پردازنده گرافیکی را که درایور میزبان بارگذاری نکرده است، ببیند. Jellyfin نمیتواند از پردازنده گرافیکی که کانتینر قادر به دیدن آن نیست، استفاده کند. این مراحل را به ترتیب انجام دهید تا هر خطا، مکان مشخصی برای بررسی داشته باشد.
- درایور NVIDIA را روی میزبان نصب کنید و سپس آن را با
nvidia-smiتأیید کنید. - ابزار NVIDIA Container Toolkit را نصب کنید تا Docker بتواند پردازنده گرافیکی را به کانتینر اختصاص دهد.
- پردازنده گرافیکی را برای سرویس Jellyfin در
docker-compose.ymlرزرو کنید و سپس تأیید کنید که کانتینر آن را شناسایی کرده است. - گزینههای NVENC و NVDEC را در تنظیمات پخش Jellyfin فعال کنید و سپس تأیید کنید که یک پخش واقعی از آنها استفاده میکند.
قابلیتهای NVENC (انکودر NVIDIA) و NVDEC (دیکودر NVIDIA) بلوکهای با عملکرد ثابت روی کارت گرافیک هستند. این بخشها از هستههای سایهزن (shader cores) که پردازشهای CUDA (معماری دستگاه محاسباتی یکپارچه) را انجام میدهند، مجزا هستند. همین جداسازی دلیل اصلی ارزشمند بودن این کار است: استریمی که در حالت نرمافزاری چندین هسته CPU را اشغال میکند، در این حالت تنها بخش کوچکی از یک هسته به همراه یک بلوک سختافزاری اختصاصی روی پردازنده گرافیکی را مصرف میکند.
پخش مستقیم (Direct play) همیشه بهتر از transcode است، پس ابتدا آن را بررسی کنید
پیش از آنکه هر یک از این تنظیمات را انجام دهید، بررسی کنید که آیا دلیل transcode کردن چیزی است که میتوانید بهسادگی آن را حذف کنید. Jellyfin زمانی عملیات transcode را انجام میدهد که کلاینت قادر به پخش فایل به همان شکل اصلی نباشد. دلیل این اتفاق همیشه یکی از موارد موجود در این لیست کوتاه است: کدک ویدیو، کدک صوتی، فرمت کانتینر، زیرنویسهای مبتنی بر تصویر، یا محدودیت bitrate که توسط کلاینت درخواست شده است.
داشبورد (Dashboard) را باز کنید، سپس به بخش Playback بروید و در حین پخش یک فایل، وضعیت یک نشست (session) فعال را مشاهده کنید. نشستی که با عنوان Direct playing علامتگذاری شده باشد، فایل را بدون تغییر ارسال میکند و تقریباً هیچ فشاری به CPU وارد نمیکند. نشستی که با عنوان Transcoding علامتگذاری شده باشد، دلیلی که Jellyfin برای این کار انتخاب کرده است را نمایش میدهد. اگر آن دلیل را برطرف کنید، GPU هرگز نیازی به فعالیت نخواهد داشت.
دو تغییر، اکثر موارد transcode را حذف میکند. کیفیت اپلیکیشن کلاینت را روی Auto یا حداکثر مقدار ممکن تنظیم کنید، زیرا کلاینتی که درخواست 4 Mbps دارد، فارغ از نوع کدک، باعث میشود یک فایل 20 Mbps دوباره انکود شود. سپس بهجای تب مرورگر، از یک اپلیکیشن کلاینت بومی (native) استفاده کنید، زیرا مرورگر محدودترین پخشکنندهای است که در اختیار دارید و یک اپلیکیشن بومی روی همان تلویزیون، اغلب میتواند همان فایل را بهصورت Direct play پخش کند.
زیرنویسهای مبتنی بر تصویر، استثنایی هستند که با هیچ تنظیماتی در کلاینت برطرف نمیشوند. زیرنویسهای PGS از ریپهای Blu-ray و VOBSUB از ریپهای DVD در واقع تصویر هستند، بنابراین باید روی خودِ ویدیو ترسیم شوند که این به معنای انکود کامل جریان ویدیویی است. زیرنویسهای متنی در فرمت SRT بهعنوان یک ترک جداگانه به کلاینت ارسال میشوند و هیچ هزینهای ندارند. تبدیل ترکهای زیرنویس به متن در هر جایی که امکانپذیر است، ارزشی بیش از یک GPU دارد. مابقی مباحث سمت سرور در راهنمای اجرای سرور رسانهای Jellyfin روی VPS پوشش داده شده است.
بیشتر پلنهای VPS فاقد GPU هستند
پلنهای استاندارد VPS شامل GPU نمیشوند. پیش از هرگونه برنامهریزی، این دستور را روی سرور اجرا کنید.
lspci -nn | grep -Ei "3d|display|vga"در یک VPS معمولی مبتنی بر KVM، این دستور یک آداپتور نمایشگر مجازی از سمت هایپروایزر یا هیچ خروجی مفیدی را نمایش نمیدهد. آن دستگاه قادر به انکود ویدیو نیست. یک GPU واقعی تنها زمانی ظاهر میشود که ارائهدهنده، یک کارت فیزیکی را به instance شما اختصاص دهد (Passthrough) یا بخشی از آن را در اختیار شما بگذارد؛ این پلنها قیمتگذاری متفاوتی دارند. بخش چه بارهایی واقعاً هزینه کردن برای یک VPS دارای GPU را توجیه میکنند توضیح میدهد که چه کسانی باید و چه کسانی نباید از این سرویسها استفاده کنند.
اگر GPU وجود ندارد، هدف خود را بر پخش مستقیم (Direct Play) بگذارید و transcoding نرمافزاری را به عنوان یک مورد نادر در نظر بگیرید. یک transcoding نرمافزاری برای ویدیوی 1080p با کدک H.264 سنگین است، اما با چند هسته CPU قابل مدیریت است. یک transcoding نرمافزاری برای ویدیوی 4K HDR همراه با tone mapping، کاری نیست که یک VPS کوچک بتواند در لحظه (Real-time) انجام دهد؛ بنابراین در حالی که CPU روی 100 درصد قفل میشود، استریم دچار وقفه و پرش خواهد شد.
نصب درایور NVIDIA روی میزبان
نسخه 10.11 از Jellyfin حداقل درایور 520.56.06 را برای NVIDIA در لینوکس الزامی میداند. اوبونتو ابزاری کمکی ارائه میدهد که بسته مناسب را برای شما انتخاب میکند.
sudo ubuntu-drivers list --gpgpu
sudo ubuntu-drivers install --gpgpu
sudo rebootدستور --gpgpu نسخه headless (بدون رابط گرافیکی) درایور را انتخاب میکند؛ این همان چیزی است که یک مدیا سرور به آن نیاز دارد، زیرا هیچ دسکتاپی روی دستگاه وجود ندارد. دستور لیست، شاخههای موجود را نمایش میدهد و شما میتوانید با استفاده از نام، یکی را انتخاب کنید؛ برای مثال sudo ubuntu-drivers install --gpgpu nvidia:570-server. از شاخهای استفاده کنید که در خروجی دستور لیست مشاهده کردید، نه لزوماً آنچه در اینجا نوشته شده است.
نسخه server همیشه بسته nvidia-smi را به همراه خود نصب نمیکند. بسته utils مربوط به شاخهای که انتخاب کردهاید را نصب کنید، برای مثال sudo apt install nvidia-utils-570-server. سپس درایور را بررسی کنید.
nvidia-smiیک نتیجه سالم، جدولی را نمایش میدهد که نسخه درایور و نسخه CUDA در سربرگ آن است، کارت گرافیک شما با نام لیست شده و لیست پردازشها خالی است. دو خطا در اینجا رایج است. nvidia-smi: command not found به این معنی است که بسته utils نصب نشده است، نه اینکه درایور مشکل داشته باشد. NVIDIA-SMI has failed because it couldn't communicate with the NVIDIA driver به این معنی است که ماژول هسته بارگذاری نشده است؛ در یک نصب تازه، این معمولاً به این معناست که هنوز سیستم را reboot نکردهاید یا Secure Boot از بارگذاری یک ماژول بدون امضا جلوگیری میکند. حضور ماژول را با lsmod | grep nvidia تأیید کنید.
نصب NVIDIA Container Toolkit
درایور به میزبان اجازه میدهد از GPU استفاده کند. با این حال، Docker آن را به داخل کانتینر منتقل نمیکند، زیرا کانتینر نه گرههای دستگاه (device nodes) را دارد و نه کتابخانههای درایور را. ابزار NVIDIA Container Toolkit همان بخشی است که هر دوی این موارد را در زمان شروع کانتینر تزریق میکند. اینها دستورات نصب رسمی NVIDIA برای Debian و Ubuntu هستند.
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg
curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' | sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list
sudo apt-get update
sudo apt-get install -y nvidia-container-toolkitنصب بسته به تنهایی کافی نیست، زیرا باید به Docker اطلاع داده شود که این runtime وجود دارد.
sudo nvidia-ctk runtime configure --runtime=docker
sudo systemctl restart dockernvidia-ctk runtime configure یک ورودی runtime در nvidia داخل فایل /etc/docker/daemon.json مینویسد. راهاندازی مجدد (restart) بخشی است که افراد اغلب فراموش میکنند و نادیده گرفتن آن، رایجترین خطا در کل این تنظیمات را ایجاد میکند. پیش از آنکه به سراغ Jellyfin بروید، اتصالات را تست کنید.
sudo docker run --rm --runtime=nvidia --gpus all ubuntu nvidia-smiاین دستور باید همان جدولی را چاپ کند که میزبان چاپ کرده است. اگر به جای آن با خطایی مبنی بر ناتوانی در انتخاب درایور دستگاه با قابلیتهای gpu مواجه شدید، به این معنی است که Docker daemon از وجود nvidia runtime اطلاع ندارد؛ بنابراین دستور پیکربندی را دوباره اجرا کرده و daemon را مجدداً راهاندازی کنید.
اختصاص GPU به کانتینر Jellyfin در Docker Compose
این روش مدرن استفاده از Compose است که با نمونه منتشرشده توسط Jellyfin مطابقت دارد.
services:
jellyfin:
image: jellyfin/jellyfin
container_name: jellyfin
user: 1000:1000
network_mode: host
restart: unless-stopped
environment:
- NVIDIA_VISIBLE_DEVICES=all
- NVIDIA_DRIVER_CAPABILITIES=all
volumes:
- /srv/jellyfin/config:/config
- /srv/jellyfin/cache:/cache
- /srv/media:/media:ro
runtime: nvidia
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: all
capabilities: [gpu]سرویس را بالا بیاورید و مستقیماً از کانتینر پرسوجو کنید.
docker compose up -d
docker compose exec jellyfin nvidia-smiاگر این دستور جدول درایور را از داخل کانتینر چاپ کند، GPU بهدرستی به کانتینر پاس داده شده است و هر مشکل باقیمانده مربوط به تنظیمات خود Jellyfin است.
چهار خط در آن فایل نیاز به توضیح دارند. capabilities: [gpu] توسط خود Compose الزامی است و حذف آن باعث میشود Compose بهجای اجرای سرویس بدون GPU، از اجرای آن خودداری کند. NVIDIA_DRIVER_CAPABILITIES=all اهمیت دارد زیرا toolkit تنها زمانی کتابخانههای ویدئویی را در کانتینر mount میکند که قابلیت ویدئویی درخواست شده باشد، و مستندات Jellyfin این متغیر را برای image رسمی الزامی میداند. بدون آن، CUDA کار میکند اما NVDEC کار نمیکند و لاگ transcode خطای Cannot load libnvcuvid.so.1 را گزارش میدهد. network_mode: host همان چیزی است که نمونه خود Jellyfin استفاده میکند، زیرا کشف خودکار کلاینت (client auto-discovery) روی پورت UDP 7359 از شبکه bridge عبور نمیکند.
user: 1000:1000 آخرین مورد است و هیچ ارتباطی به GPU ندارد. این متغیر تعیین میکند که Jellyfin چه فایلهایی را میتواند در mount رسانهای شما بخواند؛ عدم تطابق در اینجا بهصورت یک کتابخانه خالی نمایش داده میشود، نه یک خطای مجوز (permissions error). نحوه نگاشت کاربر کانتینر به فایلهای روی دیسک با PUID و PGID این شمارهگذاری را توضیح میدهد و این همان شمارهگذاری است که اگر استک Sonarr و Radarr در Docker Compose را در کنار این سرویس اجرا میکنید، قبلاً تنظیم کردهاید.
چرا اکثر آموزشها همچنان از runtime: nvidia استفاده میکنند
شکل قدیمیتر در تقریباً تمام راهنماهایی که پیدا میکنید وجود دارد و اشتباه هم نیست. این بخشی از تاریخچه است. بسته اصلی nvidia-docker2 یک OCI runtime به نام nvidia را ثبت میکرد، بنابراین تنها راه برای وارد کردن GPU به یک container استفاده از --runtime=nvidia به همراه NVIDIA_VISIBLE_DEVICES بود. نسخه 19.03 داکر، فلگ --gpus و یک API مناسب برای درخواست دستگاه (device-request) اضافه کرد. Docker Compose دیرتر با این تغییرات هماهنگ شد و وقتی هم که هماهنگ شد، درخواست دستگاه تحت کلید deploy.resources.reservations.devices قرار گرفت؛ کلیدی که اکثر افراد یاد گرفته بودند نادیدهاش بگیرند، چون deploy قبلاً به معنای Docker Swarm بود.
نتیجه این است که امروزه هر دو شکل کار میکنند و مثال منتشرشده برای Jellyfin هر دو را همزمان دارد. نگه داشتن runtime: nvidia هزینهای ندارد و باعث میشود فایل در نسخههای قدیمیتر Compose نیز کار کند. اگر فقط runtime: nvidia را نگه دارید و بلوک deploy را حذف کنید، باید NVIDIA_VISIBLE_DEVICES=all را حفظ کنید؛ زیرا آن مسیر قدیمی، متغیر محیطی را میخواند تا تصمیم بگیرد کدام دستگاهها را تزریق کند و هیچ درخواست دستگاهی برای خواندن جایگزین آن ندارد.
فعالسازی transcoding سختافزاری NVIDIA در Jellyfin
تا اینجای کار، هیچ دستوری به Jellyfin برای استفاده از کارت گرافیک داده نشده است. به Dashboard بروید، سپس Playback و بعد Transcoding را انتخاب کنید. گزینه Hardware acceleration را روی Nvidia NVENC تنظیم کنید. تیک Enable hardware encoding را بزنید؛ در غیر این صورت، Jellyfin عملیات decode را روی GPU انجام میدهد اما encode را به CPU میسپارد. این وضعیت میانیِ گیجکننده باعث میشود GPU فعال به نظر برسد اما CPU همچنان تحت فشار باشد.
گزینه Enable enhanced NVDEC decoder، مسیر فعلی NVDEC را با مسیر قدیمیتر CUVID جایگزین میکند. آن را فعال نگه دارید. برای استفاده از NVDEC در پردازش Dolby Vision، این گزینه الزامی است.
در بخش Enable hardware decoding for، فقط تیک کدکهایی را بزنید که کارت گرافیک شما واقعاً از آنها پشتیبانی میکند. این بخشی است که اکثر کاربران در آن اشتباه میکنند. فعال کردن AV1 روی کارتی که فاقد decoder برای AV1 است، پیام خطایی ایجاد نمیکند. Jellyfin درخواست decode سختافزاری میکند، پاسخی دریافت نمیکند و به ناچار به سراغ decode نرمافزاری میرود. در نتیجه، CPU درگیر میشود و GPU تقریباً بیکار میماند؛ وضعیتی که دقیقاً مشابه زمانی است که passthrough اصلاً کار نمیکند.
یک محدودیت دیگر برای کل این صفحه وجود دارد: شتابدهنده سختافزاری فقط با نسخه bundled jellyfin-ffmpeg کار میکند. اگر مسیر FFmpeg را به یک FFmpeg سیستمی تغییر داده باشید، شتابدهی یا ناقص عمل میکند یا اصلاً کار نخواهد کرد.
کدکهایی که نسل GPU شما قادر به رمزگشایی و رمزگذاری آنها است
اینها محدودیتهایی هستند که Jellyfin برای NVENC و NVDEC مستند کرده است. رمزگشایی (decode) و رمزگذاری (encode) قابلیتهای مجزایی هستند و یک کارت گرافیک ممکن است یکی را داشته باشد و دیگری را نداشته باشد.
- H.264 8-bit: تمام GPUهای NVIDIA که دارای NVENC و NVDEC هستند، هم آن را رمزگشایی و هم رمزگذاری میکنند.
- HEVC 8-bit: رمزگشایی و رمزگذاری از نسل دوم Maxwell (مدل GM206) و جدیدتر.
- HEVC 10-bit: رمزگشایی از نسل دوم Maxwell و جدیدتر، اما رمزگذاری فقط از Pascal و جدیدتر.
- AV1: رمزگشایی از Ampere و جدیدتر، رمزگذاری از Ada Lovelace و جدیدتر.
تفاوت در HEVC 10-bit همان موردی است که در عمل مشکلساز میشود. یک کارت گرافیک از نسل Maxwell فایل 4K HDR شما را روی GPU رمزگشایی میکند، اما نمیتواند خروجی 10-bit تولید کند؛ بنابراین Jellyfin به جای آن، H.264 8-bit را رمزگذاری میکند. این خروجی همچنان پخش میشود و برای اکثر کلاینتها نیز انتخاب درستی است. صرفنظر از مدل کارت گرافیک، رمزگذاری AV1 در سال 2026 بهندرت همان چیزی است که به آن نیاز دارید، زیرا پشتیبانی کلاینتها از رمزگشایی AV1 هنوز محدود است و ترنسکد (transcode) زمانی انجام میشود که کلاینت در پخش فایل دچار مشکل شده باشد.
چرا tone mapping بهطور نامحسوس GPU را اشباع میکند
تبدیل HDR (دامنه دینامیکی بالا) به SDR (دامنه دینامیکی استاندارد) یا همان tone mapping، تنظیمی است که بودجه پردازشی GPU شما را هدر میدهد و دلیل آن ساختاری است. عملیات Decode روی NVDEC اجرا میشود. عملیات Encode روی NVENC اجرا میشود. اما tone mapping روی هیچکدام اجرا نمیشود: این یک فیلتر CUDA است که روی هستههای shader اجرا میشود؛ یعنی همان بخش عمومی GPU که کارهای محاسباتی را انجام میدهد. بنابراین، یک استریم 4K HDR که به tone mapping نیاز دارد، از decoder و encoder استفاده میکند و علاوه بر آن، بار اضافی روی shaderها میگذارد.
Jellyfin مستند کرده است که tone mapping مبتنی بر CUDA روی تمام GPUهای NVIDIA که قابلیت decode کردن HEVC 10-bit را دارند، در دسترس است. این یعنی چکباکس مربوطه روی کارتهایی که توانایی پردازش 4K را ندارند نیز ظاهر شده و فعال میشود. نشانه این وضعیت، استریمی است که شروع میشود، مدام بافر میکند و هرگز به پایداری نمیرسد، در حالی که nvidia-smi گزارش میدهد که encoder تقریباً بیکار است.
به همین دلیل است که بررسی جداگانه بار shaderها اهمیت دارد.
nvidia-smi dmon -s uاین دستور در هر ثانیه یک خط با ستونهای مجزا برای sm، enc و dec چاپ میکند. مقادیر پایین برای enc و dec در کنار عدد بالای sm به این معنی است که بلوکهای با عملکرد ثابت (fixed-function) در حال استراحت هستند و گلوگاه اصلی، shaderها هستند؛ بنابراین tone mapping، مقیاسبندی (scaling) یا رندر کردن زیرنویس (subtitle burn-in) همان چیزی است که منابع شما را مصرف میکند. مسیر CUDA همچنین از Dolby Vision profile 5 با قابلیت zero copy پشتیبانی میکند؛ این موضوع اهمیت دارد زیرا بدون zero copy، فریمها بین مراحل فیلتر به حافظه سیستم منتقل شده و بازمیگردند، و این رفتوبرگشت در هر فریم، پهنای باند را اشفال میکند.
محدودیت واقعی سشنهای NVENC در کارتهای گرافیک مصرفی
The data behind this chart
[
{
"label": "GeForce RTX 5090",
"nvenc_engines": 3,
"max_encode_sessions": 12
},
{
"label": "GeForce RTX 4090",
"nvenc_engines": 2,
"max_encode_sessions": 12
},
{
"label": "GeForce RTX 4060",
"nvenc_engines": 1,
"max_encode_sessions": 12
}
]این ارقام، مقادیر رسمی منتشرشده توسط NVIDIA تا اوت 2026 هستند و اندازهگیریهای انجامشده در اینجا نیستند. کارتهای GeForce فارغ از مدل، به 12 سشن انکود همزمان محدود شدهاند. این محدودیت در درایور اعمال میشود، نه در سختافزار؛ و NVIDIA طی سالهای گذشته چندین بار آن را افزایش داده است، بنابراین بهجای تکیه بر تاپیکهای قدیمی انجمنها، همیشه ماتریس فعلی را مطالعه کنید. تعداد موتورهای انکود بخشی است که واقعاً با مدل کارت تغییر میکند: مدل GeForce RTX 5090 دارای 3 موتور NVENC است، در حالی که مدل GeForce RTX 4060 دارای 1 موتور است. موتورهای بیشتر به معنای توان عملیاتی بالاتر برای انکود موازی است، نه افزایش سقف تعداد سشنها.
این محدودیت فقط سشنهای انکود را میشمارد، بنابراین تنها شامل استریمهای ترنسکد (transcoding) میشود. پخش مستقیم (Direct play) و ریمکس کردن (remuxing) هرگز سشن انکود باز نمیکنند. کارتهای دیتاسنتر مانند L4 در همان ماتریس بهعنوان بدون محدودیت ذکر شدهاند و کارتهای دیتاسنتر همان چیزی هستند که معمولاً در پلنهای GPU VPS ارائه میشود؛ بنابراین این محدودیت عمدتاً دغدغه سرورهای خانگی است.
هنگامی که به این محدودیت میرسید، ترنسکد با شکست مواجه شده و لاگ FFmpeg حاوی OpenEncodeSessionEx failed: out of memory (10) خواهد بود. پیام خطا به حافظه اشاره دارد، اما رد درخواست به دلیل محدودیت سشن نیز همین کد را گزارش میکند؛ بنابراین پیش از آنکه به دنبال نشت VRAM باشید، تعداد استریمهای همزمان خود را بررسی کنید. در عمل، اکثر کاربران بسیار پیش از رسیدن به سشن دوازدهم، با محدودیتهای tone-mapping یا پهنای باند آپلود مواجه میشوند.
اثبات انجام Transcoding توسط GPU؛ به تنظیمات اعتماد نکنید
تنظیمات ذخیرهشده مدرک قطعی نیستند. فایلی را پخش کنید که میدانید سیستم را مجبور به Transcoding میکند، سپس سه بررسی زیر را انجام دهید.
- بخش Dashboard و سپس Playback را باز کنید. در نشست فعال باید عبارت Transcoding درج شده باشد و دلیل آن نیز ذکر شود. اگر عبارت Direct playing نمایش داده میشود، هیچ عملیات Transcoding در حال انجام نیست و شما در حال تست فایل اشتباهی هستید.
- بخش Dashboard و سپس Logs را باز کرده و جدیدترین لاگ
FFmpeg.Transcodeرا مشاهده کنید. یک Transcode سختافزاری در خط فرمان با-hwaccel cudaو-hwaccel_output_format cudaنمایش داده میشود و در آنh264_nvencیاhevc_nvencبه عنوان انکودر ذکر شده است. مشاهدهlibx264در آنجا به این معنی است که صرفنظر از آنچه در صفحه تنظیمات ادعا شده، شما در حال انجام Transcoding نرمافزاری هستید. - در حالی که پخش فایل ادامه دارد، دستور
nvidia-smiرا روی میزبان (Host) اجرا کنید. باید فرآیندی از/usr/lib/jellyfin-ffmpeg/ffmpegبا حافظه GPU تخصیصیافته ظاهر شود وnvidia-smi dmon -s uباید مقادیر غیرصفر را در ستونهای enc و dec نشان دهد.
این بررسی سوم را روی میزبان اجرا کنید، نه داخل کانتینر. دستور nvidia-smi داخل کانتینر معمولاً لیست فرآیندهای خالی را نشان میدهد، زیرا نمیتواند ID فرآیندها را از خارج از namespace خود ببیند، در حالی که اعداد مربوط به میزان استفاده (utilization) همچنان به درستی خوانده میشوند. خالی بودن لیست فرآیندها در داخل کانتینر به معنای وجود خطا نیست.
زمانی که سیستم بدون اطلاع شما به حالت نرمافزاری بازمیگردد
Jellyfin ترجیح میدهد پخش را ادامه دهد. هنگامی که مسیر سختافزاری در دسترس نباشد، سیستم بهجای متوقف کردن استریم، به حالت نرمافزاری بازمیگردد؛ بنابراین شاخص دقیق، میزان بار CPU و لاگ FFmpeg است، نه نمایش یک بنر خطا.
عبارت Cannot load libnvcuvid.so.1 در لاگ transcode به این معناست که کتابخانه decoder هرگز در container مونت نشده است. مقدار NVIDIA_DRIVER_CAPABILITIES=all را تنظیم کرده و container را دوباره ایجاد کنید، زیرا تغییر در متغیرهای محیطی نیازمند docker compose up -d برای بازسازی است و یک restart ساده، تنظیمات قدیمی را حفظ میکند.
خطای No capable devices found از سمت h264_nvenc به این معناست که FFmpeg به کتابخانه encoder دسترسی پیدا کرده اما کارت گرافیک قابلاستفادهای نیافته است. docker compose exec jellyfin nvidia-smi را دوباره بررسی کنید، زیرا این وضعیت معمولاً به این معنی است که رزرو دستگاه حذف شده یا container از روی یک فایل قدیمی بازسازی شده است.
بالا بودن مصرف CPU در حالی که GPU بیکار است، نشاندهنده شکست بیصدای بخش decode است. کدکهایی که نسل سختافزار شما قادر به decode آنها نیست را غیرفعال کنید، سپس همان فایل را دوباره پخش کرده و لاگ FFmpeg را بخوانید تا ببینید آیا -hwaccel cuda ظاهر میشود یا خیر.
اگر یک transcode برای محتوای 4K HDR شروع شده و سپس متوقف میشود، در حالی که 1080p بهخوبی کار میکند، این موضوع مربوط به محدودیت tone-mapping است، نه خرابی نصب. این مورد را با ستون sm در nvidia-smi dmon -s u تأیید کنید، سپس یا رزولوشن درخواستی کلاینت را کاهش دهید یا فایلهای 4K HDR را فقط روی کلاینتهایی که قابلیت direct play دارند، پخش کنید.
FAQ
چرا Jellyfin پس از فعالسازی NVENC همچنان از CPU استفاده میکند؟
جدیدترین لاگ FFmpeg.Transcode را در بخش Dashboard و سپس Logs بررسی کنید. اگر پیام libx264 را مشاهده کردید، یعنی هیچ مسیر سختافزاری استفاده نشده است؛ این معمولاً به این معناست که کانتینر به GPU دسترسی ندارد، پس دستور docker compose exec jellyfin nvidia-smi را اجرا کنید تا وضعیت را تأیید کنید. اگر پیام h264_nvenc را میبینید اما CPU همچنان درگیر است، بخش رمزگشایی (decode) بهصورت نرمافزاری اجرا میشود. این اتفاق زمانی رخ میدهد که کدکی را انتخاب کرده باشید که کارت گرافیک شما قادر به رمزگشایی آن نیست، یا گزینه Enable hardware encoding فعال نشده باشد و در نتیجه تنها نیمی از فرآیند به GPU منتقل شده باشد.
آیا هنوز به خط runtime: nvidia در Docker Compose نیاز دارم؟
اگر بلوک deploy.resources.reservations.devices و نسخه بهروزی از Docker Compose دارید، خیر. این بلوک روش مدرن درخواست دستگاه است و همان کار را انجام میدهد. runtime: nvidia مسیر قدیمیتری از دوران nvidia-docker2 است؛ این روش همچنان کار میکند و نمونههای رسمی Jellyfin هر دو را نگه میدارند. نگه داشتن هر دو بیضرر است. اگر فقط runtime: nvidia را نگه میدارید، باید NVIDIA_VISIBLE_DEVICES=all را نیز حفظ کنید، زیرا آن مسیر فاقد درخواست دستگاه برای خواندن است و لیست دستگاهها را از محیط (environment) دریافت میکند.
یک کارت گرافیک NVIDIA همزمان چند استریم را میتواند Transcode کند؟
ماتریس منتشرشده توسط NVIDIA، محدودیت کارتهای GeForce را تا آگوست 2026 برابر با دوازده نشست رمزگذاری همزمان اعلام کرده است و کارتهای دیتاسنتر بدون محدودیت ذکر شدهاند. این سقف معمولاً عامل اصلی محدودیت شما نیست. فرآیند Tone mapping از HDR به SDR روی هستههای Shader اجرا میشود، نه روی NVENC؛ بنابراین تعداد کمی استریم 4K HDR خیلی زودتر از آنکه شمارنده نشستها اهمیت پیدا کند، هستههای Shader را اشغال میکند. مورد خاص خود را با nvidia-smi dmon -s u اندازهگیری کنید و ستون sm را زیر نظر بگیرید، نه تعداد نشستها را.
آیا میتوانم از Transcoding سختافزاری روی VPS بدون GPU استفاده کنم؟
خیر. رمزگذاری به بلوک فیزیکی NVENC نیاز دارد و دستور lspci -nn | grep -Ei "3d|display|vga" روی یک VPS استاندارد، تنها یک آداپتور نمایشگر مجازی از سمت هایپروایزر را نشان میدهد. پاسخ واقعبینانه برای پلنهای بدون GPU این است که Transcodeها را حذف کنید: تنظیمات کیفیت کلاینت را روی Auto قرار دهید، بهجای مرورگر از اپلیکیشن کلاینت بومی استفاده کنید و زیرنویسهای مبتنی بر تصویر را به متن تبدیل کنید تا باعث اجبار به بازنویسی (re-encode) ویدیو نشوند.
چرا ویدیوهای 4K HDR دچار لگ میشوند در حالی که 1080p بهخوبی Transcode میشود؟
این دو بار کاری از بخشهای متفاوتی از کارت گرافیک استفاده میکنند. Transcode یک ویدیوی 1080p SDR فقط شامل رمزگشایی و رمزگذاری است که هر دو روی سختافزار اختصاصی انجام میشوند. استریم 4K HDR شامل Tone mapping است که یک فیلتر CUDA بوده و روی هستههای Shader اجرا میشود، بهعلاوه اینکه مقیاسبندی فریمهای بزرگتر نیز مطرح است. اگر nvidia-smi dmon -s u مقادیر پایین برای enc و dec در کنار مقدار بالای sm نشان میدهد، یعنی بلوکهای اختصاصی بیکار هستند و هستههای عمومی (General-purpose) عامل محدودکننده هستند.