-
[Support] Human-126094 - docker templates
🚀 v2.48.0 - the job log viewer works again ghcr.io/masterjb/x265-butler:2.48.0 and :latest are up. amd64-only image on a Debian 13 (Trixie) base. Pull / upgrade: docker pull ghcr.io/masterjb/x265-butler:latest docker restart x265-butler One fix, but a bad one: if you clicked a job's log and got an empty panel, or downloaded it and got {"error_code":"log_not_found"} that was Butler, not your permissions. Both routes that read a job log checked the cache pool path setting, found it empty, and answered 404 before ever looking at the disk. But empty is the NORMAL state: since 2.21.0 an empty setting means "work it out yourself", and Butler then writes those logs to /mnt/cache/x265-butler or /config/cache quite happily. So the viewer was dark on nearly every install that never typed a path in by hand. No chmod could have fixed it, and several of you tried. Thanks to @rasalf who reported it and said up front that they had already ruled out permissions. You were right, and that is what made it quick to find. Worth updating for even if you never open a job log: since 2.47.0 that log is the only place the full ffmpeg command line gets written, and it is what I ask for when something looks wrong. If you worked around it by typing the path into Settings → Paths → Cache pool path, leave it - an explicit value was always honoured and still is. Nothing about encoding changed in this release. No migration, no settings change, no new dependencies. 🟢 NVIDIA NVENC - HOST SETUP RECAP (applies to all versions) If you run an NVIDIA card, NVENC needs the host driver (unRAID NVIDIA-Driver-Plugin or nvidia-container-toolkit) plus these on the container: Extra Parameters: --runtime=nvidia Variables: NVIDIA_VISIBLE_DEVICES = all NVIDIA_DRIVER_CAPABILITIES = compute,video,utility The "video" capability is the one that bites you: the runtime default is compute,utility and WITHOUT video the NVENC session fails to init even though nvidia-smi works fine. utility = the detection probe, compute = CUDA filters, video = NVENC itself. Verify: docker exec x265-butler nvidia-smi -L → expect a "GPU 0: ..." line. ♻️ ROLLBACK If v2.48.0 misbehaves on your hardware, roll back to the previous image: docker stop x265-butler && docker rm x265-butler docker pull ghcr.io/masterjb/x265-butler:2.47.0
-
[Support] Human-126094 - docker templates
🐞 THE LOG VIEWER 404 IS MY BUG, NOT YOUR PERMISSIONS Thanks for the report, and for ruling out permissions before posting. You were right to: the file system was never involved. What happens: the two routes that read a job log (the viewer and the download link) read the "cache pool path" setting DIRECTLY and answer log_not_found when it is empty, before ever looking at the disk. But empty is the NORMAL state. Since 2.21.0 an empty setting means "work it out yourself", and Butler then uses /mnt/cache/x265-butler or, if that is not writable, /config/cache. The encoder writes your job logs there quite happily. Only the reader insisted there was no path at all. So: 404 for every job, on nearly every install that never typed a path in manually. No chmod could have fixed it. The container log kept working because it comes from memory, not from disk, which is exactly why it looked like a file-permission problem. ✅ FIX FOR YOU RIGHT NOW, NO UPDATE NEEDED Type the path in manually. The reader honours an explicit value, so the viewer starts working straight away. You do not have to guess which path that is, the app already shows it: • go to Settings → Paths • scroll to the "Cache pool path" card • it shows "Effective cache path" - that is the directory Butler is really using • copy that exact value into the "Override path" field below it and save No restart needed. Open a finished job's log and it should load. If you want to confirm your logs are where the card says before you change anything, replace PATH below with that effective path: docker exec x265-butler ls -la PATH/logs 🔧 AND THE PROPER FIX Already committed, ships in the next release. There is now exactly ONE place in the codebase that reads that setting, and it always hands back a resolved path, an empty setting can no longer be mistaken for a missing one. A log that genuinely is not on disk still returns 404, but now only after actually looking. The test suite had been asserting the broken behaviour as if it were intended, which is why this survived so long. That test now asserts the opposite. Same bug had already bitten the log retention sweep once, so this time it is fenced: a repo check fails the build if anyone reads that setting raw again. Bonus from the same trip: the Dashboard system card showed a dash for the cache path on all affected installs, which is the other thing that sends you hunting for permissions. It now shows the path actually in use. 🎬 THE MKVTOOLNIX FINDING @alsdkjf THANK YOU, THAT IS A REAL CLUE This is more useful than it may look, so let me spell out why. mkvmerge does not re-encode. It copies the video bitstream through untouched and writes a new container around it. So if a remux fixes playback, the video stream was fine all along and the CONTAINER is what your player is choking on. That rules out the encoder, the quality settings, 10-bit and the keyframe policy in one shot, which is a lot of ground cleared. It also rules out the cover-art bug fixed in 2.47.0: that one produced a second video track, and mkvmerge would have carried it straight over. Your version comparison points somewhere specific: • your working HandBrake files: Lavf 62.3.102 • Butler's output: Lavf 63.5.101 Lavf 63 is unreleased FFmpeg. Butler currently ships a nightly master build, because that is the build that also carries libvmaf for the benchmark feature. That is a defensible reason to be on master, but it is not a reason for you to be a test subject for muxer changes, and I am treating "we ship a nightly" as its own thing to look at. 🙏 WHAT WOULD HELP ME PIN IT DOWN I do not want to swap out a core dependency on a hunch, so before I touch anything: 1. What exactly did the playback failure look like? Refusing to open, stuttering, breaking up on seek, audio dropping out? "Bad" covers several very different causes. 2. Which player and version, and did anything besides VLC also fail? 3. The identify output of one bad file and its repaired twin, so I can diff the container structure: mkvmerge --identify "/path/to/the/bad/file.mkv" mkvmerge --identify "/path/to/the/remuxed/file.mkv" 4. And from inside the container, for the same bad file: docker exec x265-butler ffprobe -v error -show_entries format=format_name,duration -show_entries stream=index,codec_type,codec_name,r_frame_rate -of json "/path/inside/container/bad.mkv" If it turns out the muxer is the culprit, the fix is on my side, not yours, please do not go and remux your library by hand in the meantime.
-
[Support] Human-126094 - docker templates
Thanks @alsdkjf that argv is the key piece, and it says the fix was switched off for this run. v2.47.0 at factory settings emits two extra tokens for QSV: -forced_idr 1 -force_key_frames expr:gte(t,n_forced*5) Your log has neither. I reconstructed your exact options locally against the shipping code: the only env state that produces your argv byte-for-byte is ENCODE_KEYFRAME_INTERVAL_SEC=0 together with ENCODE_CLOSED_GOP_DISABLED=1. Those two are the REVERT levers, they restore the broken v2.45.0 command line. So "the variables do not change the outcome" is expected: with them set there is nothing to change. Please do this: 1) DELETE both variables from the container config. Do not set them to 0 or 1, remove them entirely. Restart the container. 2) Re-encode the same file. The first line of the job log must now contain -force_key_frames expr:gte(t,n_forced*5). If it does not, stop and post the argv again. 3) Run this on the OLD (bad) output and on the NEW one, and post both: ffprobe -v error -select_streams v:0 -show_entries packet=pts_time,flags -of csv=p=0 /path/to/output.mkv | grep ",K" | head -20 Old file: I expect one keyframe at 0.000000, or gaps of ~10 seconds. New file: should be a 5-second grid. That grid is what a player seeks to. Without it there is no refresh point, so the picture stays broken until the next I-frame and the audio stalls waiting for one, which matches exactly what you describe, and matches "no error message from VLC because nothing is actually malformed. On libva: hevc_qsv already runs on libmfx-gen.so. The stack is hevc_qsv -> libvpl -> libmfx-gen.so -> libva -> iHD_drv_video.so -> i915. libva sits underneath oneVPL; there is no "libmfx instead of libva" path. The older alternative (libmfxhw64 / MSDK) does not exist for Gen12+ hardware. There IS a real alternative encoder that bypasses oneVPL entirely: hevc_vaapi. If step 3 shows a correct 5-second grid and the picture is STILL wrong, switch Settings -> Encoder to vaapi and re-run the same file. That isolates the oneVPL layer properly. Two more things worth testing if the picture is still wrong after step 3: - force_10bit is on. Your source is 8-bit yuv420p and the output is forced to Main 10 / p010le. Turn it off and re-run. - If -forced_idr 1 is missing from the new argv even with the variables remove the runtime rejected the option and v2.47.0 degraded itself. Open /diagnostics, hit Copy Report and post it — the encoder row will read forcedIdr: unsupported.
-
[Support] Human-126094 - docker templates
@alsdkjf Thanks, that HandBrake log is genuinely useful, and yes, please do grab the package versions. Let me lay out what I can read from it, what I still can't, and the one test that would settle it fastest. What HandBrake did differently from us on the same file STREAMS IN THE OUTPUT HandBrake : 2 only - video + audio (mux: track 0, track 1). The ASS subtitle track and all 14 TTF font attachments were dropped. butler : video + audio + subtitles + attachments (-map 0:v -map 0:a? -map 0:s? -map 0:t?) PIXEL FORMAT HandBrake : explicit "Format (format=nv12)" filter before the encoder butler : no format= filter on the production path; ffmpeg auto-converts RATE CONTROL HandBrake : quality: 25.00 (QP) butler : -global_quality <n> -low_power 0 (ICQ) or -q:v <n> (constant QP) whichever the boot probe validated on your chip PRESET HandBrake : speed -> "encoding with preset veryfast" butler : slow (our default) KEYFRAMES HandBrake : nothing set - encoder default GOP butler : -force_key_frames expr:gte(t,n_forced*5) CLOSED GOP HandBrake : nothing set butler : -forced_idr 1 DECODE HandBrake : software h264, system-memory path butler : same oneVPL RUNTIME HandBrake : libmfx-gen.so.1.2.17, API 2.17, Arch butler : Debian Trixie apt packages - almost certainly older Three candidate causes, in the order I'd bet on them 1. The forced-IDR / keyframe tokens. Both are new in 2.46.0. HandBrake sets neitme mishandles forced IDRs, that reproduces exactly the "works in HandBrake,breaks here" shape, and the timing lines up with when you started seeing this. 2. Runtime version. Arch ships libmfx-gen 1.2.17; we're on whatever Debian Trixi arguments would run fine inside the Arch container. 3. The subtitle/font mapping. Our output carries the ASS track and the 14 fonts; HandBrake's doesn't. Only in play if VLC's complaint actually mentions subtitles or attachments. The test that separates 1 from the rest, no new image needed Both of these are environment variables. Set them on the container, restart it (~30s), re-encode the same file. Step 1 — this disables only the forced-IDR token: ENCODE_CLOSED_GOP_DISABLED=1 Step 2 — only if step 1 changed nothing, add: ENCODE_KEYFRAME_INTERVAL_SEC=0 Together those two produce byte-identical ffmpeg arguments to 2.45.0. If the filause #1 is confirmed and I'll fix it properly rather than leaving you on envvars. If it's still broken with both set, #1 is ruled out and we're looking at the runtime or the mapping. What would help most, roughly in order 1. The exact VLC error text. Right now I'm inferring; the wording tells me whether this is a video-stream problem or a container/track problem. 2. The job log for a broken encode. As of 2.47.0 the first line of every job log is the complete ffmpeg argv: … that's the direct counterpart to the HandBrake JSON you posted, and it tells me exactly which rate-control path and which tokens your chip actually got. 3. The copy-report from /diagnostics. It already carries our libmfx-gen1.2 version, the Intel media driver version and the ffmpeg version, so I only need your Arch side to compare: pacman -Q vpl-gpu-rt libvpl intel-media-driver ffmpeg 4. ffprobe -v error -show_streams on one of our broken outputs. Shows whether there's a stray/phantom stream in there or whether the video stream itself is malformed. Items 1 and 2 first — those two alone probably decide it.
-
[Support] Human-126094 - docker templates
🚀 v2.47.0 - output integrity, cover art, and an honest test encode ghcr.io/masterjb/x265-butler:2.47.0 and :latest are up. amd64-only image on a Debian 13 (Trixie) base. Pull / upgrade: docker pull ghcr.io/masterjb/x265-butler:latest docker restart x265-butler This one started with a bug report I could not analyse: a finished, green job whose output held 17 of 371722 video frames. Butler booked it as a success, trashed the original and moved on. The original was recoverable from the trash, but the library had lied - and nothing in the app would have caught the next silent encoder failure either. Chasing that report turned up four more places where Butler reported one thing and did another. This release fixes the reporting, not just the one symptom. 🛑 AN OUTPUT WITHOUT A PICTURE IS NO LONGER A SUCCESS Butler now counts the video packets of the file it actually produced and compares them against the expected duration times frame rate. Below 98% the job FAILS instead of being booked into a verdict bucket - no commit, no trash, your original stays untouched. Before, the check was only "does ffprobe parse it" plus "does it have a size", and a video-less file passes both. The gate deliberately fails OPEN in three cases (no duration, no usable frame rate, or the counting probe itself failed) - a failed check is not proof of a broken output. One false-positive class worth knowing: the expectation rides on the SOURCE duration. A file whose audio runs much longer than its video inflates that expectation and can fail a perfectly good encode. The cost is a failed job, never data loss. If it bites you: ENCODE_FRAME_GATE_DISABLED=1 Also new: the full ffmpeg command line is now the first line of every job log. It was never logged anywhere, which is exactly why the 17-frame report was a dead end. It deliberately stays OUT of the diagnostics copy-report, because that report is meant for sharing and would otherwise carry your absolute share paths. 🖼️ COVER ART SURVIVES AN MKV RE-ENCODE Embedded cover art is now extracted and written back as a real Matroska attachment. On v2.46.0 it came back as a SECOND VIDEO TRACK - a 600x900 MJPEG posing as a 90000 fps stream, which crashes VLC and gives mpv a black picture with sound. Files hit by that heal on their next encode. MP4 was never affected. 🧹 THE WATCHER NO LONGER FEEDS ITSELF Auto-scan ingested everything the file watcher reported - including the *.x265-butler.json sidecars Butler writes itself, plus posters, .nfo and .srt files. Those became library rows and got queued, then failed with "Invalid data found when processing input". The watch path now applies the same media rules the scan walker always had. Nothing is cleaned up for you: existing junk rows stay visible and can be removed with the library delete action. ↩️ UN-BLOCKLIST FROM THE LIBRARY A blocklisted file now has an undo action right where the "add to blocklist" button sits, with a 10 second undo window. No more detour through the blocklist page. (Files blocklisted by a PATTERN that has since been deleted have no entry to remove, so no button. Pre-existing gap, now at least visible, fix is queued.) 🔎 LOG VIEWER: SEARCH + HIDE TELEMETRY The container log panel gained a free-text filter and a switch that hides routine telemetry lines. The switch filters on the log LEVEL, not on a list of names - so when a telemetry line escalates into a warning, it stays visible. The download link still gives you the UNFILTERED tail. 🧪 THE TEST ENCODE NOW RUNS YOUR CONFIGURATION The Test Encode button on the Diagnostics page used to hard-code CRF 28 and the default preset, ignore the 10-bit setting and the keyframe policy, and - the big one - NEVER READ YOUR ENCODER SELECTION AT ALL. If you pinned VAAPI while auto-detection preferred QSV, it probed QSV and told you about hardware your jobs never touch. It now resolves encoder, CRF, preset, 10-bit and keyframe interval through the same code the real encode uses, and shows all of it - plus the exact command line it ran - in the copy-report. It also feeds proper 4:2:0 video now; it used to hand libx265 an RGB 4:4:4 frame, a format no real source has. ⚠️ EXPECT THIS IF YOU ENABLED "FORCE 10-BIT" ON HARDWARE WITHOUT 10-BIT HEVC: your test encode will now come back RED where it used to be green. That is correct - your real jobs fail the same way - but it will look like a regression. The test finally tells you the truth. And if a pinned encoder is not detected, the test falls back to libx265 exactly as a real job would, and now SAYS SO instead of handing you a green card. 🔧 NEW ESCAPE HATCHES All three are opt-OUT switches. Leave them unset unless something above misfires on your hardware. Each needs a container restart. • ENCODE_FRAME_GATE_DISABLED=1 - restores v2.46.0: no frame counting, no gate • ENCODE_COVER_ATTACH_DISABLED=1 - drops embedded cover art instead of re-attaching it (output stays valid, just coverless) • WATCH_INGEST_FILTER_DISABLED=1 - restores the v2.46.x watch path (note: this also re-enables queuing of the non-media rows the filter suppresses) 🟢 NVIDIA NVENC - HOST SETUP RECAP (applies to all versions) If you run an NVIDIA card, NVENC needs the host driver (unRAID NVIDIA-Driver-Plugin or nvidia-container-toolkit) plus these on the container: Extra Parameters: --runtime=nvidia Variables: NVIDIA_VISIBLE_DEVICES = all NVIDIA_DRIVER_CAPABILITIES = compute,video,utility The "video" capability is the one that bites you: the runtime default is compute,utility and WITHOUT video the NVENC session fails to init even though nvidia-smi works fine. utility = the detection probe, compute = CUDA filters, video = NVENC itself. Verify: docker exec x265-butler nvidia-smi -L → expect a "GPU 0: ..." line. ♻️ ROLLBACK If v2.47.0 misbehaves on your hardware, roll back to the previous image: docker stop x265-butler && docker rm x265-butler docker pull ghcr.io/masterjb/x265-butler:2.46.0 🔭 COMING NEXT 🙏 As always: the reports in this thread are what drive these releases. Every single item above came from someone posting a log instead of just uninstalling. Thank you.
-
[Support] Human-126094 - docker templates
🚀 v2.46.0 - Cover art, keyframes, and CRF values that finally tell the truth ghcr.io/masterjb/x265-butler:2.46.0 and :latest are up. amd64-only image on a Debian 13 (Trixie) base. Pull / upgrade: docker pull ghcr.io/masterjb/x265-butler:latest docker restart x265-butler 📌 Files that failed on an older version need a retry - nothing is repaired retroactively, and files already encoded keep the keyframe layout they were given. No database migration in this release. But please read the CRF section: new installations get a different QSV default, and existing values are deliberately left alone. v2.45.0 fixed what the app SEES. This one fixes what it PRODUCES. It comes almost entirely out of one very detailed report in this thread against 2.45.0 on an Intel N100 (Alder-Lake-N iGPU, iHD, VA-API 1.22.0) - plus the things that turned up while checking it. Thank you for that report. Two of the five findings below existed since long before 2.45.0 and nobody had noticed them. 🖼️ EMBEDDED COVER ART NO LONGER KILLS THE ENCODE An MKV with embedded cover art carries it as a SECOND VIDEO STREAM (attached_pic). Every -c:v, -vf and -tag:v argument this app emitted was global, so ffmpeg dutifully tried to push a single still image through the HEVC encoder next to the film, and the job died. • Cover art is now detected by video ordinal and stream-copied instead of encoded. • All three global video arguments were narrowed to the actual video track. The third one (-tag:v hvc1 → -tag:v:0) only showed up when running against real ffmpeg. • No backfill. Files that failed before the upgrade stay failed until you re-queue them. 🎬 EVERY OUTPUT NOW GETS A KEYFRAME EVERY 5 SECONDS - AND IT IS A REAL IDR This is the fix for "the picture is only normal after about 10 seconds", and the cause is blunter than it sounds: until 2.45.0 this project NEVER SET A KEYFRAME INTERVAL AT ALL. Every output rode ffmpeg's bare default of gop_size = 250 FRAMES, which is about 10.4 seconds at 24 fps. That is measured, not the folklore 12. The interval alone was not enough either. Counted on the raw HEVC bitstream by NAL unit type: • -force_key_frames alone → correct 5 s spacing, but 1 IDR and 5 CRA • closed-GOP pin alone → 3 IDR and 0 CRA, at the wrong 10.4 s spacing • both together → 6 IDR, 0 CRA, at 5 s A CRA with leading pictures is exactly the "block garbage over an otherwise correct picture" signature. So both are emitted now: a time-based forced keyframe every 5 s (one form for all four encoders, no fps probe needed) plus a per-encoder closed-GOP pin - open-gop=0 for libx265, -forced_idr 1 for QSV, -forced-idr 1 for NVENC. VAAPI emits nothing on purpose: its idr_interval default already means every I-frame is an IDR, and adding a no-op flag would only fake confidence. WHAT IT COSTS YOU: more keyframes means a bigger file. On a synthetic worst case (60 s testsrc, every frame completely new content, CRF 28 ultrafast) the old baseline was 518 185 bytes and the new 5 s default is 614 321 bytes - plus 18.6 percent. Real film material pays far less, because the I-frame share collapses when consecutive frames actually look like each other. The shape holds either way: halve the interval, roughly double the I-frames. Two levers, both need a container restart: ENCODE_KEYFRAME_INTERVAL_SEC = <seconds> (default 5; =0 emits no forced keyframe at all) ENCODE_CLOSED_GOP_DISABLED = 1 (drops the closed-GOP pin) Setting BOTH (ENCODE_KEYFRAME_INTERVAL_SEC = 0 and ENCODE_CLOSED_GOP_DISABLED = 1) reproduces the byte-identical 2.45.0 command line. That is the full revert without downgrading the image. ⚠️ One limit worth knowing: your value is used verbatim, but the spacing you actually observe is the SMALLER of your interval and the encoder's own GOP default - and this release does not change gop_size. Measured: setting 60 still gives keyframes at 0 / 10.4 / 20.8 s, not at 0 / 60. Only values below roughly 10 s actually shorten the spacing. 🔬 THE DETECTION PROBE STOPPED CONTRADICTING PRODUCTION Two separate problems, both in the synthetic probe that runs at boot: • A FALSE NEGATIVE ON INTEL. The probe fed testsrc, which produces rgb24, and iHD rejects that - so /diagnostics declared QSV broken on a host whose real encodes were perfectly fine, because a real encode never sees rgb24. The probe now pins -pix_fmt nv12 for QSV and NVENC. This lives ONLY in the probe; your production command line is byte-identical. • THE NEW IDR OPTION IS NOW CONFIRMED INSTEAD OF ASSUMED. One extra tiny probe per working QSV/NVENC chain checks whether your runtime actually accepts -forced_idr / -forced-idr. If it gets rejected, that encoder LOSES THE CLOSED-GOP PIN AND KEEPS WORKING - it is not thrown out of the encoder list and it does not fail 100 percent of your jobs. You get a warning, and /api/diagnostics carries a per-encoder forcedIdr state of supported, unsupported or not-probed. not-probed means exactly that - unprobed, not "fine". You will see it when probe encoding is switched off, when detection was inconclusive, when the confirm timed out, when the closed-GOP pin is off anyway, on encoders that carry no IDR flag (libx265, VAAPI), or when the confirm failed for an unrelated reason like a busy GPU. In those cases the option still ships unverified, and the report says so instead of pretending otherwise. 🤫 THE CONTAINER LOG IS QUIET AGAIN Since 2.35.0 the CPU-attribution sampler wrote a line every 15 seconds. It had nowhere else to go: a log line was either invisible to everybody or shouted at you. • There is now a tier that is RECORDED BUT NOT PRINTED. The quiet sampler ticks go into the diagnostics buffer and into the copy-report and stay off the container log. The loud ticks - the ones that actually mean something - still print. • LOG_LEVEL = debug puts them back on stdout if you want them. • An unknown LOG_LEVEL no longer crashes the container. A typo used to kill it at startup; it now falls back to info with a single warning. • BEHAVIOUR CHANGE: LOG_LEVEL = silent now silences the container log but KEEPS the diagnostics buffer filled, so a copy-report from a silenced container still carries evidence. It used to empty both. 📏 THE FOUR CRF SETTINGS STOP PRETENDING TO BE ONE SCALE This is the 1.1 GB versus 500 MB report. Same source, same UI value 22, QSV gave 1.1 GB and VAAPI gave 500 MB. Neither encoder did anything wrong - the number simply means different things: • crf_libx265 → -crf (x265 CRF) • crf_nvenc → -rc constqp -qp (NVENC constant QP) • crf_qsv → -global_quality (ICQ) OR -q:v (constant QP), depending on the tier your hardware resolved • crf_vaapi → -rc_mode CQP -qp (VAAPI constant QP) • Each field now NAMES the parameter it really sets, and says plainly that the value does not carry over to another encoder. • The QSV field shows WHICH RATE-CONTROL TIER the boot probe resolved. This has been decided at boot since 2.27.0 and was never visible anywhere. It now shows up in Settings, in /api/diagnostics and in the copy-report. If it could not be resolved, the text says so AND names the -global_quality fallback the encode will actually use. • NEW INSTALLATIONS seed crf_qsv = 26 instead of 22. EXISTING INSTALLATIONS KEEP THEIR VALUE - nothing is migrated, no setting is rewritten. Instead you get an advisory under the QSV field if you are still on 22 with QSV detected. Changing it is your call, not mine. • Being straight about that 26: IT IS AN ESTIMATE. It comes from the 26-28 recommendation posted in this thread, lower end chosen. There is no VMAF measurement behind it and no Intel hardware here to make one. The honest route to a calibrated number is a vmaf-anchored /bench run, which the CRF section now links to. crf_vaapi stays at 22 because nothing contradicts it. • Bench display fix: the native_quality_param column is resolved from the active tier when a row is created, and the NVENC entry is corrected from -cq to -qp (the encoder emits -rc constqp -qp and never emitted -cq). Existing rows are left exactly as they are - the tier is not stored on the row, so rewriting them at display time would reinterpret history instead of repairing it. 📊 If you compare bench runs across this release: pass 2 is the production path and now carries the new keyframe policy, pass 1 does not. That keeps the VMAF comparison apples-to-apples, but it means the size recorded per combination understates what a real encode produces, by up to the amount above. Rows from before and after 2.46.0 carry no marker of either the keyframe policy or the rate-control tier, so treat cross-version comparisons in the /bench UI as indicative only. 🟢 NVIDIA NVENC - HOST SETUP RECAP (applies to all versions) If you run an NVIDIA card, NVENC needs the host driver (unRAID NVIDIA-Driver-Plugin or nvidia-container-toolkit) plus these on the container: Extra Parameters: --runtime=nvidia Variables: NVIDIA_VISIBLE_DEVICES = all NVIDIA_DRIVER_CAPABILITIES = compute,video,utility The "video" capability is the one that bites you: the runtime default is compute,utility and WITHOUT video the NVENC session fails to init even though nvidia-smi works fine. utility = the detection probe, compute = CUDA filters, video = NVENC itself. Verify: docker exec x265-butler nvidia-smi -L → expect a "GPU 0: ..." line. ♻️ ROLLBACK docker stop x265-butler && docker rm x265-butler docker pull ghcr.io/masterjb/x265-butler:2.45.0 No migration file was added and no existing setting was rewritten, so the rollback is clean - you just get the five defects back. If you installed FRESH on 2.46.0, your crf_qsv stays at 26 after a downgrade; it is an ordinary setting you can change in the UI. If you would rather not downgrade: the keyframe change is the only one that alters output bytes, and it reverts on its own - set ENCODE_KEYFRAME_INTERVAL_SEC = 0 and ENCODE_CLOSED_GOP_DISABLED = 1 and restart. 🔭 COMING NEXT No fixed roadmap - development follows your reports in this thread. There is no Intel or NVIDIA hardware here, so all five fixes are traced to named lines of code and covered by tests, and the keyframe result is proven by counting NAL units in a real bitstream, but the on-hardware confirmation has to come from you.
-
[Support] Human-126094 - docker templates
@alsdkjf Thanks for the detailed report, that's exactly the kind of log detail that makes these fixable. I've traced four of the five to actual bugs on my side (cover-art re-encode, the rgb24 test-encode failure, the log spam, and the QSV/VAAPI CRF scale mismatch). Those are queued. For the playback problem I have two suspects and need your help to pick the right one before I fix the wrong thing: 1. Do you have "Force 10-bit" enabled in Settings? Your encode log shows the output as p010le, which is 10-bit Main10, but your source is 8-bit yuv420p, and 10-bit is not the default. So either that toggle is on, or something is forcing it that I need to find. If it is on: please turn it off, re-encode one SubsPlease file, and check whether VLC still shows the black screen. 2. How far apart are the keyframes in a broken output? I currently never set a keyframe interval, so the encoder's own default applies. "20 seconds of black, then blocky garbage, then it recovers" and "seeking kills the audio permanently" both point at a GOP that is far too long. Please run this against one of the broken output files: ffprobe -v error -select_streams v:0 -show_entries frame=key_frame,pts_time -of csv out.mkv | grep ",1$" | head -5 (replace out.mkv with the actual file). That prints the timestamps of the first five keyframes. If the gap is ~20s, that confirms it and the fix is straightforward, I'd force an IDR every 5 seconds, which also fixes seeking. Also useful if you have it: does the same source file play correctly in VLC when encoded with libx265 instead of QSV? Two workarounds you can use right now: - Log spam: set container variable CPU_ATTRIBUTION_DISABLED=1 and restart. A proper log-level split is coming so the diagnostics data survives while the container log stays quiet. - File sizes: QSV and VAAPI both default to 22, but that number means different things per encoder (QSV runs quality-based ICQ, VAAPI runs constant-QP). Try 26–28 for QSV. I'll recalibrate the defaults properly. The cover-image crash is a real bug: I map every video stream through the HEVC encoder, which includes the attached cover.jpg. QSV refuses it (yuvj444p at 90k fps). Fix is to pass attached images through untouched, no re-encode, no stripping.
-
[Support] Human-126094 - docker templates
🚀 v2.45.0 - Scan integrity on unRAID shares, share-root guard, honest queue counts ghcr.io/masterjb/x265-butler:2.45.0 and :latest are up. amd64-only image on a Debian 13 (Trixie) base. Pull / upgrade: docker pull ghcr.io/masterjb/x265-butler:latest docker restart x265-butler 📌 After upgrading, please run ONE full library scan. The scan fix below cannot repair what an older version never wrote - the missing entries come back on the next scan, not on their own. No database migration in this release. This one is built entirely from three reports in this thread against 2.44.0. All three turned out to be real, and all three were traced to a specific line of code. Thank you - that is exactly the kind of report that makes a fix possible. 🔍 THE SCAN NOW FINDS YOUR WHOLE LIBRARY One of you had 143 of 546 folders in the library. About 74 percent missing, and nothing in the UI said so. Cause: the scanner skipped folders it believed it had already visited, identifying them by device + inode. That is a perfectly normal POSIX assumption and it is WRONG on /mnt/user. The share is ONE shfs/FUSE mount, so it reports ONE device id, while the array disks behind it each keep their own independent inode numbering that shfs passes straight through. Two files on two disks can end up with the same identity - and entire sibling folder trees pruned each other away. The bigger and the more spread across disks your library is, the more went missing. • Loop protection now works the way GNU find does: only the ancestors of the current path are checked. Symlink loops are still caught, sibling folders can no longer collide. • Every folder the scan refuses to enter is now COUNTED - permissions, loop, or system path - and shown under "Scan Integrity" in the diagnostics copy-report, both when a scan succeeds and when it fails. A silent library loss is now a visible number. • Nothing is repaired retroactively. Affected installs simply have missing rows. One full scan after the upgrade brings them back. 🛡️ A SHARE PATH CAN NO LONGER TAKE THE CONTAINER DOWN "/" was a valid share path. With the watcher walking 99 levels deep that means the container's own root filesystem: an unthrottled storm of permission warnings that flushed the diagnostics buffer and, for one of you, killed the container. • /, /proc, /sys, /dev, /etc, /boot and /run are now rejected on all three places that can save a share path - create, edit, and the onboarding wizard (which had its own validation and used to slip past the other two). • An install that ALREADY has such a path heals itself, no action needed from you: both tree walkers now skip /proc, /sys, /dev and /run at runtime no matter what is configured. A share that legitimately lives under one of those (say /run/media/usb1) is exempted so it does not disappear. • The permission-warning storm is capped at about two log lines per 15 minutes per share instead of one line per error. • BEHAVIOUR CHANGE worth knowing: the watcher no longer follows symlinked directories. If your media tree is reached THROUGH a symlink, auto-scan will stop seeing it. Set WATCH_FOLLOW_SYMLINKS = 1 and restart to get the old behaviour back. • Kill-switches: SCAN_PRUNE_SYSTEM_PATHS = 0 turns the runtime skip off again, WATCH_FOLLOW_SYMLINKS = 1 restores symlink following. Both need a container restart. The first one does NOT re-allow a bad share path - the input validation stays. 🔢 THE QUEUE FINALLY COUNTS ENCODING AND WAITING SEPARATELY The number labelled "active" was actually queued + encoding. With encode_parallelism = 4 and 995 files waiting that read "999 active", which quite reasonably looks like 999 ffmpeg processes about to start. • The queue header now reads "4 encoding · 995 queued". • Cancel-all counts each job once: 999 for a 999-job queue, not 1994. • The topbar badge no longer jumps from the correct 4 to 999 a second after the page loads, and it disappears the moment the last encode finishes even while hundreds of jobs are still waiting. • The dashboard live-queue card tells "encoding right now" apart from "waiting". • If you read the SSE stream from outside: activeJobs keeps its name AND its meaning (queued + encoding). A new encodingJobs field carries the encoding-only count. Nothing you parse today breaks. • Small note for diagnostics pastes: cpu_attribution.activeEncodes in the copy-report is encoding-only from this version on. If you compare a 2.44 report with a 2.45 report, that same field name means slightly different things on either side. 🟢 NVIDIA NVENC - HOST SETUP RECAP (applies to all versions) If you run an NVIDIA card, NVENC needs the host driver (unRAID NVIDIA-Driver-Plugin or nvidia-container-toolkit) plus these on the container: Extra Parameters: --runtime=nvidia Variables: NVIDIA_VISIBLE_DEVICES = all NVIDIA_DRIVER_CAPABILITIES = compute,video,utility The "video" capability is the one that bites you: the runtime default is compute,utility and WITHOUT video the NVENC session fails to init even though nvidia-smi works fine. utility = the detection probe, compute = CUDA filters, video = NVENC itself. Verify: docker exec x265-butler nvidia-smi -L → expect a "GPU 0: ..." line. ♻️ ROLLBACK docker stop x265-butler && docker rm x265-butler docker pull ghcr.io/masterjb/x265-butler:2.44.0 No migration in this release, so the rollback is clean - you just get the three defects back. Library entries a 2.45.0 scan added stay in the database. 🔭 COMING NEXT No fixed roadmap - development follows your reports in this thread. If your library looked incomplete before, the most useful thing you can post after upgrading is the diagnostics copy-report with the new "Scan Integrity" section, once a full scan has finished.
-
[Support] Human-126094 - docker templates
🚀 v2.44.0 - Delete bench runs + library-delete unblock is live ghcr.io/masterjb/x265-butler:2.44.0 and :latest are up. amd64-only image on a Debian 13 (Trixie) base. Pull / upgrade: docker pull ghcr.io/masterjb/x265-butler:latest docker restart x265-butler ⚠️ This one carries a database migration that cannot be undone. Please back up your appdata folder before pulling - details in the MIGRATION section below. This release closes a reported dead end. A benchmark run could never be deleted, and a library entry that a benchmark had ever touched could not be deleted either - the library delete just kept answering "referenced by a benchmark". Both doors are open now. 🆕 WHAT'S NEW • Delete bench runs, single row or bulk - the /bench history table's action column finally does something, and the multi-select bar gained a bulk delete next to Compare. The delete is IRREVERSIBLE, there is no trash tier for bench runs, so both buttons use the slow inverted-cooldown confirm on purpose. A running benchmark is refused, and so is a finished run whose full-file verify pass is still writing into it. Bulk is partial-success: one refused run does not drop the rest, and the toast tells you exactly what went and what stayed. • A finished benchmark no longer blocks a library delete, deleting a library entry now severs the link instead of refusing. The benchmark keeps its VMAF, size and time numbers, it just no longer points at a file. Still blocked: an entry held by a CURRENTLY RUNNING benchmark, otherwise a click in the library could kill a benchmark in flight. That message names the run and links you to /bench so you can finish or delete it first. • Kill-switch if the delete misbehaves for you: set NEXT_PUBLIC_BENCH_DELETE_DISABLED = 1 and restart, both delete controls disappear, compare / search / sort / selection stay. No image rebuild needed. • API note, only relevant if you scripted against it: DELETE /api/bench/{id} now means PURGE. Cancel moved to POST /api/bench/{id}/cancel. 🗄️ MIGRATION 0029 - PLEASE READ • It runs once, automatically, at container start. Row counts are verified before the old table is dropped, a short copy stops the container loudly instead of silently losing rows. An old database with a dangling reference (exactly the reported broken state) is self-healed during the migration instead of failing to boot. • It is FORWARD-ONLY. Going back to 2.43.0 does NOT undo it: the database stays migrated, the older image just lacks the new code and goes back to refusing every bench-referenced library delete. No data is lost, the feature simply disappears again. • So: back up your appdata folder before you pull. That backup is the only real rollback for a schema change. 🟢 NVIDIA NVENC - HOST SETUP RECAP (applies to all versions) If you run an NVIDIA card, NVENC needs the host driver (unRAID NVIDIA-Driver-Plugin or nvidia-container-toolkit) plus these on the container: Extra Parameters: --runtime=nvidia Variables: NVIDIA_VISIBLE_DEVICES = all NVIDIA_DRIVER_CAPABILITIES = compute,video,utility The "video" capability is the one that bites you: the runtime default is compute,utility and WITHOUT video the NVENC session fails to init even though nvidia-smi works fine. utility = the detection probe, compute = CUDA filters, video = NVENC itself. Verify: docker exec x265-butler nvidia-smi -L → expect a "GPU 0: ..." line. ♻️ ROLLBACK If v2.44.0 misbehaves on your hardware, roll back to the previous image: docker stop x265-butler && docker rm x265-butler docker pull ghcr.io/masterjb/x265-butler:2.43.0 Remember the migration caveat: the image rolls back, the schema does not. Restore the appdata backup if you need the old database too.
-
[Support] Human-126094 - docker templates
🚀 v2.43.0 - NVENC HEVC-unsupported diagnosis + NVIDIA GPU surface is live ghcr.io/masterjb/x265-butler:2.43.0 and :latest are up. amd64-only image on a Debian 13 (Trixie) base. Pull / upgrade: docker pull ghcr.io/masterjb/x265-butler:latest docker restart x265-butler This one is about making NVENC failures on older NVIDIA cards readable instead of cryptic. If your GPU can't do HEVC-NVENC you used to get a bare "-22 / Could not open encoder before EOF" and the diagnostics showed only that an nvidia device existed - never which card. Now both are clear. 🆕 WHAT'S NEW • Dedicated "GPU has no HEVC-NVENC block" diagnosis - the -22 / Could not open encoder failure now maps to a clear (hedged) message on the test-encode surface and the notification bell, distinct from the Pascal API-floor case from v2.41.0. This signature means the card is Kepler / Maxwell-1 era with no HEVC encode block; HEVC-NVENC needs Maxwell-2 / GM206+ (GTX 950/960 or newer). The message points you at a self-check before giving up on NVENC. • NVIDIA GPU model + driver in diagnostics - the diagnostics page and the copy-report now list each NVIDIA card's name + driver version (via nvidia-smi), next to the existing CPU line. So a report can be evidence-checked - confirm a "GeForce GT 730" really is Kepler - instead of a hedged guess. On a host without the NVIDIA runtime it just shows a clean "not present" line and the report still loads fine. No new dependencies, no DB migration, no encode/scan behaviour change - this is diagnostics-surface only. 🟢 NVIDIA NVENC - HOST SETUP RECAP (applies to all versions) If you run an NVIDIA card, NVENC needs the host driver (unRAID NVIDIA-Driver-Plugin or nvidia-container-toolkit) plus these on the container: Extra Parameters: --runtime=nvidia Variables: NVIDIA_VISIBLE_DEVICES = all NVIDIA_DRIVER_CAPABILITIES = compute,video,utility The "video" capability is the one that bites you: the runtime default is compute,utility and WITHOUT video the NVENC session fails to init even though nvidia-smi works fine. utility = the detection probe, compute = CUDA filters, video = NVENC itself. Verify: docker exec x265-butler nvidia-smi -L → expect a "GPU 0: ..." line. ♻️ ROLLBACK If v2.43.0 misbehaves on your hardware, roll back to the previous image: docker stop x265-butler && docker rm x265-butler docker pull ghcr.io/masterjb/x265-butler:2.42.0 Keep the reports coming, the cryptic-error cleanups like this one come straight from them.
-
[Support] Human-126094 - docker templates
🚀 v2.42.0 - Clear NVENC "API too new" diagnosis ghcr.io/masterjb/x265-butler:2.42.0 and :latest are up. amd64-only image on a Debian 13 (Trixie) base. Pull / upgrade: docker pull ghcr.io/masterjb/x265-butler:latest docker restart x265-butler This is a small diagnostics release. When NVENC refuses a card with "Required: X.Y Found: A.B", the app now tells you what it actually means, the GPU's NVENC API is older than the encoder was built for (a hardware-generation limit on Pascal/Maxwell, not a driver you can update), instead of the old misleading "update your driver" hint. v2.41.0 already fixed the normal path (NVENC routes to the bundled jellyfin-ffmpeg), so you'll only see this via the FFMPEG_NVENC_PATH=ffmpeg revert lever or a card older than jellyfin's floor. No encode behaviour changed - QSV / VAAPI / libx265 / NVENC / bench / VMAF are all byte-for-byte identical. 🟢 NVIDIA NVENC - HOST SETUP RECAP (applies to all versions) If you run an NVIDIA card, NVENC needs the host driver (unRAID NVIDIA-Driver-Plugin or nvidia-container-toolkit) plus these on the container: Extra Parameters: --runtime=nvidia Variables: NVIDIA_VISIBLE_DEVICES = all NVIDIA_DRIVER_CAPABILITIES = compute,video,utility The "video" capability is the one that bites you: the runtime default is compute,utility and WITHOUT video the NVENC session fails to init even though nvidia-smi works fine. utility = the detection probe, compute = CUDA filters, video = NVENC itself. Verify: docker exec x265-butler nvidia-smi -L → expect a "GPU 0: ..." line. ♻️ ROLLBACK If v2.42.0 misbehaves on your hardware, roll back to the previous image: docker stop x265-butler && docker rm x265-butler docker pull ghcr.io/masterjb/x265-butler:2.41.0 Keep the reports coming, the cryptic-error cleanups like this one come straight from them.
-
[Support] Human-126094 - docker templates
🚀 v2.41.0 - Pascal/Maxwell NVENC support is live ghcr.io/masterjb/x265-butler:2.41.0 and :latest are up. amd64-only image on a Debian 13 (Trixie) base. Pull / upgrade: docker pull ghcr.io/masterjb/x265-butler:latest docker restart x265-butler If you have an older NVIDIA card, Pascal (Tesla P4, GTX 10-series) or Maxwell (GTX 9-series), NVENC now works. Before this release those cards were refused with "Required: 13.1 Found: 13.0" and silently fell back to CPU encoding, because our ffmpeg build (BtbN) has an NVENC API floor of 13.1 compiled in and those cards top out at 13.0. The fix ships a SECOND ffmpeg - jellyfin-ffmpeg - used only for NVENC. It has an older NVENC floor so Pascal/Maxwell cards encode, and modern RTX cards keep working too (the floor is backward-compatible). Everything else is unchanged: the primary BtbN ffmpeg still handles QSV, VAAPI, libx265, cropdetect, ffprobe and the VMAF quality bench. An encode routes to the jellyfin binary only when the encoder is NVENC. Your existing settings carry over untouched. (Trade-off: the image grew ~100 MB for the second binary.) Escape hatch: if you want NVENC back on the old binary, set container env FFMPEG_NVENC_PATH=ffmpeg (this re-triggers the Pascal refusal - it is a revert lever, not a fix). 🟢 NVIDIA NVENC - HOST SETUP RECAP (applies to all versions) If you run an NVIDIA card, NVENC needs the host driver (unRAID NVIDIA-Driver-Plugin or nvidia-container-toolkit) plus these on the container: Extra Parameters: --runtime=nvidia Variables: NVIDIA_VISIBLE_DEVICES = all NVIDIA_DRIVER_CAPABILITIES = compute,video,utility The "video" capability is the one that bites you: the runtime default is compute,utility and WITHOUT video the NVENC session fails to init even though nvidia-smi works fine. utility = the detection probe, compute = CUDA filters, video = NVENC itself. Verify: docker exec x265-butler nvidia-smi -L → expect a "GPU 0: ..." line. ♻️ ROLLBACK If v2.41.0 misbehaves on your hardware, roll back to the previous image: docker stop x265-butler && docker rm x265-butler docker pull ghcr.io/masterjb/x265-butler:2.40.0 🔭 COMING NEXT • A clearer diagnostic message for the NVENC API-floor case (instead of the cryptic "Required: 13.1 Found: 13.0") Plans can shift, but that's the current direction. More of the same rolling bug-stabilisation from your reports, keep them coming in this thread
-
[Support] Human-126094 - docker templates
@obideuce the Pascal NVENC fix is ready for you to test on a dev build 🎉 Quick recap of what changed: instead of swapping our ffmpeg (which would have broken the VMAF quality bench, since the Pascal-capable build ships no libvmaf), the image now carries TWO ffmpeg binaries. The normal BtbN one stays for QSV/VAAPI/x265/bench, and a second jellyfin-ffmpeg binary (older NVENC floor) handles NVENC only. So your Tesla P4 should finally encode instead of falling back to CPU. It's on the dev image, not a release tag yet, I need your P4 to confirm before I ship it. STEP 1 pull the dev image: docker pull ghcr.io/masterjb/x265-butler:dev Confirm you actually got a fresh image (the id should change from before): docker inspect --format '{{.Id}}' ghcr.io/masterjb/x265-butler:dev STEP 2 run the NVENC probe against the NEW binary (note: ffmpeg-nvenc, not ffmpeg). Assumes your container is named x265-butler and is running with --runtime=nvidia + NVIDIA_DRIVER_CAPABILITIES=compute,video,utility: docker exec x265-butler ffmpeg-nvenc -hide_banner -f lavfi -i testsrc=size=320x240:rate=30 -frames:v 30 -c:v hevc_nvenc -f null - 2>&1 | tail -20 WHAT I'M HOPING TO SEE: a "frame= 30" line and exit 0, NOT the old "Required: 13.1 Found: 13.0" refusal. That's the GO signal. STEP 3 sanity check in the Butler UI: • Encoder detection now lists NVENC as working (not a silent libx265 fallback) • The "Test encode" button on the Diagnostics page succeeds for NVENC • A real encode with the encoder set to NVENC completes STEP 4 (optional, nice-to-have) 10-bit HEVC on the P4: docker exec x265-butler ffmpeg-nvenc -hide_banner -f lavfi -i testsrc=size=320x240:rate=30 -frames:v 30 -pix_fmt p010le -c:v hevc_nvenc -f null - 2>&1 | tail -20 Same "frame= 30" + exit 0 = 10-bit works too. If this one fails but Step 2 passed, no problem — 8-bit is the fix, 10-bit would just be a known gap. Paste back the tail output from Step 2 (and Step 4 if you try it). If it's "frame= 30" I'll tag the release; if it's another "Required: … Found: …" line on the fresh dev image, that tells me the floor is still too high and I re-scope. Thanks for being the P4 test bench, no way to validate this without your hardware 🙏
-
[Support] Human-126094 - docker templates
Thanks for the report, the Required: 13.1 Found: 13.0 line pins it exactly. Your Tesla P4 is Pascal, and the bundled FFmpeg is compiled against NVENC headers that demand a driver newer than any Pascal driver branch (580) can provide. The NVENC minimum is baked into the binary at compile time, so there's no setting to flip, it needs a different FFmpeg build. I have a candidate fix (swap the bundled FFmpeg for a build with an older NVENC floor that still runs on modern cards too). Before I rebuild, could you run these 4 commands on your unRAID host and paste the output? Command C is the important one, it proves the fix works on your actual P4 before I ship anything. A — your exact GPU + driver: nvidia-smi --query-gpu=name,driver_version,compute_cap --format=csv B — reproduce the failure with Butler's current FFmpeg (replace x265-butler if your container name differs): docker exec x265-butler ffmpeg -hide_banner -f lavfi -i testsrc=size=320x240:rate=30 -frames:v 30 -c:v hevc_nvenc -f null - 2>&1 | tail -20 (expected: the Required: 13.1 Found: 13.0 error) C — proof-of-fix: same NVENC test, but with the candidate FFmpeg build, on your P4: docker run --rm --runtime=nvidia --gpus all -e NVIDIA_DRIVER_CAPABILITIES=all --entrypoint /usr/lib/jellyfin-ffmpeg/ffmpeg jellyfin/jellyfin:latest -hide_banner -f lavfi -i testsrc=size=320x240:rate=30 -frames:v 30 -c:v hevc_nvenc -f null - 2>&1 | tail -20 (if this ends with frame= 30 and no error → the fix will work for you. If it shows another Required: … Found: … line → it won't, and I'll need a different approach.) D — encoder parity check on the candidate build: docker run --rm --entrypoint /usr/lib/jellyfin-ffmpeg/ffmpeg jellyfin/jellyfin:latest -hide_banner -encoders 2>/dev/null | grep -Ei 'nvenc|qsv|vaapi|libx265' And 3 quick questions so I scope it right: 1. Besides the Tesla P4, do you run any other older NVIDIA cards (Maxwell GTX 9xx, other Pascal) you'd want supported? 2. On the P4 you only need HEVC encoding, correct? (Pascal can't do AV1 encode either way.) 3. Once I have a fix, can you pull a :dev image and re-run command B (now expecting success) on the real P4 before I tag the release?
-
[Support] Human-126094 - docker templates
🚀 v2.40.0 - Encoding Profile card is live ghcr.io/masterjb/x265-butler:2.40.0 and :latest are up. amd64-only image on a Debian 13 (Trixie) base. Pull / upgrade: docker pull ghcr.io/masterjb/x265-butler:latest docker restart x265-butler This one is pure UI tidy-up: the three per-encode video toggles - Auto-Crop, Force 10-bit, and Colour/HDR10 passthrough - now sit together under one "Encoding Profile" card in the Encoder settings tab instead of being scattered across separate cards. That delivers the "gather the per-encode toggles into one place" note from the last release. No encoder code changed - your encodes come out byte-for-byte identical to v2.39.0, and your existing toggle states carry over untouched. Nothing to re-configure after the upgrade. 🟢 NVIDIA NVENC - HOST SETUP RECAP (applies to all versions) If you run an NVIDIA card, NVENC needs the host driver (unRAID NVIDIA-Driver-Plugin or nvidia-container-toolkit) plus these on the container: Extra Parameters: --runtime=nvidia Variables: NVIDIA_VISIBLE_DEVICES = all NVIDIA_DRIVER_CAPABILITIES = compute,video,utility The "video" capability is the one that bites you: the runtime default is compute,utility and WITHOUT video the NVENC session fails to init even though nvidia-smi works fine. utility = the detection probe, compute = CUDA filters, video = NVENC itself. Verify: docker exec x265-butler nvidia-smi -L → expect a "GPU 0: ..." line. ♻️ ROLLBACK If v2.40.0 misbehaves on your hardware, roll back to the previous image: docker stop x265-butler && docker rm x265-butler docker pull ghcr.io/masterjb/x265-butler:2.39.0