Subsyncarr

repository·main·Indexed 43 days ago

https://github.com/johnpc/subsyncarr

An automated subtitle synchronization tool that runs in a Docker container. It monitors media directories and uses engines such as ffsubsync, autosubsync, and alass to automatically sync out-of-sync subtitles. It features a Web UI, a REST API, and supports non-destructive synchronization by creating engine-specific suffix files.

Tokens
10.2K
Snippets
35
Records
50
Agent score
53%

What's inside Subsyncarr

  1. Organize media directories for synchronization

    main

    Subsyncarr expects video files and their corresponding subtitle files to have matching names. It follows standard naming conventions compatible with Plex, Jellyfin, Emby, and Bazarr. The tool is non-destructive; it creates new files with engine-specific suffixes (e.g., .ffsubsync.srt) rather than altering originals.

    /movies
    ├── Movie Title (2024).mkv
    ├── Movie Title (2024).srt          # Will be synchronized
    ├── Movie Title (2024).ffsubsync.srt # Generated output
    └── Another Movie.mp4
        └── Another Movie.srt
    
    /tv
    ├── Show Name/
    │   ├── Season 01/
    │   │   ├── Show.S01E01.mkv
    │   │   └── Show.S01E01.srt
  2. Install Subsyncarr using Docker Run

    main

    You can run Subsyncarr as a standalone container using the docker run command. Ensure you map the necessary volumes for media and data persistence, and set the required environment variables.

    docker run -d \
      --name subsyncarr \
      -p 3000:3000 \
      -v /path/to/movies:/movies \
      -v /path/to/tv:/tv \
      -v ./data:/app/data \
      -e TZ=Etc/UTC \
      -e PUID=1000 \
      -e PGID=10 \
      -e CRON_SCHEDULE="0 0 * * *" \
      -e SCAN_PATHS=/movies,/tv \
      -e MAX_CONCURRENT_SYNC_TASKS=1 \
      mrorbitman/subsyncarr:latest
  3. Install Subsyncarr using Docker Compose (Recommended)

    main

    To set up Subsyncarr with Docker Compose, create a docker-compose.yaml file. You must mount your media directories as volumes and a data directory to persist the SQLite database.

    Key configuration steps:

    • Replace /path/to/movies, /path/to/tv, etc., with your actual media paths.
    • Update TZ to your timezone (e.g., America/New_York).
    • Update PUID and PGID to match your local user (use the id command to find these).
    • Adjust SCAN_PATHS to match the volumes you mounted.
    name: subsyncarr
    
    services:
      subsyncarr:
        image: mrorbitman/subsyncarr:latest
        container_name: subsyncarr
        ports:
          - '3000:3000' # Web UI
        volumes:
          # Mount your media directories
          - /path/to/movies:/movies
          - /path/to/tv:/tv
          - /path/to/anime:/anime
          - ./data:/app/data # Persist database across restarts
        restart: unless-stopped
        deploy:
          resources:
            limits:
              memory: 768M # Hard limit
            reservations:
              memory: 128M # Minimum guaranteed memory
        environment:
          - TZ=Etc/UTC # Replace with your own timezone
          - PUID=1000
          - PGID=10
          - CRON_SCHEDULE=0 0 * * * # Runs every day at midnight
          - SCAN_PATHS=/movies,/tv # Comma-separated paths to scan
          - EXCLUDE_PATHS=/movies/temp,/tv/downloads # Optional: exclude directories
          - MAX_CONCURRENT_SYNC_TASKS=1 # Number of parallel processing tasks
          - INCLUDE_ENGINES=ffsubsync,autosubsync,alass # Engines to use
  4. Configure Database and Log retention

    main

    Manage how long processing history and logs are kept using these environment variables:

    VariableDefaultDescription
    DB_PATH/app/data/subsyncarr.dbSQLite database location
    LOG_BUFFER_SIZE1000Ring buffer size for in-memory logs
    RETENTION_KEEP_RUNS_DAYS30Keep complete runs for N days
    RETENTION_TRIM_LOGS_DAYS7Trim logs after N days (keeps summary only)
    RETENTION_MAX_LOG_SIZE10000Max size for trimmed logs in bytes
    RETENTION_CLEANUP_INTERVAL_HOURS24How often to run cleanup (in hours)
  5. Real-time updates via WebSocket

    main

    Subsyncarr provides a WebSocket endpoint at /ws for real-time dashboard updates. Upon connection, the server immediately sends the current state.

    Supported Message Types:

    • state: Initial payload containing currentRun, files, and isRunning.
    • run:started: Broadcast when a new run begins.
    • run:completed: Broadcast when a run finishes successfully.
    • run:cancelled: Broadcast when a run is stopped.
    • file:updated: Broadcast when a specific file's status changes (includes { file, run }).
  6. How SubsyncarrPlusClient handles real-time updates

    main

    The client uses a WebSocket connection to listen for specific message types that update the UI and internal state without requiring manual refreshes.

    Supported WebSocket message types:

    • state: Replaces the entire application state.
    • run:started: Sets isRunning to true and updates currentRun.
    • run:completed: Sets isRunning to false, updates currentRun, and triggers a history refresh.
    • run:cancelled: Sets isRunning to false, updates currentRun, and triggers a history refresh.
    • file:updated: Updates a specific file's data in the current file list.
    • files:cleared: Resets the current file list and currentRun state.
  7. Set engine timeouts to prevent hung processes

    main

    The SYNC_ENGINE_TIMEOUT_MS environment variable controls how long each sync engine can run before being terminated. This prevents hung processes from blocking the queue. You can also use SYNC_TIMEOUT to set a timeout in seconds.

    environment:
      - SYNC_ENGINE_TIMEOUT_MS=3600000 # 60 minutes for large files
  8. Configure Core Subsyncarr settings

    main

    Use the following environment variables to control the core behavior of the synchronization process:

    VariableDefaultDescription
    SCAN_PATHS/scan_dirComma-separated directories to scan for SRT files (must be mounted as volumes)
    EXCLUDE_PATHS(none)Comma-separated directories to exclude from scanning
    SYNC_LANGUAGES(none)Comma-separated language codes to sync (e.g., en,de). Only syncs subtitles with matching language tags in the filename (e.g., movie.en.srt). If not set, all subtitles are synced.
    CRON_SCHEDULE0 0 * * *Cron expression for sync schedule, or disabled to turn off
    MAX_CONCURRENT_SYNC_TASKS1Number of subtitle files to process in parallel
    INCLUDE_ENGINESffsubsync,autosubsync,alassWhich sync engines to use (comma-separated)
    FFSUBSYNC_SUFFIXffsubsyncCustom suffix for ffsubsync output files
    AUTOSUBSYNC_SUFFIXautosubsyncCustom suffix for autosubsync output files
    ALASS_SUFFIXalassCustom suffix for alass output files
    SYNC_TIMEOUT(none)Timeout in seconds per sync operation (overrides SYNC_ENGINE_TIMEOUT_MS)
    SYNC_ENGINE_TIMEOUT_MS1800000Timeout for each sync engine in milliseconds (30 min default)
    WEB_PORT3000Port for the web UI
    WEB_HOST127.0.0.1Host to bind the web UI to (0.0.0.0 to expose externally)
    TZ(system)Timezone for logging and cron scheduling
    PUID1000User ID for file permissions
    PGID1000Group ID for file permissions
  9. Configure Subsyncarr via Docker Compose

    main

    Subsyncarr can be deployed using Docker Compose. To ensure functionality, you must mount any directories specified in the SCAN_PATHS environment variable as volumes. If SCAN_PATHS is not provided, the application defaults to scanning /scan_dir. To persist the database across restarts, mount a local directory to /app/data.

    services:
      subsyncarr:
        image: mrorbitman/subsyncarr:latest
        container_name: subsyncarr
        ports:
          - '3000:3000'
        volumes:
          - /path/to/movies:/movies
          - ./data:/app/data
        environment:
          - SCAN_PATHS=/movies
  10. View detailed processing logs in the Web UI

    main
    For granular information regarding specific subtitle synchronization runs, navigate to the "Processing History" section in the Subsyncarr Web UI. Click on any individual run to view its full execution logs.
  11. Troubleshoot files not being processed

    main

    If your media files are not being picked up for synchronization, verify the following:

    • Naming Convention: Ensure subtitle files match the video filenames (e.g., movie.mkv and movie.srt).
    • Path Configuration: Verify that SCAN_PATHS correctly matches your mounted volumes.
    • Sync Status: Check if the files have already been processed (look for .ffsubsync.srt files).
    • Auto-skip Status: Check the Web UI to see if files are being automatically skipped due to repeated previous failures.