Notifiarr / notifiarr

Client for Notifiarr.com
https://notifiarr.com
MIT License
537 stars 31 forks source link

[Feature Request]: Jellyfin 4K Transcode Killer #400

Open brettpetch opened 1 year ago

brettpetch commented 1 year ago

With the recent potential db changes to Jellyfin, the viability of using it as a Plex replacement is becoming real.

Currently, the webhooks provided by jellyfin are not sufficient for notifying of new playback events with the amount of data required to kill a transcode. To circumvent this, I'd like to propose the following running on a 30s-1m interval--

/Sessions?ActiveWithinSeconds=30&apikey=<REDACTED>

From there, you can iterate through current sessions: this may look like

# https://api.jellyfin.org/#tag/Session/operation/GetSessions
#https://api.jellyfin.org/#tag/HlsSegment/operation/StopEncodingProcess
# Responses are in JSON

x.TranscodingInfo.IsVideoDirect = True/False
x.NowPlayingItem.Height >= <Resolution>
x.Id <SessionID>

  # Get Active Sessions within last 30 seconds
  /Sessions?ActiveWithinSeconds=30&apikey=<apiKey>

  # Sending Message
  POST '{"Text":"No 4K Transcoding!","TimeoutMs":5000}' /Sessions/<Id>/Message?apikey=<apiKey>

  # Stopping Transcode
  POST /Sessions/<Id>/Playing/Stop?apikey=<apiKey>
davidnewhall commented 1 year ago

This application currently has no jellyfin support. I'm the only one who programs this app. (Others welcome!) I've never used jellyfin, so there's a pretty slim chance this feature will make it in.

davidnewhall commented 1 year ago

I've been unable to find a Jellyfin Go library. This is the closest thing I can find, and it doesn't seem to have any session management methods. https://pkg.go.dev/github.com/hrfee/jfa-go/jfapi

zeroquinc commented 1 year ago

@davidnewhall what about this? https://pkg.go.dev/github.com/hrfee/mediabrowser

I got forwarded from the Notifiarr Discord: https://discord.com/channels/764440599066574859/1131865613065789512/1131865613065789512

davidnewhall commented 1 year ago

@zeroquinc Doesn't appear that anything has changed since I left my last comment about it.

brettpetch commented 1 year ago

Python implementation:

#!/usr/bin/env python3
# /usr/local/bin/jellyfin-check.py
import requests
import time

API_BASE_URL = "http://127.0.0.1:8096"  # Replace with your server address
API_KEY = "CHANGEME"

# Retrieve active sessions from the last 30 seconds
def get_active_sessions():
    url = f"{API_BASE_URL}/Sessions?ActiveWithinSeconds=30&apikey={API_KEY}"
    response = requests.get(url)
    if response.status_code == 200:
        return response.json()
    return []

# Send a message to a specific session
def send_message(session_id):
    url = f"{API_BASE_URL}/Sessions/{session_id}/Message?apikey={API_KEY}"
    payload = {
        "Text": "4K Transcoding is not allowed, please try a lower quality version.",
        "TimeoutMs": 5000
    }
    response = requests.post(url, json=payload)
    return response.status_code == 200

# Stop transcoding for a specific session
def stop_transcoding(session_id):
    url = f"{API_BASE_URL}/Sessions/{session_id}/Playing/Stop?apikey={API_KEY}"
    response = requests.post(url)
    return response.status_code == 200

def main():
    while True:  # Infinite loop to keep checking every 30 seconds
        sessions = get_active_sessions()

        for session in sessions:
            # Check conditions
            if (
                not session.get("TranscodingInfo", {}).get("IsVideoDirect", False) and
                session.get("NowPlayingItem", {}).get("Width", 0) >= 3840  # Assuming 4K resolution as 3840 pixels in width
            ):
                session_id = session.get("Id")

                if session_id:
                    send_message(session_id)
                    stop_transcoding(session_id)
                    print(f"Stopped transcoding for session ID: {session_id}")

        time.sleep(30)  # Wait for 30 seconds before checking again

if __name__ == "__main__":
    main()