Intégration externe - Jellyfin / Emby

Salut à tous :waving_hand:

Comme annoncé dans le sujet des intégrations Home Assistant à porter, voici Jellyfin & Emby : une seule intégration pour les deux serveurs (Jellyfin est un fork d’Emby, l’API est commune), qui détecte seule à quel serveur elle parle. @AlexTrovato, c’est ta demande d’août :wink:

[capture du tableau de bord]

Ce que ça fait

Un appareil par lecteur (application TV, téléphone, navigateur) :

  • :play_button: lecture, pause, stop, précédent, suivant, retour et avance rapide, volume, muet
  • :musical_note: l’état de lecture, compatible avec le widget Musique du tableau de bord
  • :label: le titre en cours et le temps restant
  • :sparkles: « pendant l’intro » et « pendant le générique » : sous Jellyfin 10.10+ avec un plugin de segments (Chapter Segments Provider, Intro Skipper…), sous Emby avec sa détection des intros

Un appareil serveur : lectures en cours, transcodages, un résumé « qui regarde quoi » et un compteur par bibliothèque.

:bullseye: Scènes

Quatre déclencheurs, Lecture démarrée / en pause / reprise / arrêtée, filtrables par lecteur et par type de média (film, épisode, musique, TV en direct…) :

:clapper_board: Un film démarre sur la TV du salon → lumières tamisées
:pause_button: Pause → on rallume

Et deux actions de scène :

  • :bell: Afficher un message sur un lecteur : « On sonne à la porte » par-dessus le film
  • :popcorn: Lire un média sur un lecteur : cherche un titre dans la bibliothèque (film, série, album, artiste, liste de lecture) et le lance, en aléatoire si besoin

:framed_picture: Widgets

  • En cours de lecture : qui regarde quoi, où, avec les affiches
  • Lecteur : la lecture en cours en télécommande (image de fond, titre, temps restant, boutons). Réglage vide = il suit ce qui joue ; ou choisissez un lecteur précis
  • Derniers ajouts : les affiches des derniers films, séries ou albums, les nouveaux épisodes regroupés par série

Installation

:warning: Gladys 5.1 minimum.

  1. Créez une clé d’API pour Gladys : sous Jellyfin, Tableau de bord → Clés API ; sous Emby, Paramètres → Avancé → Clés API
  2. Dans Gladys : Intégrations → Multimédia → Jellyfin & Emby
  3. Renseignez l’URL du serveur (http://ip-du-serveur:8096, ou votre adresse https) et la clé, puis Tester la connexion
  4. Onglet Découverte : ajoutez le serveur et vos lecteurs

Un lecteur n’apparaît que lorsqu’il est connecté au serveur : ouvrez l’application sur la TV, puis cliquez sur « Rechercher les lecteurs ».

Ce que j’aimerais que vous testiez :folded_hands:

Je l’ai testée sur Jellyfin 10.11 et 12.1 et sur Emby 4.10, avec un lecteur simulé. Il me manque les vraies conditions :

  • vos applications TV (Android TV, Fire TV, LG, Samsung…) : les boutons, le volume, le message à l’écran
  • Emby : tout, et en particulier l’intro et le générique
  • un serveur derrière un reverse proxy : si le WebSocket ne passe pas, l’intégration se rabat sur une interrogation toutes les 15 s (dites-moi si c’est le cas, les journaux le signalent)

En cas de souci, les journaux de l’intégration, visibles dans Gladys, m’aident énormément.

C’est une 0.2.0 : la 1.0 viendra avec vos retours. Code, doc FR/EN et tests : GitHub - guim31/gladys-jellyfin · GitHub

Salut et merci :television:

Testé avec mon serveur Jellyfin derrière proxy (mais le websocket fonctionne) :white_check_mark:
Appareils découverts et ajoutés avec succès.
Les widgets affichent bien les lecteurs/lectures en courts et le derniers ajouts :star_struck:
Les actions et déclencheurs fonctionnent sauf celle pour envoyer un message (testé avec client iPhone officiel et Apple Tv officiel).
Les fonctions Pause/Lecture et Stop marchent bien sur le widget (mais avec quelques secondes de latence sur le retour de l’état). Par contre, rien du tout avec le bouton suivant.

Voici mes logs :

[2026-09-27T20:31:16.413Z] [INFO] Starting the Jellyfin & Emby integration v0.2.0...
[2026-09-27T20:31:17.027Z] [INFO] [gladys-sdk] connected to Gladys (http://172.30.0.1:80)
[2026-09-27T20:31:17.119Z] [INFO] Waiting for the configuration (server URL + API key)
[2026-09-27T20:32:03.208Z] [INFO] onConfigUpdated -> new configuration received
[2026-09-27T20:32:03.401Z] [INFO] [media-monitor] Connected to Jellyfin server "99b9829bee05" (v12.1.0)
[2026-09-27T20:32:03.478Z] [INFO] [media-monitor] New player discovered: Firefox (Jellyfin Web)
[2026-09-27T20:32:03.871Z] [INFO] [media-socket] Real-time socket connected
[2026-09-27T20:32:07.675Z] [INFO] [media-monitor] Connected to Jellyfin server "99b9829bee05" (v12.1.0)
[2026-09-27T20:32:07.694Z] [INFO] [media-monitor] New player discovered: Firefox (Jellyfin Web)
[2026-09-27T20:32:39.225Z] [INFO] [media-monitor] New player discovered: iPhone de Cyril (Jellyfin iOS)
[2026-09-27T20:32:39.382Z] [INFO] [media-monitor] Scene event playback_started: Severance - S01E02 - Demi-boucle on iPhone de Cyril
[2026-09-27T20:32:50.765Z] [INFO] onDeviceCreated <- ext:ext-guim31-gladys-jellyfin:player:62eff0df731b02bf
[2026-09-27T20:32:52.309Z] [INFO] onDeviceCreated <- ext:ext-guim31-gladys-jellyfin:server:76b6e7325e104d378c17f1432a1a0dde
[2026-09-27T20:35:20.643Z] [INFO] onSetValue <- ext:ext-guim31-gladys-jellyfin:player:62eff0df731b02bf:pause = 1
[2026-09-27T20:35:20.731Z] [INFO] [media-monitor] Command pause sent to iPhone de Cyril
[2026-09-27T20:35:29.191Z] [INFO] onSetValue <- ext:ext-guim31-gladys-jellyfin:player:62eff0df731b02bf:pause = 1
[2026-09-27T20:35:29.243Z] [INFO] [media-monitor] Command pause sent to iPhone de Cyril
[2026-09-27T20:35:35.099Z] [INFO] onSetValue <- ext:ext-guim31-gladys-jellyfin:player:62eff0df731b02bf:stop = 1
[2026-09-27T20:35:35.176Z] [INFO] [media-monitor] Command stop sent to iPhone de Cyril
[2026-09-27T20:35:50.401Z] [INFO] onSetValue <- ext:ext-guim31-gladys-jellyfin:player:62eff0df731b02bf:pause = 1
[2026-09-27T20:35:50.479Z] [INFO] [media-monitor] Command pause sent to iPhone de Cyril
[2026-09-27T20:37:57.838Z] [INFO] [media-monitor] Message displayed on iPhone de Cyril
[2026-09-27T20:38:27.762Z] [INFO] [media-monitor] Playing "Vaiana, la légende du bout du monde (2016)" on iPhone de Cyril
[2026-09-27T20:38:31.917Z] [INFO] [media-monitor] Playing "Vaiana, la légende du bout du monde (2016)" on iPhone de Cyril
[2026-09-27T20:39:26.866Z] [INFO] [media-monitor] Scene event playback_paused: Severance - S01E02 - Demi-boucle on iPhone de Cyril
[2026-09-27T20:39:30.246Z] [INFO] [media-monitor] New player discovered: AppleTV (Swiftfin tvOS)
[2026-09-27T20:39:40.014Z] [INFO] [media-monitor] Playing "Vaiana, la légende du bout du monde (2016)" on iPhone de Cyril
[2026-09-27T20:40:11.116Z] [INFO] onDeviceCreated <- ext:ext-guim31-gladys-jellyfin:player:aa7023ad2115e61c
[2026-09-27T20:40:26.749Z] [INFO] [media-monitor] Playing "Severance" on AppleTV
[2026-09-27T20:40:32.684Z] [INFO] [media-monitor] Scene event playback_started: Severance - S01E01 - Le bon côté de l'enfer on AppleTV
[2026-09-27T20:41:01.842Z] [INFO] [media-monitor] Scene event playback_paused: Severance - S01E01 - Le bon côté de l'enfer on AppleTV
[2026-09-27T20:41:14.032Z] [INFO] [media-monitor] Scene event playback_resumed: Severance - S01E01 - Le bon côté de l'enfer on AppleTV
[2026-09-27T20:41:29.032Z] [INFO] onSetValue <- ext:ext-guim31-gladys-jellyfin:player:aa7023ad2115e61c:pause = 1
[2026-09-27T20:41:29.120Z] [INFO] [media-monitor] Command pause sent to AppleTV
[2026-09-27T20:41:31.034Z] [INFO] onSetValue <- ext:ext-guim31-gladys-jellyfin:player:aa7023ad2115e61c:pause = 1
[2026-09-27T20:41:31.042Z] [INFO] [media-monitor] Command pause sent to AppleTV
[2026-09-27T20:41:34.246Z] [INFO] [media-monitor] Scene event playback_paused: Severance - S01E01 - Le bon côté de l'enfer on AppleTV
[2026-09-27T20:41:35.699Z] [INFO] onSetValue <- ext:ext-guim31-gladys-jellyfin:player:aa7023ad2115e61c:play = 1
[2026-09-27T20:41:35.709Z] [INFO] [media-monitor] Command play sent to AppleTV
[2026-09-27T20:41:40.846Z] [INFO] [media-monitor] Scene event playback_resumed: Severance - S01E01 - Le bon côté de l'enfer on AppleTV
[2026-09-27T20:41:48.766Z] [INFO] onSetValue <- ext:ext-guim31-gladys-jellyfin:player:aa7023ad2115e61c:next = 1
[2026-09-27T20:41:48.843Z] [INFO] [media-monitor] Command next sent to AppleTV
[2026-09-27T20:41:58.735Z] [INFO] onSetValue <- ext:ext-guim31-gladys-jellyfin:player:aa7023ad2115e61c:stop = 1
[2026-09-27T20:41:58.793Z] [INFO] [media-monitor] Command stop sent to AppleTV
[2026-09-27T20:41:58.923Z] [INFO] [media-monitor] Scene event playback_stopped: Severance - S01E01 - Le bon côté de l'enfer on AppleTV
[2026-09-27T20:42:11.278Z] [INFO] [media-monitor] Scene event playback_started: Severance - S01E02 - Demi-boucle on AppleTV
[2026-09-27T20:42:15.261Z] [INFO] onSetValue <- ext:ext-guim31-gladys-jellyfin:player:aa7023ad2115e61c:pause = 1
[2026-09-27T20:42:15.352Z] [INFO] [media-monitor] Command pause sent to AppleTV
[2026-09-27T20:42:20.614Z] [INFO] [media-monitor] Scene event playback_paused: Severance - S01E02 - Demi-boucle on AppleTV

Au top les retour, je regarde ça demain !