Vue normale

Recommendarr : recommandations Plex/Jellyfin/arrs par l’IA

Par : Aerya
10 septembre 2025 à 16:16


Ok, y’a déjà whatmille solutions de recommandations et découverte de contenus : les listes prises à droite à gauche et ajoutées aux arrs ou à ListSync, Overseerr/Jellyseerr, Suggestarr etc BAH EN VOICI UNE DE PLUS !

Recommendarr de fingerthief permet d’avoir des recommandations faites par une IA à partir des contenus vus sous Plex/Jellyfin, Trakt, Tautulli (eh non ! pas encore mort) et de ceux indexés par Radarr et Sonarr.
Attention, tous les synopsis etc sont en anglais.

Quand je parle d’IA, c’est vaste et comprend l’autohébergé (j’ai testé avec OpenAI) :

Services d’IA compatibles

Vous pouvez utiliser n’importe lequel de ces services avec une API compatible OpenAI :

  • OpenAI : URL par défaut (https://api.openai.com/v1) avec votre clé API OpenAI
  • LM Studio : URL locale (ex. http://localhost:1234/v1) exécutant des modèles sur votre ordinateur
  • Ollama : URL locale (ex. http://localhost:11434/v1) pour des modèles hébergés en local
  • Anthropic Claude : API d’Anthropic avec l’URL de base appropriée
  • Auto-hébergé : votre propre serveur d’API LLM compatible avec OpenAI
  • Mistral, Groq, Cohere : la plupart des fournisseurs d’IA avec des endpoints compatibles OpenAI


Honnêtement, vu que je passe 90% de mon temps à tester des trucs plutôt qu’à profiter de mon setup, les recommandations que j’ai sont certes logiques (plus que celles de TMDB, en bas des fiches du moins) mais je ne sais pas si elles reflètent vraiment la qualité de cet outil. Ce dont je ne doute pas.

L’installation est simple puisque tout se configure via la WebUI

services:
  recommendarr:
    container_name: recommendarr
    restart: always
    ports:
      - 3080:3000
    volumes:
      - /home/aerya/docker/recommendarr:/app/server/data
    image: tannermiddleton/recommendarr:latest
    labels:
      - com.centurylinklabs.watchtower.enable=true

Et ensuite on peut connecter ses outils/comptes. Dans mon cas Trakt, TMDB, Jellyfin et Radarr/Sonarr. Je pense que ça venait de mon navigateur mais impossible d’accéder à la configuration en cliquant sur un autre bouton que Configure AI Service ou le menu des paramètres.

recommendarr1


Pour l’IA j’ai utilisé mon compte OpenAI avec le modèle gpt-5-chat-latest (pas comme sur le screen). Choix complètement fait au pifomètre, je suis preneur de conseils.

recommendarr2

Et ensuite…. magie…. Ou presque. L’IA ne fera qu’aller chercher des contenus par rapport à notre demande. Il faut donc paramétrer la demande. Au moins le nombre de recommandations.

recommendarr4

Dans la partie IA, en sus du modèle à choisir et son degré de précision, on peut demander à ce que Recommandarr utilise un sous-ensemble de la bibliothèque afin de réduire l’utilisation de jetons tout en fournissant des recommandations pertinentes.

recommendarr5

On sélectionne la catégorie visée (films/séries) et le nombre de recommandations souhaitées.

recommendarr6


Puis on peut affiner la recherche en sélectionnant des genres.

recommendarr7

Puis sélectionner un prompt pré-défini ou en créer

recommendarr8
Style « Vibe »

Se concentre sur l’atmosphère émotionnelle et l’expérience sensorielle du contenu de votre bibliothèque. Les recommandations privilégient la correspondance avec le ressenti et l’ambiance de vos films/séries préférés plutôt que le simple genre ou la similarité de l’intrigue.
Idéal pour : Trouver du contenu qui évoque la même sensation, capturant des tons et atmosphères spécifiques.


Style analytique

Procède à une analyse détaillée des structures narratives, des motifs thématiques et des techniques formelles. Les recommandations reposent sur une analyse en profondeur des éléments cinématographiques et télévisuels qui relient les œuvres à un niveau plus substantiel.
Idéal pour : Une exploration intellectuelle et la découverte de contenus partageant une approche artistique ou une profondeur thématique similaire.


Style créatif

Dépasse les catégorisations classiques pour trouver des liens inattendus entre les œuvres. Met en avant les parcours émotionnels, la vision artistique et les approches narratives originales.
Idéal pour : Découvrir des recommandations surprenantes, qui peuvent sembler éloignées au premier abord mais partagent une même essence créative.


Style technique

Se focalise sur l’artisanat de la production, les techniques de réalisation et l’exécution technique. Analyse les méthodes de mise en scène, la cinématographie, les styles de montage et les éléments de production.
Idéal pour : L’appréciation des aspects techniques et la recherche de contenus offrant une qualité de production ou une innovation technique similaire.


Comme souvent on peut sélectionner la langue préférée du contenu (séries plutôt en langue française etc). On pourra aussi de temps en temps rescanner les bibliothèques.

recommendarr9

Et enfin, découvrir les reco. À noter qu’on ne peut pas les ajouter à Radarr/Sonarr directement, sans passer par Overseerr/Jellyseerr/whatever.

Voici par exemple pour les films

recommendarr10
recommendarr11
recommendarr12
recommendarr13

Évidemment, avec Decypharr, ça tombe en quelques secondes.

recommendarr14

Et pour les séries, on peut évidemment sélectionner les saisons

recommendarr15

C’est sympa à tester, on peut y créer plusieurs utilisateurs donc c’est intéressant mais avec un LLM autohébergé ça doit consommer pas mal de ressources. Avec OpenAI ça ne consomme en revanche rien que le serveur donc je vais le garder dans un coin mais je doute l’utiliser tous les jours, avec tout le reste…

recommendarr16


L’idéal serait de couler ça à Overseerr/Jellyseerr…

Loading

Aphrodite – Sublimez vos affiches pour Jellyfin (et Emby ?)

Par : Aerya
10 septembre 2025 à 11:04

Ok, pour Emby je pose la question vu qu’ils ont la même origine.

J’utilise Kometa sur Plex et j’ai trouvé son pendant pour Jellyfin avec Aphrodite de jackkerouac. Enfin en mieux, selon moi, plus configurable et en WebUI.

Pour nos bibliothèques Jellyfin on peut tout simplement changer les affiches (bases), configurer et ajouter tout ou au choix la résolution, l’audio, les notes et les récompenses.

Avec la totale, ça peut donner ceci.

aphrodite20
aphrodite preview 1757492972706
aphrodite preview 1757493205061


Ça ne fonctionne évidemment pas sur les affiches des collections vu que ces badges concernent une vidéo donnée.

aphrodite21

Pour répondre à nos besoins, sommaires vu que je connais mes règles Radarr/Sonarr, je n’affiche que les notes et récompenses.

aphrodite23


Via la WebUI on peut planifier des opérations (cron) pour appliquer tout ou partie des badges sur les bibliothèques sélectionnées. En reprenant ou non les éléments déjà traités.
En revanche, pour la modification des affiches, c’est à faire manuellement, par grappes de 50 (ouais, léger…).

L’installation est relativement simple, j’ai cependant rencontré pas mal de soucis en ne configurant que via la WebUI pour Jellyfin. J’ai tout décommenté/renseigné dans le .env et ça roule.

Comme indiqué sur le GitHub, il faut télécharger le compose et son .env. Je mets ça dans /home/aerya/docker/aphrodite

# Créer le dossier entrer dedans
mkdir /home/aerya/docker/aphrodite && cd /home/aerya/docker/aphrodite

# Télécharger le docker-compose et le .env
curl -L https://github.com/jackkerouac/aphrodite/releases/latest/download/docker-compose.yml -o docker-compose.yml
curl -L https://github.com/jackkerouac/aphrodite/releases/latest/download/default.env.example -o .env


Et on passe à l’édition du compose.
Par rapport au compose de base, j’ai juste modifié les volumes sur la base de /home/aerya/docker/aphrodite/…

Mis en always pour « restart » et ajouté la MàJ auto d’Aphrodite avec watchtower. Pas la peine pour Postgre et Redis vu que ça va chercher des versions précises.
Tout le reste se modifie dans .env qui suit

services:
  postgres:
    image: postgres:15-alpine
    container_name: aphrodite-postgres
    restart: always
    ports:
      - ${POSTGRES_PORT:-5433}:5432
    environment:
      POSTGRES_DB: ${POSTGRES_DB:-aphrodite}
      POSTGRES_USER: ${POSTGRES_USER:-aphrodite}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-aphrodite123}
    volumes:
      - /home/aerya/docker/aphrodite/postgres_data:/var/lib/postgresql/data
    healthcheck:
      test:
        - CMD-SHELL
        - pg_isready -U ${POSTGRES_USER:-aphrodite}
      interval: 10s
      timeout: 10s
      retries: 5
  redis:
    image: redis:7-alpine
    container_name: aphrodite-redis
    restart: always
    ports:
      - ${REDIS_PORT:-6379}:6379
    volumes:
      - /home/aerya/docker/aphrodite/redis_data:/data
    healthcheck:
      test:
        - CMD
        - redis-cli
        - ping
      interval: 10s
      timeout: 10s
      retries: 5
  aphrodite:
    image: ${APHRODITE_IMAGE:-ghcr.io/jackkerouac/aphrodite:latest}
    container_name: aphrodite
    pull_policy: always
    restart: always
    environment:
      POSTGRES_HOST: postgres
      POSTGRES_PORT: 5432
      POSTGRES_DB: ${POSTGRES_DB:-aphrodite}
      POSTGRES_USER: ${POSTGRES_USER:-aphrodite}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-aphrodite123}
      DATABASE_URL: ${DATABASE_URL:-postgresql+asyncpg://aphrodite:aphrodite123@postgres:5432/aphrodite}
      REDIS_URL: ${REDIS_URL:-redis://redis:6379/0}
      API_HOST: ${API_HOST:-0.0.0.0}
      API_PORT: ${API_PORT:-8000}
      ENVIRONMENT: ${ENVIRONMENT:-production}
      SECRET_KEY: ${SECRET_KEY:-please-change-this-secret-key-in-production}
      ALLOWED_HOSTS: ${ALLOWED_HOSTS:-*}
      CORS_ORIGINS: ${CORS_ORIGINS:-*}
      LOG_LEVEL: ${LOG_LEVEL:-info}
      LOG_FILE_PATH: ${LOG_FILE_PATH:-/app/logs/aphrodite-v2.log}
      DEBUG: ${DEBUG:-false}
      CELERY_BROKER_URL: ${CELERY_BROKER_URL:-redis://redis:6379/0}
      CELERY_RESULT_BACKEND: ${CELERY_RESULT_BACKEND:-redis://redis:6379/1}
      ENABLE_BACKGROUND_JOBS: ${ENABLE_BACKGROUND_JOBS:-true}
      JELLYFIN_URL: ${JELLYFIN_URL:-}
      JELLYFIN_API_KEY: ${JELLYFIN_API_KEY:-}
      JELLYFIN_USER_ID: ${JELLYFIN_USER_ID:-}
    ports:
      - ${APHRODITE_PORT:-8000}:8000
    volumes:
      - /home/aerya/docker/aphrodite/aphrodite_data:/app/data
      - /home/aerya/docker/aphrodite/aphrodite_logs:/app/logs
      - /home/aerya/docker/aphrodite/aphrodite_media:/app/media
      - /home/aerya/docker/aphrodite/aphrodite_static:/app/api/static/originals
    labels:
      - com.centurylinklabs.watchtower.enable=true
    depends_on:
      postgres:
        condition: service_healthy
      redis:
        condition: service_healthy
    healthcheck:
      test:
        - CMD
        - curl
        - -f
        - http://localhost:8000/health/live
      interval: 10s
      timeout: 10s
      retries: 5
      start_period: 40s
  aphrodite-worker:
    image: ${APHRODITE_IMAGE:-ghcr.io/jackkerouac/aphrodite:latest}
    container_name: aphrodite-worker
    pull_policy: always
    restart: always
    command:
      - python3
      - -m
      - celery
      - -A
      - celery_app
      - worker
      - --loglevel=debug
      - --pool=solo
      - --concurrency=1
    environment:
      POSTGRES_HOST: postgres
      POSTGRES_PORT: 5432
      POSTGRES_DB: ${POSTGRES_DB:-aphrodite}
      POSTGRES_USER: ${POSTGRES_USER:-aphrodite}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-aphrodite123}
      DATABASE_URL: ${DATABASE_URL:-postgresql+asyncpg://aphrodite:aphrodite123@postgres:5432/aphrodite}
      REDIS_URL: ${REDIS_URL:-redis://redis:6379/0}
      CELERY_BROKER_URL: ${CELERY_BROKER_URL:-redis://redis:6379/0}
      CELERY_RESULT_BACKEND: ${CELERY_RESULT_BACKEND:-redis://redis:6379/1}
      ENVIRONMENT: ${ENVIRONMENT:-production}
      SECRET_KEY: ${SECRET_KEY:-please-change-this-secret-key-in-production}
      LOG_LEVEL: ${LOG_LEVEL:-info}
      LOG_FILE_PATH: ${LOG_FILE_PATH:-/app/logs/aphrodite-v2.log}
      PYTHONPATH: /app
    volumes:
      - /home/aerya/docker/aphrodite/aphrodite_data:/app/data
      - /home/aerya/docker/aphrodite/aphrodite_logs:/app/logs
      - /home/aerya/docker/aphrodite/aphrodite_media:/app/media
      - /home/aerya/docker/aphrodite/aphrodite_static:/app/api/static/originals
    labels:
      - com.centurylinklabs.watchtower.enable=true
    depends_on:
      postgres:
        condition: service_healthy
      redis:
        condition: service_healthy
    working_dir: /app/api
    healthcheck:
      test:
        - CMD
        - python3
        - -c
        - import sys; sys.path.insert(0, '/app'); from celery_app import
          celery_app; print('Worker healthy')
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 60s
networks:
  default:
    name: aphrodite_network


Et le fameux .env. Comme expliqué plus haut, après plusieurs tests, il faut y paramétrer le serveur Jellyfin et également décommenter les informations liées à Postgre et Redis. J’ai passé les logs en DEBUG vu les soucis que je rencontrais au début.

Pour créer la SECRET_KEY : (en console) openssl rand -hex 64

Et ne pas oublier de mettre le mot de passe POSTGRES_PASSWORD dans la partie DATABASE_URL
Créer une clé API dans Jellyfin via le menu tout en bas du Tableau de bord

Et récupérer l’ID utilisateur qui sera utilisée pour connecter Aphrodite. Dans Tableau de bord/Utilisateurs, cliquer sur le user et l’ID est à la fin de l’URL

# =============================================================================
# Docker Image Configuration
# =============================================================================
# Leave blank to always pull the latest version from GitHub Container Registry
# APHRODITE_IMAGE=ghcr.io/jackkerouac/aphrodite:latest

# =============================================================================
# Database Configuration
# =============================================================================
# IMPORTANT: Change POSTGRES_PASSWORD to a secure password!
# This password will be used to create the database user
POSTGRES_DB=aphrodite
POSTGRES_USER=aphrodite
POSTGRES_PASSWORD=motdepassedelamortquitue
POSTGRES_PORT=5432

# =============================================================================
# Redis Configuration
# =============================================================================
REDIS_PORT=6379

# =============================================================================
# Security Configuration (REQUIRED)
# =============================================================================
SECRET_KEY=4c887cda6e10bac46eb61a961e38f4626609c9caeca08123ed1d6d876c6b14c20a11118cec534f26d5d5de4f5b6935fa07ff8887b91322058c20f95705025fa0
# =============================================================================
# Application Configuration
# =============================================================================
# Port to run Aphrodite on (default: 8000)
APHRODITE_PORT=8000

# API Configuration
API_HOST=0.0.0.0
API_PORT=8000

# Environment
ENVIRONMENT=production

# Logging level (debug, info, warning, error)
LOG_LEVEL=debug
DEBUG=true

# Network Configuration
ALLOWED_HOSTS=*
CORS_ORIGINS=*

# =============================================================================
# Background Jobs Configuration
# =============================================================================
ENABLE_BACKGROUND_JOBS=true
CELERY_BROKER_URL=redis://redis:6379/0
CELERY_RESULT_BACKEND=redis://redis:6379/1

# =============================================================================
# Database & Redis URLs (Advanced - Override defaults if needed)
# =============================================================================
DATABASE_URL=postgresql+asyncpg://aphrodite:motdepassedelamortquitue@postgres:5432/aphrodite
REDIS_URL=redis://redis:6379/0

# =============================================================================
# Jellyfin Integration (Optional - Configure via Web Interface)
# =============================================================================
# You can set these here or configure them in the web interface
JELLYFIN_URL=https://jelly.domaine.tld
JELLYFIN_API_KEY=xxx
JELLYFIN_USER_ID=xxx


On peut ensuite lancer la Docker et aller visiter les paramètres d’Aphrodite. Mon screen date de ma 1ère installation aussi je ne sais plus si les paramètres de Jellyfin sont déjà remplis par le biais du .env

Il faut aller récupérer (ou créer) ses clés API :
OMDB : version gratuite, clé dans le mail qu’on reçoit suite à l’inscription
TMDB : le token, pas la clé
MDBList : en bas de page
AniDB si vous avez des mangas : j’ai pas regardé plus que ça pour créer une clé API

aphrodite2

C’est par ailleurs dans cette partie qu’on peut configurer les badges à mettre en overlay sur les affiches. Je ne rentre pas dans les détails, il y a tellement de personnalisation possible que c’est propre à chacun.
Aphrodite étant tout jeune, les notes ne sont pour l’instant disponibles qu’à partir d’IMDb, Metacritic, MyAnimeList, Rotten Tomatoes et TMDb. C’est déjà pas mal même si je suis impatient de voir Trakt arriver. TMDb et Trakt.tv ont maintenant un nombre d’utilisateurs suffisant pour avoir plusieurs centaines de votes et les rendre qualitatifs.
Il n’y a évidemment pas AlloCiné, pardon pour ceux qui y bossent, mais c’est bien trop franco-nombriliste-français pour avoir une quelconque utilité dans la galaxie des *arrs et du streaming.


aphrodite4
aphrodite5
aphrodite6
aphrodite7
aphrodite8
aphrodite10
aphrodite11


Pour l’audio et la vidéo, Aphrodite peut détecter les données via l’analyse des fichiers. Faut évidemment avoir la machine qui le permet sans que ça prenne des heures.

aphrodite24
aphrodite25

On peut générer un aperçu de sa configuration via le menu Preview

aphrodite26

Avant d’aller plus loin, il faut prendre le temps de vérifier l’import des bibliothèques suite à la connexion avec Jellyfin, dans le menu Poster Manager.
C’est ballot, j’ai pas pensé à faire de screen avant de modifier mes affiches…

aphrodite29

Ici on peut modifier les affiches, par lots de 50 donc faut être patient… C’est sympa, ça change mais on ne peut pas faire de choix et, pour l’instant, il n’y a pas MediUX d’intégré. Mais le projet est jeune, ça a le temps de venir.

aphrodite30

C’est également dans ce menu qu’on peut lancer à la demande l’application des badges, toujours par lots de 50 affiches. Ça peut être intéressant pour tester ou s’occuper des bibliothèques spécifiques avec peu de contenus.

aphrodite31

Et ensuite passer aux choses sérieuses avec la mise en place de tâches (ou d’une seule, c’est selon) via les Schedules

aphrodite27

Après avoir testé plusieurs configurations, j’ai créé une tâche qui se répète toutes les heures pour mes 2 bibliothèques, pour les contenus non encore « badgés » et seulement les notes et récompenses, comme expliqué au début de mon article.

aphrodite28

On peut déclencher le travail directement, sans attendre la prochaine planification et mes bibliothèques passent d’affiches simples

aphrodite18

à des badgées selon mes préférences !
Il y a eu l’ajout de collections entre temps également, depuis Jellyfin.

aphrodite40

Au final ça tourne très bien, il y a presque trop de réglages possibles quand on est comme moi un éternel insatisfait ^^’

Aphrodite est encore jeune et en sus de l’utiliser je suivrai assurément ses évolutions !

Loading

❌