jellyfin-mpv-shim/jellyfin_mpv_shim/event_handler.py

177 lines
6.0 KiB
Python

import logging
import os
from .conf import settings
from .media import Media
from .player import playerManager
from .timeline import timelineManager
log = logging.getLogger("event_handler")
bindings = {}
NAVIGATION_DICT = {
"Back": "back",
"Select": "ok",
"MoveUp": "up",
"MoveDown": "down",
"MoveRight": "right",
"MoveLeft": "left",
"GoHome": "home",
"GoToSettings": "home",
}
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from jellyfin_apiclient_python import JellyfinClient as JellyfinClient_type
def bind(event_name: str):
def decorator(func):
bindings[event_name] = func
return func
return decorator
class EventHandler(object):
mirror = None
def handle_event(
self,
client: "JellyfinClient_type",
event_name: str,
arguments: dict,
):
if event_name in bindings:
log.debug("Handled Event {0}: {1}".format(event_name, arguments))
bindings[event_name](self, client, event_name, arguments)
else:
log.debug("Unhandled Event {0}: {1}".format(event_name, arguments))
@bind("Play")
def play_media(self, client: "JellyfinClient_type", _event_name, arguments: dict):
play_command = arguments.get("PlayCommand")
if not playerManager.has_video():
play_command = "PlayNow"
if play_command == "PlayNow":
seq = arguments.get("StartIndex")
if seq is None:
seq = 0
media = Media(
client,
arguments.get("ItemIds"),
seq=seq,
user_id=arguments.get("ControllingUserId"),
aid=arguments.get("AudioStreamIndex"),
sid=arguments.get("SubtitleStreamIndex"),
srcid=arguments.get("MediaSourceId"),
)
log.debug("EventHandler::playMedia %s" % media)
offset = arguments.get("StartPositionTicks")
if offset is not None:
offset /= 10000000
video = media.video
if video:
if settings.pre_media_cmd:
os.system(settings.pre_media_cmd)
playerManager.play(video, offset, is_initial_play=True)
timelineManager.send_timeline()
if arguments.get("SyncPlayGroup") is not None:
playerManager.syncplay.join_group(arguments["SyncPlayGroup"])
if settings.play_cmd:
os.system(settings.play_cmd)
elif play_command == "PlayLast":
playerManager.get_video().parent.insert_items(
arguments.get("ItemIds"), append=True
)
playerManager.upd_player_hide()
elif play_command == "PlayNext":
playerManager.get_video().parent.insert_items(
arguments.get("ItemIds"), append=False
)
playerManager.upd_player_hide()
@bind("GeneralCommand")
def general_command(
self, client: "JellyfinClient_type", _event_name, arguments: dict
):
command = arguments.get("Name")
if command == "SetVolume":
# There is currently a bug that causes this to be spammed, so we
# only update it if the value actually changed.
if playerManager.get_volume(True) != int(arguments["Arguments"]["Volume"]):
playerManager.set_volume(int(arguments["Arguments"]["Volume"]))
elif command == "SetAudioStreamIndex":
playerManager.set_streams(int(arguments["Arguments"]["Index"]), None)
elif command == "SetSubtitleStreamIndex":
playerManager.set_streams(None, int(arguments["Arguments"]["Index"]))
elif command == "DisplayContent":
# If you have an idle command set, this will delay it.
timelineManager.delay_idle()
if self.mirror:
self.mirror.display_content(client, arguments)
elif command in (
"Back",
"Select",
"MoveUp",
"MoveDown",
"MoveRight",
"MoveLeft",
"GoHome",
"GoToSettings",
):
playerManager.menu_action(NAVIGATION_DICT[command])
elif command in ("Mute", "Unmute"):
playerManager.set_mute(command == "Mute")
elif command == "TakeScreenshot":
playerManager.screenshot()
elif command == "ToggleFullscreen" or command is None:
# Currently when you hit the fullscreen button, no command is specified...
playerManager.toggle_fullscreen()
@bind("Playstate")
def play_state(self, _client: "JellyfinClient_type", _event_name, arguments: dict):
command = arguments.get("Command")
if command == "PlayPause":
playerManager.toggle_pause()
elif command == "Pause":
playerManager.pause_if_playing()
elif command == "Unpause":
playerManager.play_if_paused()
elif command == "PreviousTrack":
playerManager.play_prev()
elif command == "NextTrack":
playerManager.play_next()
elif command == "Stop":
playerManager.stop()
elif command == "Seek":
playerManager.seek(
arguments.get("SeekPositionTicks") / 10000000, absolute=True
)
@bind("PlayPause")
def pause_play(self, _client: "JellyfinClient_type", _event_name, _arguments: dict):
playerManager.toggle_pause()
timelineManager.send_timeline()
@bind("SyncPlayGroupUpdate")
def sync_play_group_update(
self, client: "JellyfinClient_type", _event_name, arguments: dict
):
playerManager.syncplay.client = client
playerManager.syncplay.process_group_update(arguments)
@bind("SyncPlayCommand")
def sync_play_command(
self, client: "JellyfinClient_type", _event_name, arguments: dict
):
playerManager.syncplay.client = client
playerManager.syncplay.process_command(arguments)
eventHandler = EventHandler()