Skip to content

Commit

Permalink
Fix Youtube progress tracking #581
Browse files Browse the repository at this point in the history
  • Loading branch information
MoojMidge committed Feb 24, 2024
1 parent 7e7ed24 commit f3ddaac
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 73 deletions.
57 changes: 27 additions & 30 deletions resources/lib/youtube_plugin/kodion/utils/player_monitor.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ def __init__(self, player, provider, context, monitor, playback_json):

self.total_time = 0.0
self.current_time = 0.0
self.segment_start = 0.0
self.progress = 0

self.daemon = True
Expand Down Expand Up @@ -90,9 +89,6 @@ def run(self):
self._context,
self.video_id,
report_url,
st=0,
et='N/A',
state=state
)

access_manager = self._context.get_access_manager()
Expand All @@ -101,6 +97,7 @@ def run(self):
video_id_param = 'video_id=%s' % self.video_id
report_url = use_remote_history and playback_stats.get('watchtime_url')

segment_start = 0
played_time = -1.0
wait_interval = 0.5
report_period = waited = 10
Expand Down Expand Up @@ -153,38 +150,37 @@ def run(self):
state = 'playing'
played_time = self.current_time

# refresh client, tokens may need refreshing
if logged_in and report_url:
self._provider.reset_client()
client = self._provider.get_client(self._context)
logged_in = self._provider.is_logged_in()

if self.segment_start < 0:
self.segment_start = 0.0

if state == 'playing':
segment_end = self.current_time
else:
segment_end = self.segment_start
segment_end = segment_start

if self.segment_start > segment_end:
segment_end = self.segment_start + report_period
if segment_start > segment_end:
segment_end = segment_start + report_period

if segment_end > self.total_time:
segment_end = self.total_time

# only report state='paused' once
if state == 'playing' or last_state == 'playing':
client.update_watch_history(
self._context,
self.video_id,
report_url,
st=format(self.segment_start, '.3f'),
et=format(segment_end, '.3f'),
state=state
)

self.segment_start = segment_end
# refresh client, tokens may need refreshing
self._provider.reset_client()
client = self._provider.get_client(self._context)
logged_in = self._provider.is_logged_in()

if logged_in:
client.update_watch_history(
self._context,
self.video_id,
report_url,
status=(self.current_time,
segment_start,
segment_end,
state),
)

segment_start = segment_end

self._monitor.waitForAbort(wait_interval)
waited += wait_interval
Expand Down Expand Up @@ -212,19 +208,20 @@ def run(self):
if self.progress >= settings.get_play_count_min_percent():
play_count += 1
self.current_time = 0.0
segment_end = format(self.total_time, '.3f')
segment_end = self.total_time
else:
segment_end = format(self.current_time, '.3f')
segment_end = self.current_time
refresh_only = True

if logged_in and report_url:
client.update_watch_history(
self._context,
self.video_id,
report_url,
st=segment_end,
et=segment_end,
state=state
status=(segment_end,
segment_end,
segment_end,
state),
)
if use_local_history:
play_data = {
Expand Down
69 changes: 39 additions & 30 deletions resources/lib/youtube_plugin/youtube/client/youtube.py
Original file line number Diff line number Diff line change
Expand Up @@ -155,42 +155,51 @@ def calculate_next_page_token(page, max_result):

return 'C%s%s%sAA' % (high[high_iteration], low[low_iteration], overflow_token)

def update_watch_history(self,
context,
video_id,
url,
st=None,
et=None,
state=None):
if None not in (st, et, state):
url.format(st=st, et=et, state=state)
def update_watch_history(self, context, video_id, url, status=None):
if status is None:
cmt = st = et = state = None
else:
st = et = state = 'N/A'
cmt, st, et, state = status

context.log_debug('Playback reported [{video_id}]:'
' {st} segment start,'
' {et} segment end,'
' current time={cmt},'
' segment start={st},'
' segment end={et},'
' state={state}'.format(
video_id=video_id, st=st, et=et, state=state
video_id=video_id, cmt=cmt, st=st, et=et, state=state
))

headers = {'Host': 'www.youtube.com',
'Connection': 'keep-alive',
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.36 Safari/537.36',
'Accept': 'image/webp,*/*;q=0.8',
'DNT': '1',
'Referer': 'https://www.youtube.com/tv',
'Accept-Encoding': 'gzip, deflate',
'Accept-Language': 'en-US,en;q=0.8,de;q=0.6'}
params = {'noflv': '1',
'html5': '1',
'video_id': video_id,
'referrer': '',
'eurl': 'https://www.youtube.com/tv#/watch?v=%s' % video_id,
'skl': 'false',
'ns': 'yt',
'el': 'leanback',
'ps': 'leanback'}
headers = {
'Host': 's.youtube.com',
'Connection': 'keep-alive',
'Accept-Encoding': 'gzip, deflate',
'Accept-Charset': 'ISO-8859-1,utf-8;q=0.7,*;q=0.7',
'Accept': '*/*',
'Accept-Language': 'en-US,en;q=0.5',
'DNT': '1',
'Referer': 'https://www.youtube.com/watch?v={0}'.format(video_id),
'User-Agent': ('Mozilla/5.0 (Linux; Android 10; SM-G981B)'
' AppleWebKit/537.36 (KHTML, like Gecko)'
' Chrome/80.0.3987.162 Mobile Safari/537.36'),
}
params = {
'docid': video_id,
'referrer': 'https://accounts.google.com/',
'ns': 'yt',
'el': 'detailpage',
'ver': '2',
'fs': '0',
'volume': '100',
'muted': '0',
}
if cmt is not None:
params['cmt'] = format(cmt, '.3f')
if st is not None:
params['st'] = format(st, '.3f')
if et is not None:
params['et'] = format(et, '.3f')
if state is not None:
params['state'] = state
if self._access_token:
params['access_token'] = self._access_token

Expand Down
20 changes: 7 additions & 13 deletions resources/lib/youtube_plugin/youtube/helper/video_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -1188,24 +1188,18 @@ def _get_video_info(self):

if _settings.use_remote_history():
playback_stats = {
'playback_url': (
'videostatsPlaybackUrl',
'{0}&ver=2&fs=0&volume=100&muted=0&cpn={1}',
),
'watchtime_url': (
'videostatsWatchtimeUrl',
('{0}&ver=2&fs=0&volume=100&muted=0&cpn={1}'
'&st={{st}}&et={{et}}&state={{state}}'),
)
'playback_url': 'videostatsPlaybackUrl',
'watchtime_url': 'videostatsWatchtimeUrl',
}
playback_tracking = response.get('playbackTracking', {})
cpn = self._generate_cpn()

for key, (url, url_template) in playback_stats.items():
url = playback_tracking.get(url, {}).get('baseUrl')
if not url or not url.startswith('http'):
for key, url_key in playback_stats.items():
url = playback_tracking.get(url_key, {}).get('baseUrl')
if url and url.startswith('http'):
playback_stats[key] = '&cpn='.join((url, cpn))
else:
playback_stats[key] = ''
playback_stats[key] = url_template.format(url, cpn)
else:
playback_stats = {
'playback_url': '',
Expand Down

0 comments on commit f3ddaac

Please sign in to comment.