Saving state before major refactoring of stream_organizer.js. Current version is functional - this commit allows safe rollback.
7.6 KiB
Tdarr Plugin Stack Code Review
Date: 2025-12-15
Reviewer: Antigravity Agent
Scope: /Local/*.js plugins
1. Stack Architecture Overview
The plugin stack operates in a sequential re-queue model. Each plugin that modifies the file triggers a reQueueAfter: true, causing Tdarr to process the output and restart the stack from the beginning with the new file.
Current Order:
misc_fixes(Container/Remux/Clean)stream_organizer(Subtitle Extraction/Reorder)combined_audio_standardizer(Audio Transcode/Downmix)av1_svt_converter(Video Transcode)
🚨 Architectural Risks & Findings
- High I/O Overhead: This stack can potentially trigger 4 separate transcode/remux cycles per file.
- Pass 1: Remux to MKV (misc_fixes)
- Pass 2: Reorder/Extract Subtitles (stream_organizer)
- Pass 3: Audio Transcode (audio_standardizer)
- Pass 4: Video Transcode (av1_converter)
- Recommendation: Consider combining logic where possible, or accepting high I/O for modularity.
- Race Conditions:
stream_organizerhandles CC extraction via mostly atomic locks, but file existence checks in Tdarr's distributed environment are always tricky. The currentreQueueAfterlogic relies heavily on "state convergence" (eventually the file meets criteria).
2. Individual Plugin Analysis
A. Tdarr_Plugin_misc_fixes.js (v2.8)
Overview: Handles container standardization, stream cleaning, and TS fixes.
Strengths:
- Correct Logic Flow: Checks for "work already done" (e.g.,
currentContainer !== targetContainer,firstStreamIsVideo) to prevent infinite loops. - Robust Skip Logic: Correctly identifies unfixable ISO/TS files early.
Issues & Improvements:
- Complexity/Refactoring: The
pluginfunction is becoming monolithic.- Suggestion: Extract
analyzeStreamsandbuildFFmpegCommandinto helper functions.
- Suggestion: Extract
- Hardcoded Lists:
brokenTypes,image codecsare defined inside the function.- Fix: Move
constdefinitions (likeBROKEN_TYPES,IMAGE_CODECS) to top-level scope for readability and memory efficiency.
- Fix: Move
- Variable Shadowing:
inputsis reassigned (inputs = lib.loadDefaultValues...). Ideally, useconst settings = ...to avoid mutating arguments.
B. Tdarr_Plugin_stream_organizer.js (v4.8)
Overview: Manages subtitles, language ordering, and extraction.
Strengths:
- Sanitization: Strong input/filename sanitization (
sanitizeFilename,sanitizeForShell). - Loop Protection: Excellent use of
MAX_EXTRACTION_ATTEMPTSandextractionAttemptsmap (though memory-only). - Robustness:
fileExistsRobustwrapper helps with filesystem flakes.
Issues & Improvements:
- Massive Function Size: The
pluginfunction is ~500 lines. It violates Single Responsibility Principle.- Critical Refactor: Move stream analysis, extraction logic, and command building into separate functions:
getReorderedStreams(),processSubtitles(),buildFFmpegArgs().
- Critical Refactor: Move stream analysis, extraction logic, and command building into separate functions:
- Redundant Logic:
isEnglishStreamis used in partitioning and mapping loops separately. - CC Extraction Lock: The lock file mechanism (
.lock) is decent but relies onprocess.pid. If a node crashes hard, the lock remains.- Recommendation: Add a "stale lock" check (e.g., if lock file > 1 hour old, ignore/delete it).
- Efficiency: The
partitionStreamslogic iterates arrays multiple times.
C. Tdarr_Plugin_combined_audio_standardizer.js (v1.13)
Overview: Complex audio mapping, downmixing, and transcoding.
Strengths:
- Modular Helpers:
buildCodecArgs,buildDownmixArgs,calculateBitrateare well-separated. Good code structure. - Explicit Mapping: Correctly handles attachments via
streamMapconstruction (prevents the "muxing overhead 400%" issues).
Issues & Improvements:
- Complex Conditionals: The
needsTranscodinglogic is a bit nested. - Downmix Logic Risk:
buildDownmixArgsassumes the source stream is compatible with thedownmixfilter. Usually safe, but edge cases exist. - Attachment Handling: It maps
0:tcopies, butmisc_fixesmight have stripped images.- Check: If
misc_fixesruns first, it removes images.audio_standardizerwon't see them infile.ffProbeData(sourced from Tdarr DB). - Risk: If Tdarr DB is stale (scan didn't happen after misc_fixes?),
combined_audiomight try to map non-existent streams. - Mitigation:
reQueueAfterusually forces a rescan, so this should be safe.
- Check: If
D. Tdarr_Plugin_av1_svt_converter.js (v2.22)
Overview: AV1 video encoding.
Strengths:
- Modern AV1 Handling: Good use of SVT-AV1 parameters (SCD, TF, etc.).
- Resolution Awareness: Smart CRF adjustment logic based on resolution.
- Input Handling: Explicit checks for HDR/10-bit.
Issues & Improvements:
- Argument Injection Risk (Low):
svtParamsis constructed from inputs. While inputs are sanitized (stripped stars), strict type validation would be better before injection. - Parsing Logic:
resolutionMapis hardcoded. - Bitrate Strategy: The
target_bitrate_strategylogic is complex and relies on accurate source bitrate detection, which isn't always available inffProbeData.- Suggestion: Add fallback if
bit_rateis missing/NaN (currently defaults to safe uncapped, which is acceptable).
- Suggestion: Add fallback if
3. General Best Practice Violations
-
Shared Helpers Duplication:
stripStaris defined in EVERY plugin.sanitizeForShellis in multiple plugins.- Fix: You have a
lib/sanitization.js(referenced in chat history), but plugins currently duplicate this code. They shouldrequirethe shared library if Tdarr environment permits, OR (if Tdarr requires self-contained plugins) this duplication is a necessary evil. - Observation: Plugins currently require
../methods/lib(Tdarr internal). Custom libs in/Localmight not be reliably accessible across nodes unless explicitly distributed.
-
Magic Numbers:
MAX_EXTRACTION_ATTEMPTS = 3MIN_SUBTITLE_FILE_SIZE = 100- Defined as constants in some files, literals in others. Standardize.
-
Error Handling Patterns:
- Most plugins use
response.processFile = false+infoLogon error. This is good Tdarr practice (don't crash the node).
- Most plugins use
4. Recommendations & Refactoring Plan
Priority 1: Safety & Stability (Immediate)
- Stale Lock Cleanup: Implement stale lock check in
stream_organizer(CC extraction). - Argument Validation: Strengthen input validation in
av1_svt_converterto ensuresvt-paramsinjection is perfectly safe.
Priority 2: Code Quality (Short-term)
- De-duplication: If Tdarr allows, strictly enforce using a shared
utils.jsforstripStar,sanitizeFilename, etc. - Modularization: Refactor
stream_organizer.jsto break up the 500-linepluginfunction.
Priority 3: Architecture (Long-term)
- Combine Passes: Investigate merging
misc_fixesandstream_organizerlogic?- Counter-argument: Keeping them separate is better for maintenance.
- Alternative: Use Tdarr's "Flows" (if upgrading to Tdarr V2 flows) or accept the I/O cost for robustness.
5. Conclusion
The plugins are currently FUNCTIONAL and SAFE (after recent fixes). The code quality is generally high but suffers from "script creep" where functions have grown too large. Logic for infinite loop prevention is verified in place.
No immediate code changes required for safety, but refactoring stream_organizer is highly recommended for maintainability.