Skip to content

Commit

Permalink
Merge pull request #593 from MoojMidge/master
Browse files Browse the repository at this point in the history
v7.0.3+beta.5
  • Loading branch information
MoojMidge authored Feb 24, 2024
2 parents 55e2f3a + 97db0ee commit 59bf158
Show file tree
Hide file tree
Showing 8 changed files with 121 additions and 107 deletions.
2 changes: 1 addition & 1 deletion addon.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<addon id="plugin.video.youtube" name="YouTube" version="7.0.3+beta.4" provider-name="anxdpanic, bromix">
<addon id="plugin.video.youtube" name="YouTube" version="7.0.3+beta.5" provider-name="anxdpanic, bromix">
<requires>
<import addon="xbmc.python" version="3.0.1"/>
<import addon="script.module.requests" version="2.12.4"/>
Expand Down
7 changes: 7 additions & 0 deletions changelog.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
## v7.0.3+beta.5
### Fixed
- Properly fix infotagger error with Kodi v19
- Disable non-functioning saved playlists menu item #569
- Fix forced logout on upgrade from v7.0.2.2 or below
- Fix Youtube progress tracking #581

## v7.0.3+beta.4
### Fixed
- Fix handling of isPostLiveDrv streams #579
Expand Down
39 changes: 19 additions & 20 deletions resources/lib/youtube_plugin/kodion/compatibility/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,25 @@
from infotagger.listitem import set_info_tag
# Compatibility shims for Kodi v18 and v19
except ImportError:
class ListItemInfoTag(object):
__slots__ = ('__li__',)

def __init__(self, listitem, *_args, **_kwargs):
self.__li__ = listitem

def add_stream_info(self, *args, **kwargs):
return self.__li__.addStreamInfo(*args, **kwargs)

def set_resume_point(self,
infoproperties,
resume_key='ResumeTime',
total_key='TotalTime'):
if resume_key in infoproperties:
infoproperties[resume_key] = str(infoproperties[resume_key])
if total_key in infoproperties:
infoproperties[total_key] = str(infoproperties[total_key])


def set_info_tag(listitem, infolabels, tag_type, *_args, **_kwargs):
listitem.setInfo(tag_type, infolabels)
return ListItemInfoTag(listitem, tag_type)
Expand Down Expand Up @@ -107,26 +126,6 @@ def _file_closer(*args, **kwargs):
xbmcvfs.File = _file_closer
xbmcvfs.translatePath = xbmc.translatePath


class ListItemInfoTag(object):
__slots__ = ('__li__',)

def __init__(self, listitem, *_args, **_kwargs):
self.__li__ = listitem

def add_stream_info(self, *args, **kwargs):
return self.__li__.addStreamInfo(*args, **kwargs)

def set_resume_point(self,
infoproperties,
resume_key='ResumeTime',
total_key='TotalTime'):
if resume_key in infoproperties:
infoproperties[resume_key] = str(infoproperties[resume_key])
if total_key in infoproperties:
infoproperties[total_key] = str(infoproperties[total_key])


string_type = basestring
byte_string_type = (bytes, str)

Expand Down
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
19 changes: 13 additions & 6 deletions resources/lib/youtube_plugin/youtube/client/__config__.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,13 +84,19 @@ def _on_init(self):
user_details = self._access_manager.get_current_user_details()
last_hash = user_details.get('last_key_hash', '')
current_set_hash = self._get_key_set_hash(switch)
self.changed = current_set_hash != last_hash

changed = current_set_hash != last_hash
if changed and switch == 'own':
changed = self._get_key_set_hash('own_old') != last_hash
if not changed:
self._access_manager.set_last_key_hash(current_set_hash)
self.changed = changed

self._context.log_debug('User: |{user}|, '
'Using API key set: |{switch}|'
.format(user=self.get_current_user(),
switch=switch))
if self.changed:
if changed:
self._context.log_debug('API key set changed: Signing out')
self._context.execute('RunPlugin(plugin://plugin.video.youtube/'
'sign/out/?confirmed=true)')
Expand Down Expand Up @@ -121,7 +127,7 @@ def get_api_keys(self, switch):
client_id = key_sets[switch]['id']
client_secret = key_sets[switch]['secret']

elif switch == 'own':
elif switch.startswith('own'):
decode = False
api_key = self._json_api['keys']['personal']['api_key']
client_id = self._json_api['keys']['personal']['client_id']
Expand All @@ -144,9 +150,10 @@ def get_api_keys(self, switch):

def _get_key_set_hash(self, switch):
key_set = self.get_api_keys(switch)
if switch == 'own':
client_id = key_set['id'].replace('.apps.googleusercontent.com',
'')
if switch.startswith('own'):
client_id = key_set['id'].replace('.apps.googleusercontent.com', '')
if switch == 'own_old':
client_id += '.apps.googleusercontent.com'
key_set['id'] = client_id
return self._access_manager.calc_key_hash(**key_set)

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
15 changes: 8 additions & 7 deletions resources/lib/youtube_plugin/youtube/provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -1245,13 +1245,14 @@ def on_root(self, context, re_match):
result.append(playlists_item)

# saved playlists
if logged_in and settings.get_bool('youtube.folder.saved.playlists.show', True):
playlists_item = DirectoryItem(
localize('saved.playlists'),
create_uri(('special', 'saved_playlists')),
image='{media}/playlist.png',
)
result.append(playlists_item)
# TODO: re-enable once functionality is restored
# if logged_in and settings.get_bool('youtube.folder.saved.playlists.show', True):
# playlists_item = DirectoryItem(
# localize('saved.playlists'),
# create_uri(('special', 'saved_playlists')),
# image='{media}/playlist.png',
# )
# result.append(playlists_item)

# subscriptions
if logged_in and settings.get_bool('youtube.folder.subscriptions.show', True):
Expand Down

0 comments on commit 59bf158

Please sign in to comment.