External integration - Jellyfin / Emby

Hi everyone :waving_hand:

As announced in the topic of Home Assistant integrations to port, here is Jellyfin & Emby: a single integration for both servers (Jellyfin is a fork of Emby, the API is common), which automatically detects which server it is communicating with. @AlexTrovato, this is your request from August :wink:

[screenshot of the dashboard]

What it does

One device per player (TV app, phone, browser):

  • :play_button: play, pause, stop, previous, next, rewind and fast forward, volume, mute
  • :musical_note: the playback state, compatible with the Music widget on the dashboard
  • :label: the current title and remaining time
  • :sparkles: « during the intro Â» and « during the credits Â»: under Jellyfin 10.10+ with a segments plugin (Chapter Segments Provider, Intro Skipper
), under Emby with its intro detection

One server device: current plays, transcodes, a summary of « who is watching what Â» and a counter per library.

:bullseye: Scenes

Four triggers, Playback started / paused / resumed / stopped, filterable by player and media type (movie, episode, music, live TV
):

:clapper_board: A movie starts on the living room TV → dim the lights
:pause_button: Pause → turn them back on

And two scene actions:

  • :bell: Display a message on a player: « Someone is at the door Â» over the movie
  • :popcorn: Play a media on a player: search for a title in the library (movie, series, album, artist, playlist) and play it, randomly if needed

:framed_picture: Widgets

  • Now playing: who is watching what, where, with the posters
  • Player: the current playback in remote control (background image, title, remaining time, buttons). Blank setting = it follows what is playing; or choose a specific player
  • Recently added: the posters of the latest movies, series or albums, the new episodes grouped by series

Installation

:warning: Gladys 5.1 minimum.

  1. Create an API key for Gladys: under Jellyfin, Dashboard → API Keys; under Emby, Settings → Advanced → API Keys
  2. In Gladys: Integrations → Multimedia → Jellyfin & Emby
  3. Enter the server URL (http://server-ip:8096, or your https address) and the key, then Test the connection
  4. Discovery tab: add the server and your players

A player only appears when it is connected to the server: open the app on the TV, then click on « Search for players Â».

What I would like you to test :folded_hands:

I tested it on Jellyfin 10.11 and 12.1 and on Emby 4.10, with a simulated player. I am missing real conditions:

  • your TV apps (Android TV, Fire TV, LG, Samsung
): the buttons, the volume, the on-screen message
  • Emby: everything, and especially the intro and the credits
  • a server behind a reverse proxy: if the WebSocket does not pass, the integration falls back to a query every 15 s (let me know if this is the case, the logs report it)

In case of trouble, the integration logs, visible in Gladys, help me a lot.

This is a 0.2.0: the 1.0 will come with your feedback. Code, FR/EN doc and tests: GitHub - guim31/gladys-jellyfin · GitHub

Hi and thanks :television:

Tested with my Jellyfin server behind a proxy (but the websocket works) :white_check_mark:
Devices discovered and added successfully.
The widgets display the players/playbacks in short and the latest additions :star_struck:
Actions and triggers work except the one to send a message (tested with the official iPhone client and the official Apple TV).
The Pause/Play and Stop functions work on the widget (but with a few seconds of latency on the state return). However, nothing at all with the next button.

Here are my 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: Cyril's iPhone (Jellyfin iOS)
[2026-09-27T20:32:39.382Z] [INFO] [media-monitor] Scene event playback_started: Severance - S01E02 - Half Loop on Cyril's iPhone
[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 Cyril's iPhone
[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 Cyril's iPhone
[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 Cyril's iPhone
[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 Cyril's iPhone
[2026-09-27T20:37:57.838Z] [INFO] [media-monitor] Message displayed on Cyril's iPhone
[2026-09-27T20:38:27.762Z] [INFO] [media-monitor] Playing "Moana (2016)" on Cyril's iPhone
[2026-09-27T20:38:31.917Z] [INFO] [media-monitor] Playing "Moana (2016)" on Cyril's iPhone
[2026-09-27T20:39:26.866Z] [INFO] [media-monitor] Scene event playback_paused: Severance - S01E02 - Half Loop on Cyril's iPhone
[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 "Moana (2016)" on Cyril's iPhone
[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 - The Good Half on AppleTV
[2026-09-27T20:41:01.842Z] [INFO] [media-monitor] Scene event playback_paused: Severance - S01E01 - The Good Half on AppleTV
[2026-09-27T20:41:14.032Z] [INFO] [media-monitor] Scene event playback_resumed: Severance - S01E01 - The Good Half 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 - The Good Half 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 - The Good Half 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 - The Good Half on AppleTV
[2026-09-27T20:42:11.278Z] [INFO] [media-monitor] Scene event playback_started: Severance - S01E02 - Half Loop 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 - Half Loop on AppleTV

Great feedback, I’ll check it out tomorrow!