Published 2024-07-30.
Last modified 2024-12-13.
Time to read: 5 minutes.
posts
collection.
I have been using Plex on one of my home Ubuntu servers for years to serve movies and images. The experience has been OK; however, I would prefer a platform that I could customize. I also do not like that Plex charges a monthly fee for simple features, like the ability to restrict access to selected media for certain users.
When I read
about the free and open-source Jellyfin product, I decided to give it a try.
The website is jellyfin.org
and
the Jellyfin Reddit channel (r/jellyfin
)
is a good place to discuss the product.
The jellyfin
GitHub account
has several projects.
The following are the most interesting to me:
jellyfin-plugin-template
(.NET; GPL-3.0 license)jellyfin-sdk-typescript
(TypeScript / React; Mozilla Public License Version 2.0)jellyfin-web
(TypeScript, JavaScript and SCSS; GPL v2 license)
The originator of the Jellyfin project,
@nullsum
on Reddit,
described how he came up with the name.
streaming → water → ocean → jellyfish + dolphin → jellyfin!
Summary
Jellyfin is less capable than Plex. The clients have uneven capbilities, and the Roku client is severely deficient.
On the server side, Jellyfin creates many images when scanning videos. Unlike Plex, which tucks those images away and cleans them up responsibly, Jellyfin intermixes the images with the videos, and does not maintain them. As a result, your media directory fills up with garbage over time.
Installation
Ubuntu Server
The Jellyfin server has been ported to Arch Linux, Debian/Ubuntu, Fedora Linux, Gentoo Linux, macOS, and Windows. There is also a generic Linux port and a portable Linux port.
The Jellyfin server runs as a service. The installation routine installs and starts the service. This is the incantation I used to install the Jellyfin server onto one of my home Ubuntu servers:
$ curl -s https://repo.jellyfin.org/install-debuntu.sh | sudo bash > Determining optimal repository settings.
Found the following details from '/etc/os-release': Real OS: ubuntu Repository OS: ubuntu Repository Release: mantic CPU Architecture: amd64 If this looks correct, press <Enter> now to continue installing Jellyfin. > Fetching repository signing key.
> Installing Jellyfin repository into APT. Types: deb URIs: https://repo.jellyfin.org/ubuntu Suites: mantic Components: main Architectures: amd64 Signed-By: /etc/apt/keyrings/jellyfin.gpg
> Updating APT repositories. Hit:1 http://ca.archive.ubuntu.com/ubuntu mantic InRelease Hit:2 http://ca.archive.ubuntu.com/ubuntu mantic-updates InRelease Hit:3 https://downloads.plex.tv/repo/deb public InRelease Hit:4 http://ca.archive.ubuntu.com/ubuntu mantic-backports InRelease Hit:5 https://dl.google.com/linux/chrome/deb stable InRelease Get:6 https://repo.jellyfin.org/ubuntu mantic InRelease [6,601 B] Hit:7 http://security.ubuntu.com/ubuntu mantic-security InRelease Get:9 https://tor1.mirror.jellyfin.org/files/ubuntu mantic/main amd64 Packages [1,990 B] Hit:8 https://scala.jfrog.io/artifactory/debian all InRelease Ign:10 https://scala.jfrog.io/artifactory/debian InRelease Hit:11 https://scala.jfrog.io/artifactory/debian Release Fetched 8,591 B in 1s (6,189 B/s) Reading package lists... Done Building dependency tree... Done Reading state information... Done 1 package can be upgraded. Run 'apt list --upgradable' to see it. W: https://repo.scala-sbt.org/scalasbt/debian/dists/all/InRelease: Key is stored in legacy trusted.gpg keyring (/etc/apt/trusted.gpg), see the DEPRECATION section in apt-key(8) for details. W: https://repo.scala-sbt.org/scalasbt/debian/Release.gpg: Key is stored in legacy trusted.gpg keyring (/etc/apt/trusted.gpg), see the DEPRECATION section in apt-key(8) for details.
> Installing Jellyfin. Reading package lists... Done Building dependency tree... Done Reading state information... Done The following additional packages will be installed: at jellyfin-ffmpeg5 jellyfin-server jellyfin-web libllvm17 The following NEW packages will be installed: at jellyfin jellyfin-ffmpeg5 jellyfin-server jellyfin-web libllvm17 0 upgraded, 6 newly installed, 0 to remove and 1 not upgraded. Need to get 151 MB of archives. After this operation, 512 MB of additional disk space will be used. Get:1 http://ca.archive.ubuntu.com/ubuntu mantic/universe amd64 at amd64 3.2.5-1ubuntu1 [41.1 kB] Get:2 http://ca.archive.ubuntu.com/ubuntu mantic/universe amd64 libllvm17 amd64 1:17.0.2-1~exp1ubuntu2.1 [26.1 MB] Get:3 https://tor1.mirror.jellyfin.org/files/ubuntu mantic/main amd64 jellyfin-server amd64 10.8.13-1 [38.6 MB] Get:4 https://nyc1.mirror.jellyfin.org/files/ubuntu mantic/main amd64 jellyfin-web all 10.8.13-1 [42.3 MB] Get:6 https://tor1.mirror.jellyfin.org/files/ubuntu mantic/main amd64 jellyfin all 10.8.13-1 [2,284 B] Get:5 https://nyc1.mirror.jellyfin.org/files/ubuntu mantic/main amd64 jellyfin-ffmpeg5 amd64 5.1.4-3-mantic [44.1 MB] Fetched 151 MB in 2s (74.1 MB/s) Selecting previously unselected package at. (Reading database ... 485611 files and directories currently installed.) Preparing to unpack .../0-at_3.2.5-1ubuntu1_amd64.deb ... Unpacking at (3.2.5-1ubuntu1) ... Selecting previously unselected package jellyfin-server. Preparing to unpack .../1-jellyfin-server_10.8.13-1_amd64.deb ... Unpacking jellyfin-server (10.8.13-1) ... Selecting previously unselected package jellyfin-web. Preparing to unpack .../2-jellyfin-web_10.8.13-1_all.deb ... Unpacking jellyfin-web (10.8.13-1) ... Selecting previously unselected package libllvm17:amd64. Preparing to unpack .../3-libllvm17_1%3a17.0.2-1~exp1ubuntu2.1_amd64.deb ... Unpacking libllvm17:amd64 (1:17.0.2-1~exp1ubuntu2.1) ... Selecting previously unselected package jellyfin-ffmpeg5. Preparing to unpack .../4-jellyfin-ffmpeg5_5.1.4-3-mantic_amd64.deb ... Unpacking jellyfin-ffmpeg5 (5.1.4-3-mantic) ... Selecting previously unselected package jellyfin. Preparing to unpack .../5-jellyfin_10.8.13-1_all.deb ... Unpacking jellyfin (10.8.13-1) ... Setting up jellyfin-web (10.8.13-1) ... Setting up at (3.2.5-1ubuntu1) ... Created symlink /etc/systemd/system/multi-user.target.wants/atd.service → /lib/systemd/system/atd.service. Setting up jellyfin-server (10.8.13-1) ... Created symlink /etc/systemd/system/multi-user.target.wants/jellyfin.service → /lib/systemd/system/jellyfin.service. Setting up libllvm17:amd64 (1:17.0.2-1~exp1ubuntu2.1) ... Setting up jellyfin-ffmpeg5 (5.1.4-3-mantic) ... Setting up jellyfin (10.8.13-1) ... Processing triggers for man-db (2.11.2-3) ... Processing triggers for libc-bin (2.38-1ubuntu6.3) ...
> Waiting 15 seconds for Jellyfin to fully start up.
------------------------------------------------------------------------------- ● jellyfin.service - Jellyfin Media Server Loaded: loaded (/lib/systemd/system/jellyfin.service; enabled; preset: enabled) Drop-In: /etc/systemd/system/jellyfin.service.d └─jellyfin.service.conf Active: active (running) since Sun 2024-07-28 13:20:56 EDT; 18s ago Main PID: 1271661 (jellyfin) Tasks: 25 (limit: 77001) Memory: 71.5M CPU: 4.787s CGroup: /system.slice/jellyfin.service └─1271661 /usr/bin/jellyfin --webdir=/usr/share/jellyfin/web --restartpath=/usr/lib/jellyfin/restart.sh --ffmpeg=/usr/lib/jelly…
Jul 28 13:21:00 BamBam jellyfin[1271661]: [13:21:00] [INF] ServerId: e2bec4b0b6ac4bc6b521ea0e5cb25bf9 Jul 28 13:21:00 BamBam jellyfin[1271661]: [13:21:00] [INF] Executed all pre-startup entry points in 0:00:00.1294312 Jul 28 13:21:00 BamBam jellyfin[1271661]: [13:21:00] [INF] Core startup complete Jul 28 13:21:00 BamBam jellyfin[1271661]: [13:21:00] [INF] Executed all post-startup entry points in 0:00:00.1755308 Jul 28 13:21:00 BamBam jellyfin[1271661]: [13:21:00] [INF] Startup complete 0:00:03.7260698 Jul 28 13:21:02 BamBam jellyfin[1271661]: [13:21:02] [INF] StartupTrigger fired for task: Update Plugins Jul 28 13:21:02 BamBam jellyfin[1271661]: [13:21:02] [INF] Queuing task PluginUpdateTask Jul 28 13:21:02 BamBam jellyfin[1271661]: [13:21:02] [INF] Executing Update Plugins Jul 28 13:21:03 BamBam jellyfin[1271661]: [13:21:03] [INF] Update Plugins Completed after 0 minute(s) and 0 seconds Jul 28 13:21:03 BamBam jellyfin[1271661]: [13:21:03] [INF] ExecuteQueuedTasks -------------------------------------------------------------------------------
You should see the service as 'active (running)' above. If not, use https://jellyfin.org/contact to find us for troubleshooting.
You can access your new instance now at http://192.168.1.180:8096 in your web browser to finish setting up Jellyfin.
Thank you for installing Jellyfin, and happy watching!
Firewall and Ports
Jellyfin can be accessed via port 8096.
If your server has a firewall, you need to open the appropriate ports.
Ubuntu 8.04 introduced the ufw
firewall,
and today it is the default firewall for Ubuntu.
The default ports used by Jellyfin are:
- 8096/tcp is the default for HTTP traffic. You can change this in the dashboard.
- 8920/tcp is the default for HTTPS traffic. You can change this in the dashboard.
- 1900/udp is used for service auto-discovery. This is not configurable.
- 7359/udp is also used for auto-discovery. This is not configurable.
I had already been using ufw
before installing Jellyfin.
At that time, the ufw
status was:
$ sudo ufw status Status: active
To Action From -- ------ ---- OpenSSH ALLOW Anywhere Nginx Full ALLOW Anywhere 9000 ALLOW Anywhere 9443 ALLOW Anywhere 32400 ALLOW Anywhere OpenSSH (v6) ALLOW Anywhere (v6) Nginx Full (v6) ALLOW Anywhere (v6) 9000 (v6) ALLOW Anywhere (v6) 9443 (v6) ALLOW Anywhere (v6) 32400 (v6) ALLOW Anywhere (v6)
To open the default ports that Jellyfin needed on my server, I typed:
$ sudo ufw allow 8096/tcp Rule added Rule added (v6)
$ sudo ufw allow 1900,7359/udp Rule added Rule added (v6)
Now the status was:
$ sudo ufw status Status: active
To Action From -- ------ ---- OpenSSH ALLOW Anywhere Nginx Full ALLOW Anywhere 9000 ALLOW Anywhere 9443 ALLOW Anywhere 32400 ALLOW Anywhere 8096/tcp ALLOW Anywhere 1900,7359/udp ALLOW Anywhere OpenSSH (v6) ALLOW Anywhere (v6) Nginx Full (v6) ALLOW Anywhere (v6) 9000 (v6) ALLOW Anywhere (v6) 9443 (v6) ALLOW Anywhere (v6) 32400 (v6) ALLOW Anywhere (v6) 8096/tcp (v6) ALLOW Anywhere (v6) 1900,7359/udp (v6) ALLOW Anywhere (v6)
Like any service, you can start
it, stop
it, and restart
it.
To stop it, type:
$ sudo service jellyfin stop
Clients
Various clients are available, including web browsers and native clients such as Android (on the Play Store), iOS (on the App Store), Linux, Roku (on the channel store), and more.
The only full-featured clients for Jellyfin that I could find were:
One of those clients must be used to configure Jellyfin so it can access your media, and they are the only clients that allow the user to delete media.
On the Jellyfin Reddit channel (r/jellyfin
) I learned that
none of the Jellyfin native TV clients
(including the Roku client) have the ability to delete media.
That sucks. Why has that not been taken care of?
Web Client
On my network, the URL to reach the Jellyfin server is
http://192.168.1.180:8096
.
When I opened that URL on my web browser, I saw the Jellyfin web client:
There were many more settings than I could capture in a screenshot:
I found that the Jellyfin web client was pretty good. It played videos quite well, unlike Plex’s web client, which stutters sometimes.
Android Client
You can install the Jellyfin Android client from the Google Play Store. It has 500K+ downloads, 3.9 stars, and 242 reviews. You can also download it from the Amazon App Store.
After installing, I found that only the IP address of my Jellyfin server needed to be typed; the Android client was smart enough to try port 8096. The Android client was able to delete media.
iOS Clients
The official iOS client (for iPad and iPhone) is Jellyfin Mobile. It has 4.2 stars on the Apple App Store, 260 ratings, and is a free download. A Jellyfin blog said:
The Jellyfin Mobile client provides users who have the appropriate credentials with the ability to delete media.
The Swiftfin client is supposedly better for playing media, but it doesn't allow for managing your content. Swiftfin never really came out of beta. I did not install it.
The Apple App Store also shows third-party Jellyfin clients, but I did not try them.
Desktop Clients
Desktop clients are available for Windows, macOS, and Linux.
I downloaded the current Windows client installer, JellyfinMediaPlayer-1.11.1-windows-x64.exe
and ran it. After rebooting Windows I was able to run the client.
I did not try to install any of the other desktop clients.
This client required the port to be specified to connect to the Jellyfin server, unlike the Android client.
The client only allowed me to attempt 3 login attempts. After that, I had of the to desktop close. the client and restart it.
This client only works full-screen. There is no way to change the window size.
Roku Client
I installed the Jellyfin Roku client on my TCL TV in the usual way. Media playback was very good; however, the Jellyfin Roku client needs work.
Using a remote that came with the TV, when I want to forward a video, the forward button must be pressed twice. The first press activates the forward / backward capability, then the video can be forwarded or rewound by pressing and holding the button a second time. This is annoying.
Restricted Users
Restricted users are useful for preventing guests and children from accessing private media.
Plex does not support restricted users without a monthly subscription.
The F/OSS Jellyfin web client makes it easy to set up a restricted user by navigating to
http:/
.
I found that using the Roku client for Jellyfin with a standard TV remote made signing in awkward because the user ID and password had to be painfully and slowly typed when not logged in. The ability to restrict access to media for authorized users should not come at the expense of usability.