Skip to content

Commit

Permalink
Improve https server sleep and wakeup anxdpanic#810 anxdpanic#951
Browse files Browse the repository at this point in the history
  • Loading branch information
MoojMidge committed Nov 1, 2024
1 parent cb4ee0c commit 718f82c
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 44 deletions.
43 changes: 22 additions & 21 deletions resources/lib/youtube_plugin/kodion/monitors/player_monitor.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@


class PlayerMonitorThread(threading.Thread):
def __init__(self, player, provider, context, monitor, playback_data):
def __init__(self, player, provider, context, monitor, player_data):
super(PlayerMonitorThread, self).__init__()

self._stopped = threading.Event()
Expand All @@ -37,10 +37,10 @@ def __init__(self, player, provider, context, monitor, playback_data):
self._context = context
self._monitor = monitor

self.playback_data = playback_data
self.video_id = playback_data.get('video_id')
self.channel_id = playback_data.get('channel_id')
self.video_status = playback_data.get('video_status')
self.player_data = player_data
self.video_id = player_data.get('video_id')
self.channel_id = player_data.get('channel_id')
self.video_status = player_data.get('video_status')

self.current_time = 0.0
self.total_time = 0.0
Expand All @@ -55,13 +55,13 @@ def abort_now(self):
or self.stopped())

def run(self):
playing_file = self.playback_data.get('playing_file')
play_count = self.playback_data.get('play_count', 0)
use_remote_history = self.playback_data.get('use_remote_history', False)
use_local_history = self.playback_data.get('use_local_history', False)
playback_stats = self.playback_data.get('playback_stats', {})
refresh_only = self.playback_data.get('refresh_only', False)
clip = self.playback_data.get('clip', False)
playing_file = self.player_data.get('playing_file')
play_count = self.player_data.get('play_count', 0)
use_remote_history = self.player_data.get('use_remote_history', False)
use_local_history = self.player_data.get('use_local_history', False)
playback_stats = self.player_data.get('playback_stats', {})
refresh_only = self.player_data.get('refresh_only', False)
clip = self.player_data.get('clip', False)

self._context.log_debug('PlayerMonitorThread[{0}]: Starting'
.format(self.video_id))
Expand Down Expand Up @@ -208,7 +208,7 @@ def run(self):
'played_time': self.current_time,
'played_percent': self.progress,
}
self.playback_data['play_data'] = play_data
self.player_data['play_data'] = play_data

if logged_in and report_url:
client.update_watch_history(
Expand All @@ -221,7 +221,7 @@ def run(self):
self._context.get_playback_history().set_item(self.video_id,
play_data)

self._context.send_notification(PLAYBACK_STOPPED, self.playback_data)
self._context.send_notification(PLAYBACK_STOPPED, self.player_data)
self._context.log_debug('Playback stopped [{video_id}]:'
' {played_time:.3f} secs of {total_time:.3f}'
' @ {played_percent}%,'
Expand Down Expand Up @@ -361,21 +361,22 @@ def onPlayBackStarted(self):
if self._ui.get_property(PLAY_WITH):
self._context.execute('Action(SwitchPlayer)')
self._context.execute('Action(Stop)')
return

def onAVStarted(self):
if self._ui.get_property(PLAY_WITH):
return

playback_data = self._ui.pop_property(PLAYER_DATA)
if not playback_data:
player_data = self._ui.pop_property(PLAYER_DATA)
if not player_data:
return
self.cleanup_threads()

playback_data = json.loads(playback_data)
player_data = json.loads(player_data)
try:
self.seek_time = float(playback_data.get('seek_time'))
self.start_time = float(playback_data.get('start_time'))
self.end_time = float(playback_data.get('end_time'))
self.seek_time = float(player_data.get('seek_time'))
self.start_time = float(player_data.get('start_time'))
self.end_time = float(player_data.get('end_time'))
self.current_time = max(0.0, self.getTime())
self.total_time = max(0.0, self.getTotalTime())
except (ValueError, TypeError, RuntimeError):
Expand All @@ -389,7 +390,7 @@ def onAVStarted(self):
self._provider,
self._context,
self._monitor,
playback_data))
player_data))

def onPlayBackEnded(self):
if not self._ui.busy_dialog_active():
Expand Down
67 changes: 48 additions & 19 deletions resources/lib/youtube_plugin/kodion/monitors/service_monitor.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,12 @@
import json
import threading

from ..compatibility import xbmc, xbmcgui
from ..compatibility import urlsplit, xbmc, xbmcgui
from ..constants import (
ADDON_ID,
CHECK_SETTINGS,
CONTAINER_FOCUS,
PATHS,
PLUGIN_WAKEUP,
REFRESH_CONTAINER,
RELOAD_ACCESS_MANAGER,
Expand Down Expand Up @@ -46,6 +47,7 @@ def __init__(self, context):
self.httpd_sleep_allowed = True

self.system_idle = False
self.system_sleep = False
self.refresh = False
self.interrupt = False

Expand Down Expand Up @@ -83,6 +85,35 @@ def refresh_container(self, force=False):
self.refresh = True

def onNotification(self, sender, method, data):
if sender == 'xbmc':
if method == 'System.OnSleep':
self.system_idle = True
self.system_sleep = True

elif method in {
'GUI.OnScreensaverActivated',
'GUI.OnDPMSActivated',
}:
self.system_idle = True

elif method in {
'GUI.OnScreensaverDeactivated',
'GUI.OnDPMSDeactivated',
'System.OnWake',
}:
self.onWake()

elif method == 'Player.OnPlay':
player = xbmc.Player()
try:
playing_file = urlsplit(player.getPlayingFile())
if playing_file.path in {PATHS.MPD, PATHS.REDIRECT}:
self.onWake()
except RuntimeError:
pass

return

if sender != ADDON_ID:
return

Expand Down Expand Up @@ -129,20 +160,6 @@ def onNotification(self, sender, method, data):
self._context.reload_access_manager()
self.refresh_container()

def onScreensaverActivated(self):
self.system_idle = True

def onScreensaverDeactivated(self):
self.system_idle = False
self.interrupt = True

def onDPMSActivated(self):
self.system_idle = True

def onDPMSDeactivated(self):
self.system_idle = False
self.interrupt = True

def onSettingsChanged(self, force=False):
context = self._context

Expand Down Expand Up @@ -201,6 +218,16 @@ def onSettingsChanged(self, force=False):
elif httpd_started:
self.shutdown_httpd()

def onWake(self):
self.system_idle = False
self.system_sleep = False
self.interrupt = True

if not self.httpd and self.httpd_required():
self.start_httpd()
if self.httpd_sleep_allowed:
self.httpd_sleep_allowed = None

def httpd_address_sync(self):
self._old_httpd_address = self._httpd_address
self._old_httpd_port = self._httpd_port
Expand Down Expand Up @@ -228,9 +255,11 @@ def start_httpd(self):
.format(ip=address[0],
port=address[1]))

def shutdown_httpd(self, sleep=False):
def shutdown_httpd(self):
if self.httpd:
if sleep and self.httpd_required(while_sleeping=True):
if (not self.system_sleep
and self.system_idle
and self.httpd_required(while_idle=True)):
return
self._context.log_debug('HTTPServer: Shutting down |{ip}:{port}|'
.format(ip=self._old_httpd_address,
Expand All @@ -255,8 +284,8 @@ def restart_httpd(self):
def ping_httpd(self):
return self.httpd and httpd_status(self._context)

def httpd_required(self, settings=None, while_sleeping=False):
if while_sleeping:
def httpd_required(self, settings=None, while_idle=False):
if while_idle:
settings = self._context.get_settings()
return (settings.api_config_page()
or settings.support_alternative_player())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
REFRESH_CONTAINER,
RELOAD_ACCESS_MANAGER,
REROUTE_PATH,
SERVER_WAKEUP,
VIDEO_ID,
)
from ...exceptions import KodionException
Expand Down Expand Up @@ -224,7 +223,6 @@ def run(self, provider, context, focused=None):
playlist_player = context.get_playlist_player()
playlist_player.play_item(item=uri, listitem=item)
else:
context.wakeup(SERVER_WAKEUP, timeout=5)
xbmcplugin.setResolvedUrl(handle,
succeeded=result,
listitem=item)
Expand Down
18 changes: 16 additions & 2 deletions resources/lib/youtube_plugin/kodion/service_runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,13 @@ def run():

while not monitor.abortRequested():
is_idle = monitor.system_idle or monitor.get_idle_time() >= loop_period
is_asleep = monitor.system_sleep

if is_idle:
if is_asleep:
plugin_idle_time_ms = 0
if not plugin_is_idle:
plugin_is_idle = set_property(PLUGIN_SLEEPING)
elif is_idle:
if plugin_idle_time_ms >= plugin_idle_timeout_ms:
plugin_idle_time_ms = 0
if not plugin_is_idle:
Expand All @@ -88,11 +93,14 @@ def run():

if not monitor.httpd:
httpd_idle_time_ms = 0
elif is_asleep:
httpd_idle_time_ms = 0
monitor.shutdown_httpd()
elif is_idle:
if monitor.httpd_sleep_allowed:
if httpd_idle_time_ms >= httpd_idle_timeout_ms:
httpd_idle_time_ms = 0
monitor.shutdown_httpd(sleep=True)
monitor.shutdown_httpd()
elif monitor.httpd_sleep_allowed is None:
monitor.httpd_sleep_allowed = True
httpd_idle_time_ms = 0
Expand All @@ -116,6 +124,12 @@ def run():
wait_time_ms = 0

while not monitor.abortRequested():
is_idle = monitor.system_idle or monitor.get_idle_time() >= loop_period
is_asleep = monitor.system_sleep

if not monitor.httpd and not is_idle and not is_asleep:
monitor.onWake()

if monitor.refresh and all(container.values()):
monitor.refresh_container(force=True)
monitor.refresh = False
Expand Down

0 comments on commit 718f82c

Please sign in to comment.