init
This commit is contained in:
commit
57f996f352
3 changed files with 145 additions and 0 deletions
3
README.md
Normal file
3
README.md
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
# PVR Stretch 4:3
|
||||||
|
|
||||||
|
Set stretch 4:3 view mode for PVR channels
|
||||||
16
addon.xml
Normal file
16
addon.xml
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<addon id="service.pvrstretch"
|
||||||
|
name="PVR Stretch 4:3"
|
||||||
|
version="0.1.0"
|
||||||
|
provider-name="wzray">
|
||||||
|
<requires>
|
||||||
|
<import addon="xbmc.python" version="3.0.0"/>
|
||||||
|
</requires>
|
||||||
|
<extension point="xbmc.service" library="service.py" start="startup"/>
|
||||||
|
<extension point="xbmc.addon.metadata">
|
||||||
|
<summary lang="en_US">Set stretch 4:3 view mode for PVR channels</summary>
|
||||||
|
<description lang="en_US">Set stretch 4:3 view mode for PVR channels</description>
|
||||||
|
<platform>all</platform>
|
||||||
|
<license>MIT</license>
|
||||||
|
</extension>
|
||||||
|
</addon>
|
||||||
126
service.py
Normal file
126
service.py
Normal file
|
|
@ -0,0 +1,126 @@
|
||||||
|
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()
|
||||||
Loading…
Add table
Add a link
Reference in a new issue