126 lines
2.8 KiB
Python
126 lines
2.8 KiB
Python
import json
|
|
import threading
|
|
|
|
import xbmc
|
|
import xbmcaddon
|
|
|
|
|
|
ADDON = xbmcaddon.Addon()
|
|
ADDON_ID = ADDON.getAddonInfo("id")
|
|
VIEW_MODE = "stretch4x3"
|
|
|
|
|
|
def log(message, level=xbmc.LOGINFO):
|
|
xbmc.log(f"[{ADDON_ID}] {message}", level)
|
|
|
|
|
|
def jsonrpc(method, params=None):
|
|
payload = {
|
|
"jsonrpc": "2.0",
|
|
"id": 1,
|
|
"method": method,
|
|
}
|
|
if params is not None:
|
|
payload["params"] = params
|
|
|
|
request = json.dumps(payload)
|
|
|
|
response = xbmc.executeJSONRPC(request)
|
|
try:
|
|
data = json.loads(response)
|
|
except ValueError:
|
|
log(f"Invalid JSON-RPC response from {method}: {response}", xbmc.LOGERROR)
|
|
return None
|
|
|
|
if "error" in data:
|
|
log(f"JSON-RPC {method} failed: {data['error']}", xbmc.LOGWARNING)
|
|
return None
|
|
|
|
return data.get("result")
|
|
|
|
|
|
def get_active_video_player_id():
|
|
result = jsonrpc("Player.GetActivePlayers")
|
|
if not isinstance(result, list):
|
|
return None
|
|
|
|
for player in result:
|
|
if player.get("type") == "video":
|
|
return player.get("playerid")
|
|
|
|
return None
|
|
|
|
|
|
def get_current_item(player_id):
|
|
result = jsonrpc(
|
|
"Player.GetItem",
|
|
{
|
|
"playerid": player_id,
|
|
"properties": ["file"],
|
|
},
|
|
)
|
|
if not isinstance(result, dict):
|
|
return None
|
|
|
|
item = result.get("item")
|
|
if not isinstance(item, dict):
|
|
return None
|
|
|
|
return item
|
|
|
|
|
|
class PvrStretchPlayer(xbmc.Player):
|
|
def __init__(self, monitor):
|
|
super().__init__()
|
|
self.monitor = monitor
|
|
|
|
def onPlayBackStarted(self):
|
|
threading.Thread(target=self._apply, daemon=True).start()
|
|
|
|
def _apply(self):
|
|
item = None
|
|
|
|
for _ in range(100):
|
|
if self.monitor.abortRequested():
|
|
return
|
|
|
|
player_id = get_active_video_player_id()
|
|
if player_id is not None:
|
|
item = get_current_item(player_id)
|
|
if item:
|
|
break
|
|
|
|
if self.monitor.waitForAbort(0.1):
|
|
return
|
|
|
|
if not item:
|
|
log("No player item found after playback start", xbmc.LOGWARNING)
|
|
return
|
|
|
|
item_type = (item or {}).get("type")
|
|
if item_type != "channel":
|
|
return
|
|
|
|
log(f"Applying {VIEW_MODE}: type={item_type}")
|
|
result = jsonrpc("Player.SetViewMode", {"viewmode": VIEW_MODE})
|
|
if result is None:
|
|
log(f"Failed to apply {VIEW_MODE}", xbmc.LOGWARNING)
|
|
return
|
|
|
|
log(f"Applied {VIEW_MODE}: result={result}")
|
|
|
|
|
|
def run():
|
|
monitor = xbmc.Monitor()
|
|
player = PvrStretchPlayer(monitor)
|
|
log("Service started")
|
|
|
|
while not monitor.abortRequested():
|
|
monitor.waitForAbort(1)
|
|
|
|
del player
|
|
log("Service stopped")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
run()
|