Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add automatic certificate generation for OneUI8 #65

Open
wants to merge 12 commits into
base: main
Choose a base branch
from
Open
80 changes: 40 additions & 40 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
@@ -1,40 +1,40 @@
name: ci

permissions:
packages: write

on:
push:
branches:
- 'main'

jobs:
docker:
runs-on: ubuntu-latest
steps:
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Generate tags and labels
uses: docker/metadata-action@v5
id: meta
with:
images: ghcr.io/Georift/install-jellyfin-tizen
tags: |
type=sha
type=raw,value=latest,enable={{is_default_branch}}

- name: Set up Docker Buildx
uses: docker/[email protected]

- name: Build and push Docker image
uses: docker/[email protected]
with:
file: ./Dockerfile
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
name: ci
permissions:
packages: write
on:
push:
branches:
- 'main'
jobs:
docker:
runs-on: ubuntu-latest
steps:
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Generate tags and labels
uses: docker/metadata-action@v5
id: meta
with:
images: ghcr.io/Georift/install-jellyfin-tizen
tags: |
type=sha
type=raw,value=latest,enable={{is_default_branch}}
- name: Set up Docker Buildx
uses: docker/[email protected]
- name: Build and push Docker image
uses: docker/[email protected]
with:
file: ./Dockerfile
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "tizencertificates"]
path = tizencertificates
url = https://github.com/sreyemnayr/tizencertificates.git
43 changes: 34 additions & 9 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,10 +1,35 @@
FROM vitalets/tizen-webos-sdk

COPY entrypoint.sh profile.xml ./

# jq for quickly parsing the TV name from the API endpoint
RUN apt update && apt install jq -y && rm -rf /var/lib/apt/lists/* && rm -rf /var/cache/apt/*
RUN chown developer:developer entrypoint.sh
RUN chmod +x entrypoint.sh

FROM vitalets/tizen-webos-sdk

EXPOSE 4794

ENV TZ=Europe/Berlin
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

COPY entrypoint.sh profile.xml install_python.sh tizencertificates/requirements.txt tizencertificates/cert_server.py tizencertificates/certtool.py ./

RUN mkdir /home/developer/templates
COPY tizencertificates/templates/completion.html /home/developer/templates/completion.html

# Install additional dependencies (jq is still needed)
RUN apt update && apt install jq -y && rm -rf /var/lib/apt/lists/* && rm -rf /var/cache/apt/*

RUN chown developer:developer install_python.sh
RUN chmod +x install_python.sh

RUN ./install_python.sh

RUN pip install --no-cache-dir -r requirements.txt

RUN chown developer:developer entrypoint.sh
RUN chmod +x entrypoint.sh

# Sets the certificate and distrobutor password with an env variable
ENV CERT_PASSWORD=8VzdJWON1KaW3IRKrie7rDkovaqVciyG3xYiNWhzJE

# Inserts the CERT_PASSWORD vsriable into the pass: segment of the cert_server.py
RUN sed -i "s/pass:/pass:$CERT_PASSWORD/" cert_server.py

# removes every encountering of the -legacy flag as openssl in this container does not support it anymore
RUN sed -i "s/-legacy//g" cert_server.py

ENTRYPOINT [ "/home/developer/entrypoint.sh" ]
170 changes: 103 additions & 67 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,116 +1,152 @@
# Install Jellyfin for Samsung TV

This project makes it easy to install [Jellyfin for Samsung TV](https://github.com/jellyfin/jellyfin-tizen) by automating the environment configuration with Docker.
This project simplifies the installation of [Jellyfin for Samsung TV](https://github.com/jellyfin/jellyfin-tizen) by automating the environment setup using Docker.

Samsung TVs have been running Tizen OS since 2015, and while the Jellyfin app is stable & officially supported, [the app has yet to make it onto the Samsung app store since efforts began in late 2021](https://github.com/jellyfin/jellyfin-tizen/issues/94).
Samsung TVs have been using Tizen OS since 2015. While the Jellyfin app is stable and officially supported, [it has not been available in the Samsung App Store since 2021](https://github.com/jellyfin/jellyfin-tizen/issues/94).

Install Jellyfin to your TV with just one command once your computer and TV are configured as described below.
With this script, you can install Jellyfin with just one command once your computer and TV are properly configured.

## Configure Computer (PC, Laptop, etc...)
- Follow [Docker Installation Instructions](https://www.docker.com/get-started/)
- Enable any necessary [Virtualization](https://support.microsoft.com/en-us/windows/enable-virtualization-on-windows-11-pcs-c5578302-6e43-4b4b-a449-8ced115f58e1) features.
- Ensure you are on the same network as the TV you are trying to install the app to.
---

## Configure Samsung TV
## Prerequisites

#### Place TV in Developer Mode
### 1. Prepare Your Computer
- [Install Docker](https://www.docker.com/get-started)
- If necessary, [enable virtualization](https://support.microsoft.com/en-us/windows/enable-virtualization-on-windows-11-pcs-c5578302-6e43-4b4b-a449-8ced115f58e1)
- Ensure that your computer is on the same network as your Samsung TV

> [!NOTE]
> If the TV is set to use a Right-to-left language (Arabic, Hebrew, etc). You need to enter the IP address on the TV backwards. [Read more.](https://github.com/Georift/install-jellyfin-tizen/issues/30)
- On the TV, open the "Smart Hub".
- Select the "Apps" panel.
- Press the "123" button (or if your remote doesn't have this button, long press the Home button) before typing "12345" with the on-screen keyboard.
- Toggle the `Developer` button to `On`.
- Enter the `Host PC IP` address of the device you're running this container on.
> Troubleshooting Tip: If the on-screen keyboard will not pop up or if it does pop up but nothing is being entered while typing then please use either an external Bluetooth keyboard or follow these instructions to utilize the virtual keyboard from the Samsung SmartThings app (available on iOS or Android). Download the SmartThings app from your app store. Sign into your Samsung account on your TV and SmartThings app. Open the SmartThings app. Grant the requested permissions. On the bottom toolbar select `Devices`, select the `+` icon, select `Samsung Devices Add`, select `TV` then wait and select your TV (it may hang during pairing but still work if you navigate back to `Devices`). Select your TV widget (the widget may briefly display 'downloading') and the virtual remote should appear shortly. Swipe up to maximize the virtual remote—you should see a bottom section appear. Swipe on the bottom section of the virtual device until you find the numeric keypad. Enter the Host PC IP address with the virtual numeric keyboard. Enter the IP address and then select `Okay`. Now run the docker command described below. (This issue has been documented on the UN43TU7000G/UN55AU8000B and likely exists on other models as well.)
### 2. Configure Your Samsung TV

#### Uninstall Existing Jellyfin Installations, If Required
#### a) Enable Developer Mode

Follow the [Samsung uninstall instructions](https://www.samsung.com/in/support/tv-audio-video/how-to-uninstall-an-app-on-samsung-smart-tv/)
> **Note:** If your TV uses a right-to-left language (e.g., Arabic or Hebrew), the IP address must be entered in reverse order. [More info here.](https://github.com/Georift/install-jellyfin-tizen/issues/30)

#### Find IP Address
1. On your TV, go to "Apps".
2. Scroll down to "App Settings" and open it.
3. Enter "12345" using the virtual keyboard.
4. Enable Developer Mode (**On**).
5. Enter your computer's IP address.

- Exact instructions will vary with the model of TV. In general you can find the TV's IP address in Settings under Networking or About. Plenty of guides are availble with a quick search, however for brevity a short guide with pictures can be found [here](https://www.techsolutions.support.com/how-to/how-to-check-connection-on-samsung-smart-tv-10925).
If you experience issues entering the IP address:
- Use an external Bluetooth keyboard.
- Use the Samsung SmartThings app to enter the IP via the virtual keyboard.

- Make a note of the IP address as it will be needed later.
#### b) Uninstall Previous Jellyfin Versions
If Jellyfin is already installed, [follow the official uninstallation guide](https://www.samsung.com/in/support/tv-audio-video/how-to-uninstall-an-app-on-samsung-smart-tv/).

#### c) Find Your TV’s IP Address
1. Open the network settings or "About This TV".
2. Note down the IP address as it will be needed later.

---

## Install Jellyfin

#### Installation
- Run the command below, replacing first argument with the IP of your Samsung TV
- If you just want to install the default build, do not put anything after the IP address.
- (Optional) You can provide preferred [jellyfin-tizen-builds](https://github.com/jeppevinkel/jellyfin-tizen-builds) option (Jellyfin / Jellyfin-TrueHD / Jellyfin-master / Jellyfin-master-TrueHD / Jellyfin-secondary) as second argument. By default, Jellyfin option is used.
- (Optional) You can provide preferred [jellyfin-tizen-builds releases](https://github.com/jeppevinkel/jellyfin-tizen-builds/releases) release tag URL as third argument. By default, latest version is used. This is useful if you want to install older Jellyfin Tizen Client version.
- (Optional) You can provide a custom Samsung certificate by mounting the `.p12` files at `/certificates/` and providing the certificate password as fourth argument.
- If you do not want to use either of these options and just install the default build, do not put anything after the IP address.
### Receive the Device-ID
Use the following command to receive the device id from the tv

```bash
docker run --rm ghcr.io/georift/install-jellyfin-tizen --ip <TV_IP> --get-device-id
```

### Installation Command
Use the following command to install Jellyfin. Replace the placeholders accordingly:

```bash
docker run --rm ghcr.io/georift/install-jellyfin-tizen <samsung tv ip> [build option] [tag url] [certificate password]
docker run --rm ghcr.io/georift/install-jellyfin-tizen --ip <TV_IP> [--build <BUILD_OPTION>] [--tag <TAG_URL>] [--oneui8 --device-id <DEVICE_ID> --email <EMAIL>] [--cert-password <PASSWORD>]
```

Examples:
### Arguments
- `--ip <TV_IP>` → IP address of the Samsung TV (**required**)
- `--build <BUILD_OPTION>` → Choose a build option (default: `Jellyfin` available: `Jellyfin, Jellyfin-TrueHD, Jellyfin-master, Jellyfin-master-TrueHD, Jellyfin-secondary`)
- `--tag <TAG_URL>` → URL of the release tag (optional, uses the latest version if not specified)
- `--oneui8` → Enables One UI 8 mode (see section below)
- `--device-id <DEVICE_ID>` → Device ID (required for `--oneui8`)
- `--email <EMAIL>` → Email address (required for `--oneui8`)
- `--cert-password <PASSWORD>` → Certificate password (optional)

### Examples

#### Standard Installation with the Latest Version:
```bash
docker run --rm ghcr.io/georift/install-jellyfin-tizen --ip 192.168.0.10
```

#### Install a Specific Version with TrueHD Support:
```bash
docker run --rm ghcr.io/georift/install-jellyfin-tizen 192.168.0.10 Jellyfin-TrueHD "https://github.com/jeppevinkel/jellyfin-tizen-builds/releases/tag/2024-05-13-0139"
docker run --rm ghcr.io/georift/install-jellyfin-tizen --ip 192.168.0.10 --build Jellyfin-TrueHD --tag "https://github.com/jeppevinkel/jellyfin-tizen-builds/releases/tag/2024-05-13-0139"
```

#### Install with a Custom Certificate:
```bash
docker run --rm -v "$(pwd)/author.p12":/certificates/author.p12 -v "$(pwd)/distributor.p12":/certificates/distributor.p12 ghcr.io/georift/install-jellyfin-tizen 192.168.0.10 Jellyfin "" 'CertPassw0rd!' # Third argument empty to use latest tag
docker run --rm -v "$(pwd)/author.p12":/certificates/author.p12 -v "$(pwd)/distributor.p12":/certificates/distributor.p12 ghcr.io/georift/install-jellyfin-tizen --ip 192.168.0.10 --cert-password 'CertPassw0rd!'
```

### Validating Success
#### Common Errors
### Installation for One UI 8
If your TV uses One UI 8, follow these steps:

- `library initialization failed - unable to allocate file descriptor table - out of memory`
```bash
docker run -p 4794:4794 ghcr.io/georift/install-jellyfin-tizen --ip 192.168.0.10 --oneui8 --device-id GU43CU7179UXZG --email [email protected]
```

0. The starting process of the certificate generation script can take a while, so be patient.
1. Open `localhost:4794/auth/start` in your browser.
2. Follow the instructions on the webpage.
3. Wait for the installation to complete.

Add `--ulimit nofile=1024:65536` to the `docker run` command:
---

```bash
docker run --ulimit nofile=1024:65536 --rm ghcr.io/georift/install-jellyfin-tizen <samsung tv ip> <build option> <tag url>
```
## Verify Installation

- `install failed[118, -11], reason: Author certificate not match :`
### Common Errors & Solutions

Uninstall the Jellyfin application from your Samsung TV, and run the installation again.
- **Error:** `library initialization failed - unable to allocate file descriptor table - out of memory`
- **Solution:** Add `--ulimit nofile=1024:65536`:
```bash
docker run --ulimit nofile=1024:65536 --rm ghcr.io/georift/install-jellyfin-tizen --ip 192.168.0.10
```

#### Success
- **Error:** `install failed[118, -11], reason: Author certificate not match`
- **Solution:** Uninstall the Jellyfin app and try again.

If everything went well, you should see docker output something like the following
- **Error:** `install failed[118, -12], reason: Check certificate error: Invalid certificate chain`
- **Solution:** Use a custom certificate as described [here](https://developer.samsung.com/smarttv/develop/getting-started/setting-up-sdk/creating-certificates.html).

### Successful Installation
If the installation is successful, you will see this message:
```txt
Installed the package: Id(AprZAARz4r.Jellyfin)
Tizen application is successfully installed.
Total time: 00:00:12.205
```

At this point you can find jellyfin on your TV by navigating to Apps -> Downloaded (scroll down), there you'll find Jellyfin.

## Supported Platforms

At the moment, these steps should work on any amd64 based system. Platforms
like the Raspberry Pi, which run ARM chips, are not yet supported, but
[we might have some progress soon.](https://github.com/Georift/install-jellyfin-tizen/issues/10).

### Additional Required Commands: ARM (MacOS M Chips and higher)
- Firstly make sure that you have the Experimental "Virtualization Framework" enabled.
- Verify that docker on your M series has qemu installed. You can do this by running:
```docker run --rm --platform linux/amd64 alpine uname -m```

If it outputs: **x86_64** you're good. If not, reinstall docker, with the needed requirements.
Jellyfin should now be available under `Apps -> Downloaded` on your TV.

Then use the ```--platform linux/amd64"``` argument on the original command. This should look something like this:
```docker run --rm --platform linux/amd64 ghcr.io/georift/install-jellyfin-tizen <samsung tv ip> <build option> <tag url>```
---

- `install failed[118, -12], reason: Check certificate error : :Invalid certificate chain with certificate in signature.`
## Supported Platforms

Recent TV models require the installation packages to be signed with a custom certificate for your specific TV.
Currently, **amd64** is supported. ARM devices (such as Raspberry Pi or Mac M1/M2) require additional configuration.

See [official documentation](https://developer.samsung.com/smarttv/develop/getting-started/setting-up-sdk/creating-certificates.html) on creating your certificate and use the custom certificate arguments.
### Installation on ARM (Mac M-Chips)
1. Enable the "Virtualization Framework".
2. Ensure that Docker supports `qemu`:
```bash
docker run --rm --platform linux/amd64 alpine uname -m
```
If `x86_64` is returned, everything is set up correctly.
3. Use `--platform linux/amd64`:
```bash
docker run --rm --platform linux/amd64 ghcr.io/georift/install-jellyfin-tizen --ip 192.168.0.10
```

## Credits
---

This project is possible thanks to these projects:
## Acknowledgments
This project would not be possible without the following:

- [jellyfin-tizen](https://github.com/jellyfin/jellyfin-tizen)
- [jeppevinkel/jellyfin-tizen-builds](https://github.com/jeppevinkel/jellyfin-tizen-builds) for providing development builds
- [vitalets/docker-tizen-webos-sdk](https://github.com/vitalets/docker-tizen-webos-sdk) for a docker container preinstalled with the Tizen SDK
- [jeppevinkel/jellyfin-tizen-builds](https://github.com/jeppevinkel/jellyfin-tizen-builds)
- [vitalets/docker-tizen-webos-sdk](https://github.com/vitalets/docker-tizen-webos-sdk)
- [tizencertificates](https://github.com/sreyemnayr/tizencertificates)

Loading