Spassmuskel
Lt. Commander
- Registriert
- Mai 2013
- Beiträge
- 1.251
Hallo zusammen,
vorab: sollte es für das weiter unten geschilderte Problem mit Kodi und Wayland schon eine Lösung geben, dann nur her damit. Ich konnte leider nichts finden. Das System welches ich verwendet habe ist Kubuntu 24.04 LTS.
Sollte der Artikel auf Interesse stoßen, kann ich das Ganze noch mit Bilder untermauern. Hatte jetzt ehrlich gesagt keine Lust dazu.
Was ist das generelle Problem?
Unter Wayland ist es leider nicht mehr möglich mit Kodi die Option "Bildwiederholfrequenz anpassen" zu nutzen (https://github.com/xbmc/xbmc/issues/20614). Neue Lösungen schlagen VRR vor, was ich aber aufgrund des Alters meines TVs nicht testen kann.
Das heißt, dass jedes Video immer mit derselben Bildfrequenz ausgegeben wird. Spiele ich ein Video mit 25p (typisch für DVD oder auch TV Aufnahmen) und die Bildfrequenz ist im System auf 60 Hz, ruckelt das Video, da 60 kein gerades Vielfaches von 25 ist.
Unter X11 (aber auch in Windows Universum) kann Kodi automatisch je nach Inhalt die Bildwiederholrate des Bildschirms anpassen. Unter Wayland ist das nicht mehr gewünscht und anscheinend nicht implementierbar. Man müsste nun jedes Mal in den Systemeinstellungen die richtige Bildfrequenz passend zum abgespielten Video einstellen.
Welche Stolpersteine gibt es, wenn man die Bildrate manuelle ändert?
Zumindest unter KDE werden in den Einstellungen leider nicht alle möglichen Bildwiederholfrequenzen angezeigt. Es gibt nämlich einen Unterschied zwischen 24 Hz und 23,976 Hz. Die meisten Kinofilme nutzen 23,976 Hz. Nur wenige genau 24 Hz. Leider ist die Differenz beim Abspielen von Videos bemerkbar und ein Video mit einer Bildrate von 23,976 würde bei einer Hz-Ausgabe von 24 ca. alle 40 Sekunden kurz Ruckeln.
KDE rundet einfach alle möglichen Frequenzen, sodass unter kscreen-doctor -o bei meinem TV bspw. zwei Mal 1920x1080@24 als Modi (in dem Fall Modi 5 und 6) steht. Eines der beiden Einträge ist allerdings die Frequenz mit 23,976 Hz. In der GUI gibt es aber nur 24 Hz (unter Windows wird bspw. zwischen 23 und 24 unterschieden), sodass immer genau 24 Hz ausgegeben werden. Das heißt, nicht einmal manuell in der GUI kann ich schnell die Bildfrquenz passend zum Medium ändern.
Mit kscreen-doctor in der Konsole kann ich allerdings 23,976 Hz erzwingen (leider nicht benutzerfreundlich und für mich mittlerweile typisch für Linux...kscreen-doctor output.1.mode.6). Das gleiche übrigens auch bei 1920x1080@60. Hier gibt es auch Unterschiede: einmal genau 60Hz und das andere wäre 59,94 Hz (NTSC). Auch diese Option gibt es nicht in der GUI
Lösungsansatz:
Die Lösung stammt ehrlicherweise nicht von mir, sondern vom Copilot. Aber sie funktioniert für meine Zwecke ganz gut:
Mir wurde ein Python Skript vorgeschlagen, welches mittels der JSON-RPC API prüft, ob ein Video abgespielt wird und dann mittels kscreen-doctor die Bildrate von Kubuntu auf die des Videos ändert. Hierzu erhält man von Kodi den Pfad der abgespielten Datei und mittels ffmpeg werden die Eigenschaften ausgelesen und dann von kscreen-doctor die Bildrate umgestellt. Wenn das Video beendet wird, wird die Bildrate wieder auf einen Standard (bei mit 1920x1080@60) umgestellt.
Die Überprüfung erfolgt alle 2 Sekunden.
Das ganze ist dann noch in einem Skript eingebettet, welches erst Kodi startet und dann das Python Skript, sodass beides mit Doppelklick aufrufbar ist.
Voraussetzungen für die Lösung:
Einschränkungen:
Hier erstmal das Python Skript:
Und hier das Startskript mit KODi Start und automatischem abrufen vom Python Code
Anpassen:
Angepasst werden muss in den ersten Zeilen der Benutzername und das Kennwort, welches ihr in Kodi für die http Steuerung vergeben habt:
Ihr müsst die richtigen Modi und den Output für euren Bildschirm eintragen, damit kscreen-doctor die richtige Bildwiederholfrequenz einträgt.
Alle Modi erhaltet ihr mit dem Befehl:
.
Aufpassen: wie schon im Einleitungstext geschrieben, rundet KDE einfach alle Frequenzen. Um auch die Ungeraden richtig einzutragen, müsst ihr es ausprobieren. Auslesbar per:
Die Modi (output.1.mode.6 , wäre in dem Fall Modi 6) müsst ihr dann hier in der Funktion für euch einstellen.
Standardfrequenz einstellen:
Zu diesem Bildmodi kehrt das Sysdtem zurück, wenn kein Video abgespielt wird:
In start_kodi_and_script.sh muss noch der Dateipfad für euer Python Skript angepasst werden:
und nochmal die Standardfrequenz, wenn Kodi geschlossen wird:
Evtl. hilft das dem ein oder anderen oder es gibt Verbesserungsvorschläge, wie man es einfacher gestalten kann.
Hoffe es war verständlich
Habe den Artikel recht schnell geschrieben, deswegen ignoriert bitte erstmal alle Rechtschreib- und Grammatikfehler.
vorab: sollte es für das weiter unten geschilderte Problem mit Kodi und Wayland schon eine Lösung geben, dann nur her damit. Ich konnte leider nichts finden. Das System welches ich verwendet habe ist Kubuntu 24.04 LTS.
Sollte der Artikel auf Interesse stoßen, kann ich das Ganze noch mit Bilder untermauern. Hatte jetzt ehrlich gesagt keine Lust dazu.
Was ist das generelle Problem?
Unter Wayland ist es leider nicht mehr möglich mit Kodi die Option "Bildwiederholfrequenz anpassen" zu nutzen (https://github.com/xbmc/xbmc/issues/20614). Neue Lösungen schlagen VRR vor, was ich aber aufgrund des Alters meines TVs nicht testen kann.
Das heißt, dass jedes Video immer mit derselben Bildfrequenz ausgegeben wird. Spiele ich ein Video mit 25p (typisch für DVD oder auch TV Aufnahmen) und die Bildfrequenz ist im System auf 60 Hz, ruckelt das Video, da 60 kein gerades Vielfaches von 25 ist.
Unter X11 (aber auch in Windows Universum) kann Kodi automatisch je nach Inhalt die Bildwiederholrate des Bildschirms anpassen. Unter Wayland ist das nicht mehr gewünscht und anscheinend nicht implementierbar. Man müsste nun jedes Mal in den Systemeinstellungen die richtige Bildfrequenz passend zum abgespielten Video einstellen.
Welche Stolpersteine gibt es, wenn man die Bildrate manuelle ändert?
Zumindest unter KDE werden in den Einstellungen leider nicht alle möglichen Bildwiederholfrequenzen angezeigt. Es gibt nämlich einen Unterschied zwischen 24 Hz und 23,976 Hz. Die meisten Kinofilme nutzen 23,976 Hz. Nur wenige genau 24 Hz. Leider ist die Differenz beim Abspielen von Videos bemerkbar und ein Video mit einer Bildrate von 23,976 würde bei einer Hz-Ausgabe von 24 ca. alle 40 Sekunden kurz Ruckeln.
KDE rundet einfach alle möglichen Frequenzen, sodass unter kscreen-doctor -o bei meinem TV bspw. zwei Mal 1920x1080@24 als Modi (in dem Fall Modi 5 und 6) steht. Eines der beiden Einträge ist allerdings die Frequenz mit 23,976 Hz. In der GUI gibt es aber nur 24 Hz (unter Windows wird bspw. zwischen 23 und 24 unterschieden), sodass immer genau 24 Hz ausgegeben werden. Das heißt, nicht einmal manuell in der GUI kann ich schnell die Bildfrquenz passend zum Medium ändern.
Mit kscreen-doctor in der Konsole kann ich allerdings 23,976 Hz erzwingen (leider nicht benutzerfreundlich und für mich mittlerweile typisch für Linux...kscreen-doctor output.1.mode.6). Das gleiche übrigens auch bei 1920x1080@60. Hier gibt es auch Unterschiede: einmal genau 60Hz und das andere wäre 59,94 Hz (NTSC). Auch diese Option gibt es nicht in der GUI
Lösungsansatz:
Die Lösung stammt ehrlicherweise nicht von mir, sondern vom Copilot. Aber sie funktioniert für meine Zwecke ganz gut:
Mir wurde ein Python Skript vorgeschlagen, welches mittels der JSON-RPC API prüft, ob ein Video abgespielt wird und dann mittels kscreen-doctor die Bildrate von Kubuntu auf die des Videos ändert. Hierzu erhält man von Kodi den Pfad der abgespielten Datei und mittels ffmpeg werden die Eigenschaften ausgelesen und dann von kscreen-doctor die Bildrate umgestellt. Wenn das Video beendet wird, wird die Bildrate wieder auf einen Standard (bei mit 1920x1080@60) umgestellt.
Die Überprüfung erfolgt alle 2 Sekunden.
Das ganze ist dann noch in einem Skript eingebettet, welches erst Kodi startet und dann das Python Skript, sodass beides mit Doppelklick aufrufbar ist.
Voraussetzungen für die Lösung:
- Kodi als Flatpak installiert
- es muss in Kodi die Steuerung per http aktiviert sein https://kodi.wiki/view/Web_interface (aus Gründen der Sicherheit mit Passwort)
- ffmpeg muss installiert sein
- die Medien müssen lokal vorhanden sein (ext./int. Festplatte, wahrscheinlich geht es auch innerhalb des Netzwerkes--> konnte ich nicht testen)
- es muss KDE sein, da wir hier mit kscreen-doctor arbeiten, geht bestimmt auch mit anderen Tools unter anderen Oberflächen
- Python solle ausführbar sein
Einschränkungen:
- funktioniert bisher nur mit lokalen Medien. Ich habe es nicht geschafft mittels der API gleich die Videodaten zu bekommen. Evtl. schafft es ein anderer

- bei ein paar älteren Videos mit Container .TS hat ffmpeg anscheinend Probleme die Infos zu extrahieren. Bei allen anderen hat es aber funktioniert. Möchte deshalb nicht ausschließen, dass andere Formate evtl. auch Probleme machen
Hier erstmal das Python Skript:
Python:
import subprocess
import time
import os
import requests
from requests.auth import HTTPBasicAuth
CHECK_INTERVAL = 2
LAST_VIDEO_LABEL = None
# 🔑 Kodi Login-Daten
KODI_USER = "BENUTZERNAME"
KODI_PASS = "PASSWORT"
KODI_URL = "http://localhost:8080/jsonrpc"
def get_active_player():
try:
output = subprocess.check_output(["playerctl", "-l"]).decode().strip().split('\n')
for player in output:
status = subprocess.check_output(["playerctl", "-p", player, "status"]).decode().strip()
if status == "Playing":
return ("playerctl", player)
except Exception:
pass
try:
payload = {
"jsonrpc": "2.0",
"method": "Player.GetActivePlayers",
"id": 1
}
r = requests.post(KODI_URL, json=payload, auth=HTTPBasicAuth(KODI_USER, KODI_PASS)).json()
if r.get("result"):
return ("kodi", r["result"][0]["playerid"])
except Exception:
pass
return (None, None)
def get_video_label(source, player_id):
if source == "playerctl":
try:
return subprocess.check_output(["playerctl", "-p", player_id, "metadata", "xesam:title"]).decode().strip()
except Exception:
return None
elif source == "kodi":
try:
# Schritt 1: Player.GetItem → movieid holen
payload = {
"jsonrpc": "2.0",
"method": "Player.GetItem",
"params": {"playerid": player_id},
"id": 2
}
r = requests.post(KODI_URL, json=payload, auth=HTTPBasicAuth(KODI_USER, KODI_PASS)).json()
item = r.get("result", {}).get("item", {})
movie_id = item.get("id")
# Schritt 2: VideoLibrary.GetMovieDetails → file holen
if movie_id and item.get("type") == "movie":
payload = {
"jsonrpc": "2.0",
"method": "VideoLibrary.GetMovieDetails",
"params": {"movieid": movie_id, "properties": ["file"]},
"id": 3
}
r = requests.post(KODI_URL, json=payload, auth=HTTPBasicAuth(KODI_USER, KODI_PASS)).json()
return r.get("result", {}).get("moviedetails", {}).get("file")
except Exception:
return None
return None
def get_framerate_from_file(file_path):
try:
output = subprocess.check_output([
"ffprobe", "-v", "0", "-select_streams", "v:0",
"-show_entries", "stream=r_frame_rate",
"-of", "default=noprint_wrappers=1:nokey=1", file_path
]).decode().strip()
num, denom = map(int, output.split('/'))
return round(num / denom, 3)
except Exception:
return None
def set_refresh_rate(fps):
if 23.95 <= fps <= 23.98:
print("🔄 Wechsel zu 23.976 Hz (mode 6)")
subprocess.run(["kscreen-doctor", "output.1.mode.6"])
elif 23.99 <= fps <= 24.01:
print("🔄 Wechsel zu 24.000 Hz (mode 5)")
subprocess.run(["kscreen-doctor", "output.1.mode.5"])
elif fps == 25:
subprocess.run(["kscreen-doctor", "output.1.mode.3"])
elif fps == 30:
subprocess.run(["kscreen-doctor", "output.1.mode.0"])
elif fps == 50:
subprocess.run(["kscreen-doctor", "output.1.mode.3"])
elif 59.0 <= fps <= 59.9999:
subprocess.run(["kscreen-doctor", "output.1.mode.2"])
elif fps == 60:
subprocess.run(["kscreen-doctor", "output.1.mode.0"])
else:
print(f"⚠️ Keine passende Bildrate für {fps} fps gefunden.")
def main():
global LAST_VIDEO_LABEL
video_mode_set = False
while True:
source, player_id = get_active_player()
if source is None:
if video_mode_set:
print("\n🛑 Kein Video — zurück zu 60 Hz")
subprocess.run(["kscreen-doctor", "output.1.mode.0"])
video_mode_set = False
LAST_VIDEO_LABEL = None
else:
print("⏳ Kein aktiver Player.")
time.sleep(CHECK_INTERVAL)
continue
file_path = get_video_label(source, player_id)
if file_path and file_path != LAST_VIDEO_LABEL:
LAST_VIDEO_LABEL = file_path
print(f"\n📺 Neues Video: {file_path}")
if os.path.isfile(file_path):
fps = get_framerate_from_file(file_path)
if fps:
set_refresh_rate(fps)
video_mode_set = True
else:
print("🚫 Framerate nicht ermittelbar.")
else:
print("❌ Datei existiert nicht oder kein Zugriff.")
time.sleep(CHECK_INTERVAL)
if __name__ == "__main__":
main()
Und hier das Startskript mit KODi Start und automatischem abrufen vom Python Code
Code:
#!/bin/bash
echo "🚀 Starte Kodi (Flatpak)..."
flatpak run tv.kodi.Kodi &
KODI_PID=$!
echo "🧠 Starte Python-Skript..."
python3 ~/Dokumente/kodi_framerate_switcher_debug.py &
SCRIPT_PID=$!
# ⏳ Warte, bis Kodi beendet wird
echo "⏳ Warte auf das Ende von Kodi..."
wait $KODI_PID
echo "🛑 Kodi wurde beendet — beende Python-Skript..."
kill $SCRIPT_PID
# 🔄 Optional: Zurück zu 60 Hz
kscreen-doctor output.1.mode.0
Anpassen:
Angepasst werden muss in den ersten Zeilen der Benutzername und das Kennwort, welches ihr in Kodi für die http Steuerung vergeben habt:
Code:
# 🔑 Kodi Login-Daten
KODI_USER = "BENUTZERNAME"
KODI_PASS = "PASSWORT"
Ihr müsst die richtigen Modi und den Output für euren Bildschirm eintragen, damit kscreen-doctor die richtige Bildwiederholfrequenz einträgt.
Alle Modi erhaltet ihr mit dem Befehl:
Code:
kscreen-doctor -o
Aufpassen: wie schon im Einleitungstext geschrieben, rundet KDE einfach alle Frequenzen. Um auch die Ungeraden richtig einzutragen, müsst ihr es ausprobieren. Auslesbar per:
Code:
wayland-info | grep -i refresh
Die Modi (output.1.mode.6 , wäre in dem Fall Modi 6) müsst ihr dann hier in der Funktion für euch einstellen.
Code:
def set_refresh_rate(fps):
if 23.95 <= fps <= 23.98:
print("🔄 Wechsel zu 23.976 Hz (mode 6)")
subprocess.run(["kscreen-doctor", "output.1.mode.6"])
elif 23.99 <= fps <= 24.01:
print("🔄 Wechsel zu 24.000 Hz (mode 5)")
subprocess.run(["kscreen-doctor", "output.1.mode.5"])
elif fps == 25:
subprocess.run(["kscreen-doctor", "output.1.mode.3"])
elif fps == 30:
subprocess.run(["kscreen-doctor", "output.1.mode.0"])
elif fps == 50:
subprocess.run(["kscreen-doctor", "output.1.mode.3"])
elif 59.0 <= fps <= 59.9999:
subprocess.run(["kscreen-doctor", "output.1.mode.2"])
elif fps == 60:
subprocess.run(["kscreen-doctor", "output.1.mode.0"])
else:
print(f"⚠️ Keine passende Bildrate für {fps} fps gefunden.")
Standardfrequenz einstellen:
Zu diesem Bildmodi kehrt das Sysdtem zurück, wenn kein Video abgespielt wird:
Code:
def main():
global LAST_VIDEO_LABEL
video_mode_set = False
while True:
source, player_id = get_active_player()
if source is None:
if video_mode_set:
print("\n🛑 Kein Video — zurück zu 60 Hz")
subprocess.run(["kscreen-doctor", "output.1.mode.0"])
video_mode_set = False
LAST_VIDEO_LABEL = None
else:
print("⏳ Kein aktiver Player.")
time.sleep(CHECK_INTERVAL)
continue
In start_kodi_and_script.sh muss noch der Dateipfad für euer Python Skript angepasst werden:
Code:
python3 ~/Dokumente/kodi_framerate_switcher_debug.py &
und nochmal die Standardfrequenz, wenn Kodi geschlossen wird:
Code:
# 🔄 Optional: Zurück zu 60 Hz
kscreen-doctor output.1.mode.0
Evtl. hilft das dem ein oder anderen oder es gibt Verbesserungsvorschläge, wie man es einfacher gestalten kann.
Hoffe es war verständlich
Habe den Artikel recht schnell geschrieben, deswegen ignoriert bitte erstmal alle Rechtschreib- und Grammatikfehler.
Zuletzt bearbeitet: