暫無描述

ArtyomV2X 312bedf1f6 Fix the updater to only pull necessary files 1 月之前
systemd 8727fd6a91 Fix nesting issue that interferes with install one-liner 1 月之前
web 8727fd6a91 Fix nesting issue that interferes with install one-liner 1 月之前
README.md 8727fd6a91 Fix nesting issue that interferes with install one-liner 1 月之前
proxmox-mount.md 8727fd6a91 Fix nesting issue that interferes with install one-liner 1 月之前
setup.sh 1a1c96620d Add update from repo compatibility 1 月之前
update.sh 312bedf1f6 Fix the updater to only pull necessary files 1 月之前

README.md

YAAR — YouTube Auto-Archiver and Retagger

Self-hosted YouTube archival system designed for Proxmox LXC (Alpine Linux). Archives YouTube videos as H.264/AAC MKVs with embedded metadata, written directly into a Jellyfin-compatible folder structure.


What it does

  • Web UI for submitting YouTube URLs with one click
  • Probes the URL first to pre-fill title, author, and upload date
  • Archives as one of three Jellyfin-native types:
    • YouTube video/media/yaar/YouTube/<Channel>/<Title>.mkv
    • TV series episode/media/yaar/Shows/<Series>/Season NN/SNNENN - <Title>.mkv
    • Movie/media/yaar/Movies/<Title> (Year)/<Title> (Year).mkv
  • Downloads best quality with H.264 video + AAC audio (Jellyfin-safe, no transcoding needed)
  • Remuxes to MKV with:
    • Embedded metadata: title, artist/channel, date, original URL, description
    • Embedded thumbnail
    • Chapter markers (if available)
  • Writes NFO sidecar files for Jellyfin scraping (series and movies)
  • Real-time job queue with progress bars and error reporting
  • Jobs persist across restarts (JSON files in /opt/yaar/jobs/)
  • Weekly auto-update of yt-dlp via cron

Requirements

  • Proxmox VE 7+ (any version with LXC support)
  • Alpine Linux 3.20 LXC template
  • A storage volume or directory on the host for media (bind-mounted into the container)

Quick start

YAAR installs entirely from inside your existing Alpine LXC container. The only thing done on the Proxmox host is attaching the Jellyfin bind-mount.

Step 1 — Attach the bind-mount in Proxmox (one-time, host only)

See proxmox-mount.md for the full guide. In short:

Web UI: Container → Resources → Add → Mount Point

  • Host path: /mnt/nas/jellyfin (your NAS location on the host)
  • Container path: /nas/jellyfin
  • Read-only: No

Or via the Proxmox host shell:

pct set <CTID> -mp0 /mnt/nas/jellyfin,mp=/nas/jellyfin
pct restart <CTID>

Step 2 — Get YAAR into the container

# From the Proxmox host:
pct push <CTID> yaar.tar.gz /root/yaar.tar.gz

# Or via scp from any machine:
scp yaar.tar.gz root@<container-ip>:/root/

Step 3 — Run setup inside the container

pct enter <CTID>          # enter the container, or ssh into it
tar xzf /root/yaar.tar.gz -C /root/
sh /root/yaar/setup.sh

setup.sh detects if it's accidentally run on the Proxmox host and exits immediately — it will not proceed unless it's running inside a container.

The script installs:

  • Python 3, pip, venv
  • ffmpeg
  • yt-dlp (latest), Flask, Gunicorn
  • OpenRC init script (/etc/init.d/yaar)
  • Weekly yt-dlp auto-update cron

Service management (Alpine / OpenRC)

rc-service yaar start
rc-service yaar stop
rc-service yaar restart
rc-service yaar status

Logs:

tail -f /opt/yaar/logs/yaar.log       # Application log
tail -f /opt/yaar/logs/gunicorn.log   # Web server log

Jellyfin integration

Point Jellyfin at the three library roots:

Library type Path
Movies /media/yaar/Movies
Shows /media/yaar/Shows
Other (YouTube) /media/yaar/YouTube

For the Shows library, enable NFO metadata reading so episode details from yt-dlp populate correctly. For YouTube videos, the library type "Other Videos" or "Shows" both work — choose based on preference.


Format choices

Setting Value Why
Video codec H.264 (avc1) Universal Jellyfin direct-play, no transcoding
Audio codec AAC (mp4a) Universal, no transcoding on any client
Container MKV Supports metadata, chapters, thumbnails
Quality Best available H.264 yt-dlp format selector: bestvideo[vcodec^=avc1]+bestaudio[acodec^=mp4a]

If a video is only available as VP9/AV1 (e.g. high-res YouTube uploads), yt-dlp falls back to the best available VP9 + audio, then remuxes to MKV. The web UI shows whatever was actually used.


File structure

/opt/yaar/
  web/
    app.py           ← Flask application
    templates/
      index.html     ← Web UI
  venv/              ← Python virtualenv
  logs/
    yaar.log
    gunicorn.log
    access.log
  jobs/              ← Persisted job JSON files

/media/yaar/
  Movies/
    Fantastic Voyage (1966)/
      Fantastic Voyage (1966).mkv
      Fantastic Voyage (1966).nfo
  Shows/
    Kurzgesagt/
      Season 01/
        S01E01 - The Egg.mkv
        S01E01 - The Egg.nfo
  YouTube/
    Veritasium/
      Does Planet 9 Exist.mkv

Configuration

Environment variables (set in /etc/yaar.env):

Variable Default Description
YAAR_BASE /opt/yaar App, logs, jobs directory
YAAR_MEDIA /media/yaar Root media output directory
YAAR_PORT 7474 Web UI port

Updating yt-dlp manually

/opt/yaar/venv/bin/pip install --upgrade yt-dlp
rc-service yaar restart

Troubleshooting

Download fails with "Sign in to confirm your age" YouTube sometimes requires cookies for age-restricted content. Export cookies from a logged-in browser and pass them to yt-dlp via --cookies in build_ydl_opts() in app.py.

H.264 format not available / falls back to VP9 Some YouTube videos are only available in VP9. YAAR will still download and remux, but Jellyfin may transcode on lower-powered clients. This is a YouTube limitation, not a YAAR bug.

Container can't write to media directory Ensure the bind mount path exists on the host and the container has write permission. For unprivileged containers, the UID/GID mapping may need adjustment: pct set <CT_ID> --mp0 /host/path,mp=/media/yaar,uid=0,gid=0.

Port already in use Edit YAAR_PORT in /etc/yaar.env and restart the service.