Improved synced and optimized version info

This commit is contained in:
JonnyWong16 2017-12-23 11:52:28 -08:00
parent 0a42cb4135
commit 33acf9402d
9 changed files with 156 additions and 42 deletions

View file

@ -162,7 +162,15 @@ DOCUMENTATION :: END
<li class="dashboard-activity-info-item"> <li class="dashboard-activity-info-item">
<div class="sub-heading">Optimized</div> <div class="sub-heading">Optimized</div>
<div class="sub-value" id="optimized_version-${sk}"> <div class="sub-value" id="optimized_version-${sk}">
${data['optimized_version_profile']} ${data['optimized_version_profile']} (${data['optimized_version_title']})
</div>
</li>
% endif
% if data['synced_version'] == 1:
<li class="dashboard-activity-info-item">
<div class="sub-heading">Synced</div>
<div class="sub-value" id="synced_version-${sk}">
${data['synced_version_profile']}
</div> </div>
</li> </li>
% endif % endif
@ -185,7 +193,7 @@ DOCUMENTATION :: END
% elif data['transcode_decision'] == 'copy': % elif data['transcode_decision'] == 'copy':
Direct Stream Direct Stream
% else: % else:
Direct Play ${'(Synced)' if data['synced_version'] == 1 else ''} Direct Play
% endif % endif
</div> </div>
</li> </li>
@ -250,7 +258,7 @@ DOCUMENTATION :: END
% elif data['stream_subtitle_decision'] == 'burn': % elif data['stream_subtitle_decision'] == 'burn':
Burn (${data['subtitle_codec'].upper()}) Burn (${data['subtitle_codec'].upper()})
% else: % else:
Direct Play (${data['subtitle_codec'].upper()}) Direct Play (${data['stream_subtitle_codec'].upper() if data['synced_version'] else data['subtitle_codec'].upper()})
% endif % endif
% else: % else:
None None

View file

@ -257,7 +257,7 @@
if (!(current_activity)) { if (!(current_activity)) {
% if _session['user_group'] == 'admin': % if _session['user_group'] == 'admin':
var msg_settings = ' Verify your server in the <a href="settings#tab_tabs-plex_media_server">settings</a>.'; var msg_settings = ' Verify your server connection in the <a href="settings#tab_tabs-plex_media_server">settings</a>.';
% else: % else:
var msg_settings = '' var msg_settings = ''
% endif % endif
@ -357,7 +357,7 @@
} else if (s.transcode_decision === 'copy') { } else if (s.transcode_decision === 'copy') {
transcode_decision = 'Direct Stream'; transcode_decision = 'Direct Stream';
} else { } else {
transcode_decision = 'Direct Play' + ((s.synced_version == 1) ? ' (Synced)' : ''); transcode_decision = 'Direct Play';
} }
$('#transcode_decision-' + key).html(transcode_decision); $('#transcode_decision-' + key).html(transcode_decision);
@ -434,7 +434,7 @@
} else if (s.stream_subtitle_decision === 'burn') { } else if (s.stream_subtitle_decision === 'burn') {
subtitle_decision = 'Burn (' + s.subtitle_codec.toUpperCase() + ')'; subtitle_decision = 'Burn (' + s.subtitle_codec.toUpperCase() + ')';
} else { } else {
subtitle_decision = 'Direct Play (' + s.subtitle_codec.toUpperCase() + ')'; subtitle_decision = 'Direct Play (' + ((s.synced_version == '1') ? s.stream_subtitle_codec.toUpperCase() : s.subtitle_codec.toUpperCase()) + ')';
} }
} }
$('#subtitle_decision-' + key).html(subtitle_decision); $('#subtitle_decision-' + key).html(subtitle_decision);
@ -453,7 +453,8 @@
} else { } else {
$('#stream_quality-' + key).html(s.quality_profile); $('#stream_quality-' + key).html(s.quality_profile);
} }
$('#optimized_version-' + key).html(s.optimized_version_profile); $('#optimized_version-' + key).html(s.optimized_version_profile + ' (' + s.optimized_version_title + ')');
$('#synced_quality_profile-' + key).html(s.synced_quality_profile);
if (s.media_type != 'photo' && parseInt(s.bandwidth)) { if (s.media_type != 'photo' && parseInt(s.bandwidth)) {
var bw = parseInt(s.bandwidth); var bw = parseInt(s.bandwidth);

View file

@ -98,14 +98,14 @@ DOCUMENTATION :: END
<tr> <tr>
<td>Optimized Version</td> <td>Optimized Version</td>
<td>-</td> <td>-</td>
<td>${data['optimized_version_profile']}</td> <td>${data['optimized_version_profile']}<br>(${data['optimized_version_title']})</td>
</tr> </tr>
% endif % endif
% if data['synced_version'] == 1: % if data['synced_version'] == 1:
<tr> <tr>
<td>Synced Version</td> <td>Synced Version</td>
<td>-</td> <td>-</td>
<td>yes</td> <td>${data['synced_version_profile']}</td>
</tr> </tr>
% endif % endif
</tbody> </tbody>

View file

@ -450,7 +450,8 @@ def dbcheck():
'transcode_protocol TEXT, transcode_container TEXT, ' 'transcode_protocol TEXT, transcode_container TEXT, '
'transcode_video_codec TEXT, transcode_audio_codec TEXT, transcode_audio_channels INTEGER,' 'transcode_video_codec TEXT, transcode_audio_codec TEXT, transcode_audio_channels INTEGER,'
'transcode_width INTEGER, transcode_height INTEGER, ' 'transcode_width INTEGER, transcode_height INTEGER, '
'optimized_version INTEGER, optimized_version_profile TEXT, synced_version INTEGER, ' 'optimized_version INTEGER, optimized_version_profile TEXT, optimized_version_title TEXT, '
'synced_version INTEGER, synced_version_profile TEXT, '
'buffer_count INTEGER DEFAULT 0, buffer_last_triggered INTEGER, last_paused INTEGER, write_attempts INTEGER DEFAULT 0, ' 'buffer_count INTEGER DEFAULT 0, buffer_last_triggered INTEGER, last_paused INTEGER, write_attempts INTEGER DEFAULT 0, '
'raw_stream_info TEXT)' 'raw_stream_info TEXT)'
) )
@ -482,7 +483,8 @@ def dbcheck():
'stream_video_framerate TEXT, ' 'stream_video_framerate TEXT, '
'stream_audio_decision TEXT, stream_audio_codec TEXT, stream_audio_bitrate INTEGER, stream_audio_channels INTEGER, ' 'stream_audio_decision TEXT, stream_audio_codec TEXT, stream_audio_bitrate INTEGER, stream_audio_channels INTEGER, '
'stream_subtitle_decision TEXT, stream_subtitle_codec TEXT, stream_subtitle_container TEXT, stream_subtitle_forced INTEGER, ' 'stream_subtitle_decision TEXT, stream_subtitle_codec TEXT, stream_subtitle_container TEXT, stream_subtitle_forced INTEGER, '
'subtitles INTEGER, subtitle_codec TEXT, synced_version INTEGER, optimized_version INTEGER, optimized_version_profile TEXT)' 'subtitles INTEGER, subtitle_codec TEXT, synced_version INTEGER, synced_version_profile TEXT, '
'optimized_version INTEGER, optimized_version_profile TEXT, optimized_version_title TEXT)'
) )
# session_history_metadata table :: This is a table which logs each session's media metadata # session_history_metadata table :: This is a table which logs each session's media metadata
@ -892,6 +894,15 @@ def dbcheck():
'ALTER TABLE sessions ADD COLUMN raw_stream_info TEXT' 'ALTER TABLE sessions ADD COLUMN raw_stream_info TEXT'
) )
# Upgrade sessions table from earlier versions
try:
c_db.execute('SELECT video_height FROM sessions')
except sqlite3.OperationalError:
logger.debug(u"Altering database. Updating database table sessions.")
c_db.execute(
'ALTER TABLE sessions ADD COLUMN video_height INTEGER'
)
# Upgrade sessions table from earlier versions # Upgrade sessions table from earlier versions
try: try:
c_db.execute('SELECT subtitles FROM sessions') c_db.execute('SELECT subtitles FROM sessions')
@ -900,13 +911,17 @@ def dbcheck():
c_db.execute( c_db.execute(
'ALTER TABLE sessions ADD COLUMN subtitles INTEGER' 'ALTER TABLE sessions ADD COLUMN subtitles INTEGER'
) )
# Upgrade sessions table from earlier versions # Upgrade sessions table from earlier versions
try: try:
c_db.execute('SELECT video_height FROM sessions') c_db.execute('SELECT synced_version_profile FROM sessions')
except sqlite3.OperationalError: except sqlite3.OperationalError:
logger.debug(u"Altering database. Updating database table sessions.") logger.debug(u"Altering database. Updating database table sessions.")
c_db.execute( c_db.execute(
'ALTER TABLE sessions ADD COLUMN video_height INTEGER' 'ALTER TABLE sessions ADD COLUMN synced_version_profile TEXT'
)
c_db.execute(
'ALTER TABLE sessions ADD COLUMN optimized_version_title TEXT'
) )
# Upgrade session_history table from earlier versions # Upgrade session_history table from earlier versions
@ -1139,6 +1154,18 @@ def dbcheck():
'ALTER TABLE session_history_media_info ADD COLUMN subtitle_codec TEXT ' 'ALTER TABLE session_history_media_info ADD COLUMN subtitle_codec TEXT '
) )
# Upgrade session_history_media_info table from earlier versions
try:
c_db.execute('SELECT synced_version_profile FROM session_history_media_info')
except sqlite3.OperationalError:
logger.debug(u"Altering database. Updating database table session_history_media_info.")
c_db.execute(
'ALTER TABLE session_history_media_info ADD COLUMN synced_version_profile TEXT '
)
c_db.execute(
'ALTER TABLE session_history_media_info ADD COLUMN optimized_version_title TEXT '
)
# Upgrade users table from earlier versions # Upgrade users table from earlier versions
try: try:
c_db.execute('SELECT do_notify FROM users') c_db.execute('SELECT do_notify FROM users')

View file

@ -90,9 +90,11 @@ class ActivityProcessor(object):
'transcode_audio_channels': session.get('transcode_audio_channels', ''), 'transcode_audio_channels': session.get('transcode_audio_channels', ''),
'transcode_width': session.get('stream_video_width', ''), 'transcode_width': session.get('stream_video_width', ''),
'transcode_height': session.get('stream_video_height', ''), 'transcode_height': session.get('stream_video_height', ''),
'synced_version': session.get('synced_version', ''),
'synced_version_profile': session.get('synced_version_profile', ''),
'optimized_version': session.get('optimized_version', ''), 'optimized_version': session.get('optimized_version', ''),
'optimized_version_profile': session.get('optimized_version_profile', ''), 'optimized_version_profile': session.get('optimized_version_profile', ''),
'synced_version': session.get('synced_version', ''), 'optimized_version_title': session.get('optimized_version_title', ''),
'stream_bitrate': session.get('stream_bitrate', ''), 'stream_bitrate': session.get('stream_bitrate', ''),
'stream_video_resolution': session.get('stream_video_resolution', ''), 'stream_video_resolution': session.get('stream_video_resolution', ''),
'quality_profile': session.get('quality_profile', ''), 'quality_profile': session.get('quality_profile', ''),
@ -110,6 +112,7 @@ class ActivityProcessor(object):
'stream_audio_channels': session.get('stream_audio_channels', ''), 'stream_audio_channels': session.get('stream_audio_channels', ''),
'stream_subtitle_decision': session.get('stream_subtitle_decision', ''), 'stream_subtitle_decision': session.get('stream_subtitle_decision', ''),
'stream_subtitle_codec': session.get('stream_subtitle_codec', ''), 'stream_subtitle_codec': session.get('stream_subtitle_codec', ''),
'subtitles': session.get('subtitles', ''),
'raw_stream_info': json.dumps(session), 'raw_stream_info': json.dumps(session),
'stopped': int(time.time()) 'stopped': int(time.time())
} }
@ -356,6 +359,8 @@ class ActivityProcessor(object):
'stream_subtitle_forced': session['stream_subtitle_forced'], 'stream_subtitle_forced': session['stream_subtitle_forced'],
'subtitles': session['subtitles'], 'subtitles': session['subtitles'],
'synced_version': session['synced_version'], 'synced_version': session['synced_version'],
'synced_version_profile': session['synced_version_profile'],
'synced_version_title': session['synced_version_title'],
'optimized_version': session['optimized_version'], 'optimized_version': session['optimized_version'],
'optimized_version_profile': session['optimized_version_profile'] 'optimized_version_profile': session['optimized_version_profile']
} }

View file

@ -872,8 +872,10 @@ class DataFactory(object):
user_cond = 'AND %s.user_id = %s ' % (table, session.get_session_user_id()) user_cond = 'AND %s.user_id = %s ' % (table, session.get_session_user_id())
if row_id: if row_id:
query = 'SELECT bitrate, video_resolution, optimized_version, optimized_version_profile, synced_version, ' \ query = 'SELECT bitrate, video_resolution, ' \
'container, video_codec, video_Bitrate, video_width, video_height, video_framerate, aspect_ratio, ' \ 'optimized_version, optimized_version_profile, optimized_version_title, ' \
'synced_version, synced_version_profile, ' \
'container, video_codec, video_bitrate, video_width, video_height, video_framerate, aspect_ratio, ' \
'audio_codec, audio_bitrate, audio_channels, subtitle_codec, ' \ 'audio_codec, audio_bitrate, audio_channels, subtitle_codec, ' \
'stream_bitrate, stream_video_resolution, quality_profile, stream_container_decision, stream_container, ' \ 'stream_bitrate, stream_video_resolution, quality_profile, stream_container_decision, stream_container, ' \
'stream_video_decision, stream_video_codec, stream_video_bitrate, stream_video_width, stream_video_height, ' \ 'stream_video_decision, stream_video_codec, stream_video_bitrate, stream_video_width, stream_video_height, ' \
@ -887,8 +889,10 @@ class DataFactory(object):
'WHERE session_history_media_info.id = ? %s' % user_cond 'WHERE session_history_media_info.id = ? %s' % user_cond
result = monitor_db.select(query, args=[row_id]) result = monitor_db.select(query, args=[row_id])
elif session_key: elif session_key:
query = 'SELECT bitrate, video_resolution, optimized_version, optimized_version_profile, synced_version, ' \ query = 'SELECT bitrate, video_resolution, ' \
'container, video_codec, video_Bitrate, video_width, video_height, video_framerate, aspect_ratio, ' \ 'optimized_version, optimized_version_profile, optimized_version_title, ' \
'synced_version, synced_version_profile, ' \
'container, video_codec, video_bitrate, video_width, video_height, video_framerate, aspect_ratio, ' \
'audio_codec, audio_bitrate, audio_channels, subtitle_codec, ' \ 'audio_codec, audio_bitrate, audio_channels, subtitle_codec, ' \
'stream_bitrate, stream_video_resolution, quality_profile, stream_container_decision, stream_container, ' \ 'stream_bitrate, stream_video_resolution, quality_profile, stream_container_decision, stream_container, ' \
'stream_video_decision, stream_video_codec, stream_video_bitrate, stream_video_width, stream_video_height, ' \ 'stream_video_decision, stream_video_codec, stream_video_bitrate, stream_video_width, stream_video_height, ' \
@ -909,7 +913,9 @@ class DataFactory(object):
'video_resolution': item['video_resolution'], 'video_resolution': item['video_resolution'],
'optimized_version': item['optimized_version'], 'optimized_version': item['optimized_version'],
'optimized_version_profile': item['optimized_version_profile'], 'optimized_version_profile': item['optimized_version_profile'],
'optimized_version_title': item['optimized_version_title'],
'synced_version': item['synced_version'], 'synced_version': item['synced_version'],
'synced_version_profile': item['synced_version_profile'],
'container': item['container'], 'container': item['container'],
'video_codec': item['video_codec'], 'video_codec': item['video_codec'],
'video_bitrate': item['video_bitrate'], 'video_bitrate': item['video_bitrate'],

View file

@ -425,7 +425,7 @@ class PlexTV(object):
return users_list return users_list
def get_synced_items(self, machine_id=None, user_id=None): def get_synced_items(self, machine_id=None, client_id_filter=None, user_id_filter=None, rating_key_filter=None):
sync_list = self.get_plextv_sync_lists(machine_id) sync_list = self.get_plextv_sync_lists(machine_id)
user_data = users.Users() user_data = users.Users()
@ -446,9 +446,15 @@ class PlexTV(object):
logger.warn(u"Tautulli PlexTV :: Unable to parse XML for get_synced_items.") logger.warn(u"Tautulli PlexTV :: Unable to parse XML for get_synced_items.")
else: else:
for a in xml_head: for a in xml_head:
sync_id = helpers.get_xml_attr(a, 'id')
client_id = helpers.get_xml_attr(a, 'clientIdentifier') client_id = helpers.get_xml_attr(a, 'clientIdentifier')
# Filter by client_id
if client_id_filter and client_id_filter != client_id:
continue
sync_id = helpers.get_xml_attr(a, 'id')
sync_device = a.getElementsByTagName('Device') sync_device = a.getElementsByTagName('Device')
for device in sync_device: for device in sync_device:
device_user_id = helpers.get_xml_attr(device, 'userID') device_user_id = helpers.get_xml_attr(device, 'userID')
try: try:
@ -467,12 +473,23 @@ class PlexTV(object):
device_last_seen = helpers.get_xml_attr(device, 'lastSeenAt') device_last_seen = helpers.get_xml_attr(device, 'lastSeenAt')
# Filter by user_id # Filter by user_id
if user_id and user_id != device_user_id: if user_id_filter and user_id_filter != device_user_id:
continue continue
for synced in a.getElementsByTagName('SyncItems'): for synced in a.getElementsByTagName('SyncItems'):
sync_item = synced.getElementsByTagName('SyncItem') sync_item = synced.getElementsByTagName('SyncItem')
for item in sync_item: for item in sync_item:
for location in item.getElementsByTagName('Location'):
clean_uri = helpers.get_xml_attr(location, 'uri').split('%2F')
rating_key = next((clean_uri[(idx + 1) % len(clean_uri)]
for idx, item in enumerate(clean_uri) if item == 'metadata'), None)
# Filter by rating_key
if rating_key_filter and rating_key_filter != rating_key:
continue
sync_id = helpers.get_xml_attr(item, 'id') sync_id = helpers.get_xml_attr(item, 'id')
sync_version = helpers.get_xml_attr(item, 'version') sync_version = helpers.get_xml_attr(item, 'version')
sync_root_title = helpers.get_xml_attr(item, 'rootTitle') sync_root_title = helpers.get_xml_attr(item, 'rootTitle')
@ -501,12 +518,6 @@ class PlexTV(object):
settings_video_quality = helpers.get_xml_attr(settings, 'videoQuality') settings_video_quality = helpers.get_xml_attr(settings, 'videoQuality')
settings_video_resolution = helpers.get_xml_attr(settings, 'videoResolution') settings_video_resolution = helpers.get_xml_attr(settings, 'videoResolution')
for location in item.getElementsByTagName('Location'):
clean_uri = helpers.get_xml_attr(location, 'uri').split('%2F')
rating_key = next((clean_uri[(idx + 1) % len(clean_uri)]
for idx, item in enumerate(clean_uri) if item == 'metadata'), None)
sync_details = {"device_name": helpers.sanitize(device_name), sync_details = {"device_name": helpers.sanitize(device_name),
"platform": helpers.sanitize(device_platform), "platform": helpers.sanitize(device_platform),
"username": helpers.sanitize(device_username), "username": helpers.sanitize(device_username),

View file

@ -24,6 +24,7 @@ import helpers
import http_handler import http_handler
import libraries import libraries
import logger import logger
import plextv
import session import session
import users import users
@ -590,7 +591,7 @@ class PmsConnect(object):
return output return output
def get_metadata_details(self, rating_key=''): def get_metadata_details(self, rating_key='', sync_id=''):
""" """
Return processed and validated metadata list for requested item. Return processed and validated metadata list for requested item.
@ -598,7 +599,10 @@ class PmsConnect(object):
Output: array Output: array
""" """
if rating_key:
metadata = self.get_metadata(str(rating_key), output_format='xml') metadata = self.get_metadata(str(rating_key), output_format='xml')
elif sync_id:
metadata = self.get_sync_item(str(sync_id), output_format='xml')
try: try:
xml_head = metadata.getElementsByTagName('MediaContainer') xml_head = metadata.getElementsByTagName('MediaContainer')
@ -1322,6 +1326,7 @@ class PmsConnect(object):
# Get the source media type # Get the source media type
media_type = helpers.get_xml_attr(session, 'type') media_type = helpers.get_xml_attr(session, 'type')
rating_key = helpers.get_xml_attr(session, 'ratingKey')
# Get the user details # Get the user details
user_info = session.getElementsByTagName('User')[0] user_info = session.getElementsByTagName('User')[0]
@ -1348,7 +1353,7 @@ class PmsConnect(object):
'product_version': helpers.get_xml_attr(player_info, 'version'), 'product_version': helpers.get_xml_attr(player_info, 'version'),
'profile': helpers.get_xml_attr(player_info, 'profile'), 'profile': helpers.get_xml_attr(player_info, 'profile'),
'player': helpers.get_xml_attr(player_info, 'title') or helpers.get_xml_attr(player_info, 'product'), 'player': helpers.get_xml_attr(player_info, 'title') or helpers.get_xml_attr(player_info, 'product'),
'machine_id': helpers.get_xml_attr(player_info, 'machineIdentifier').rstrip('_Video').rstrip('_Track'), 'machine_id': helpers.get_xml_attr(player_info, 'machineIdentifier'),
'state': helpers.get_xml_attr(player_info, 'state'), 'state': helpers.get_xml_attr(player_info, 'state'),
'local': helpers.get_xml_attr(player_info, 'local') 'local': helpers.get_xml_attr(player_info, 'local')
} }
@ -1431,14 +1436,29 @@ class PmsConnect(object):
# Determine if a synced version is being played # Determine if a synced version is being played
if media_type not in ('photo', 'clip') and not session.getElementsByTagName('Session') \ if media_type not in ('photo', 'clip') and not session.getElementsByTagName('Session') \
and helpers.get_xml_attr(session, 'ratingKey').isdigit() and transcode_decision == 'direct play': and helpers.get_xml_attr(session, 'ratingKey').isdigit() and transcode_decision == 'direct play':
synced_version = 1 plex_tv = plextv.PlexTV()
synced_items = plex_tv.get_synced_items(machine_id=plexpy.CONFIG.PMS_IDENTIFIER,
client_id_filter=player_details['machine_id'],
rating_key_filter=rating_key)
if synced_items:
sync_id = synced_items[0]['sync_id']
synced_xml = self.get_sync_item(sync_id=sync_id, output_format='xml')
synced_xml_head = synced_xml.getElementsByTagName('MediaContainer')
if synced_xml_head[0].getElementsByTagName('Track'):
synced_session_data = synced_xml_head[0].getElementsByTagName('Track')[0]
elif synced_xml_head[0].getElementsByTagName('Video'):
synced_session_data = synced_xml_head[0].getElementsByTagName('Video')[0]
else: else:
synced_version = 0 sync_id = None
# Figure out which version is being played # Figure out which version is being played
if sync_id:
media_info_all = synced_session_data.getElementsByTagName('Media')
else:
media_info_all = session.getElementsByTagName('Media') media_info_all = session.getElementsByTagName('Media')
stream_media_info = next((m for m in media_info_all if helpers.get_xml_attr(m, 'selected') == '1'), media_info_all[0]) stream_media_info = next((m for m in media_info_all if helpers.get_xml_attr(m, 'selected') == '1'), media_info_all[0])
stream_media_parts_info = stream_media_info.getElementsByTagName('Part')[0] part_info_all = stream_media_info.getElementsByTagName('Part')
stream_media_parts_info = next((p for p in part_info_all if helpers.get_xml_attr(p, 'selected') == '1'), part_info_all[0])
# Get the stream details # Get the stream details
video_stream_info = audio_stream_info = subtitle_stream_info = None video_stream_info = audio_stream_info = subtitle_stream_info = None
@ -1495,6 +1515,7 @@ class PmsConnect(object):
if subtitle_stream_info: if subtitle_stream_info:
subtitle_id = helpers.get_xml_attr(subtitle_stream_info, 'id') subtitle_id = helpers.get_xml_attr(subtitle_stream_info, 'id')
subtitle_selected = helpers.get_xml_attr(subtitle_stream_info, 'selected')
subtitle_details = {'stream_subtitle_codec': helpers.get_xml_attr(subtitle_stream_info, 'codec'), subtitle_details = {'stream_subtitle_codec': helpers.get_xml_attr(subtitle_stream_info, 'codec'),
'stream_subtitle_container': helpers.get_xml_attr(subtitle_stream_info, 'container'), 'stream_subtitle_container': helpers.get_xml_attr(subtitle_stream_info, 'container'),
'stream_subtitle_format': helpers.get_xml_attr(subtitle_stream_info, 'format'), 'stream_subtitle_format': helpers.get_xml_attr(subtitle_stream_info, 'format'),
@ -1544,14 +1565,14 @@ class PmsConnect(object):
'stream_video_height': helpers.get_xml_attr(stream_media_info, 'height'), 'stream_video_height': helpers.get_xml_attr(stream_media_info, 'height'),
'stream_video_width': helpers.get_xml_attr(stream_media_info, 'width'), 'stream_video_width': helpers.get_xml_attr(stream_media_info, 'width'),
'stream_duration': helpers.get_xml_attr(stream_media_info, 'duration') or helpers.get_xml_attr(session, 'duration'), 'stream_duration': helpers.get_xml_attr(stream_media_info, 'duration') or helpers.get_xml_attr(session, 'duration'),
'stream_container_decision': helpers.get_xml_attr(stream_media_parts_info, 'decision').replace('directplay', 'direct play'), 'stream_container_decision': 'direct play' if sync_id else helpers.get_xml_attr(stream_media_parts_info, 'decision').replace('directplay', 'direct play'),
'transcode_decision': transcode_decision, 'transcode_decision': transcode_decision,
'optimized_version': 1 if helpers.get_xml_attr(stream_media_info, 'proxyType') == '42' else 0, 'optimized_version': 1 if helpers.get_xml_attr(stream_media_info, 'proxyType') == '42' else 0,
'optimized_version_profile': helpers.get_xml_attr(stream_media_info, 'title'), 'optimized_version_title': helpers.get_xml_attr(stream_media_info, 'title'),
'synced_version': synced_version, 'synced_version': 1 if sync_id else 0,
'indexes': 1 if indexes == 'sd' else 0, 'indexes': 1 if indexes == 'sd' else 0,
'bif_thumb': bif_thumb, 'bif_thumb': bif_thumb,
'subtitles': 1 if subtitle_id else 0 'subtitles': 1 if subtitle_id and subtitle_selected else 0
} }
# Get the source media info # Get the source media info
@ -1617,7 +1638,10 @@ class PmsConnect(object):
media_id = helpers.get_xml_attr(stream_media_info, 'id') media_id = helpers.get_xml_attr(stream_media_info, 'id')
part_id = helpers.get_xml_attr(stream_media_parts_info, 'id') part_id = helpers.get_xml_attr(stream_media_parts_info, 'id')
metadata_details = self.get_metadata_details(rating_key=helpers.get_xml_attr(session, 'ratingKey')) if sync_id:
metadata_details = self.get_metadata_details(sync_id=sync_id)
else:
metadata_details = self.get_metadata_details(rating_key=rating_key)
# Get the media info, fallback to first item if match id is not found # Get the media info, fallback to first item if match id is not found
source_medias = metadata_details.pop('media_info', []) source_medias = metadata_details.pop('media_info', [])
@ -1683,6 +1707,21 @@ class PmsConnect(object):
except ValueError: except ValueError:
quality_profile = 'Original' quality_profile = 'Original'
if sync_id:
try:
synced_bitrate = min(b for b in common.VIDEO_QUALITY_PROFILES if source_bitrate <= b)
synced_version_profile = common.VIDEO_QUALITY_PROFILES[synced_bitrate]
except ValueError:
synced_version_profile = 'Original'
else:
synced_version_profile = ''
if stream_details['optimized_version']:
optimized_version_profile = '{} Mbps {}'.format(round(source_bitrate / 1000.0, 1),
plexpy.common.VIDEO_RESOLUTION_OVERRIDES.get(source_media_details['video_resolution'], source_media_details['video_resolution']))
else:
optimized_version_profile = ''
elif media_type == 'track' and 'stream_bitrate' in stream_details: elif media_type == 'track' and 'stream_bitrate' in stream_details:
stream_bitrate = helpers.cast_to_int(stream_details['stream_bitrate']) stream_bitrate = helpers.cast_to_int(stream_details['stream_bitrate'])
source_bitrate = helpers.cast_to_int(source_media_details.get('bitrate')) source_bitrate = helpers.cast_to_int(source_media_details.get('bitrate'))
@ -1693,11 +1732,26 @@ class PmsConnect(object):
except ValueError: except ValueError:
quality_profile = 'Original' quality_profile = 'Original'
if sync_id:
try:
synced_bitrate = min(b for b in common.AUDIO_QUALITY_PROFILES if source_bitrate <= b)
synced_version_profile = common.AUDIO_QUALITY_PROFILES[synced_bitrate]
except ValueError:
synced_version_profile = 'Original'
else:
synced_version_profile = ''
optimized_version_profile = ''
elif media_type == 'photo': elif media_type == 'photo':
quality_profile = 'Original' quality_profile = 'Original'
synced_version_profile = ''
optimized_version_profile = ''
else: else:
quality_profile = 'Unknown' quality_profile = 'Unknown'
synced_version_profile = ''
optimized_version_profile = ''
# Entire session output (single dict for backwards compatibility) # Entire session output (single dict for backwards compatibility)
session_output = {'session_key': helpers.get_xml_attr(session, 'sessionKey'), session_output = {'session_key': helpers.get_xml_attr(session, 'sessionKey'),
@ -1705,6 +1759,8 @@ class PmsConnect(object):
'view_offset': view_offset, 'view_offset': view_offset,
'progress_percent': str(helpers.get_percent(view_offset, stream_details['stream_duration'])), 'progress_percent': str(helpers.get_percent(view_offset, stream_details['stream_duration'])),
'quality_profile': quality_profile, 'quality_profile': quality_profile,
'synced_version_profile': synced_version_profile,
'optimized_version_profile': optimized_version_profile,
'user': user_details['username'], # Keep for backwards compatibility 'user': user_details['username'], # Keep for backwards compatibility
'channel_stream': channel_stream 'channel_stream': channel_stream
} }

View file

@ -2195,7 +2195,7 @@ class WebInterface(object):
machine_id = plexpy.CONFIG.PMS_IDENTIFIER machine_id = plexpy.CONFIG.PMS_IDENTIFIER
plex_tv = plextv.PlexTV() plex_tv = plextv.PlexTV()
result = plex_tv.get_synced_items(machine_id=machine_id, user_id=user_id) result = plex_tv.get_synced_items(machine_id=machine_id, user_id_filter=user_id)
if result: if result:
output = {"data": result} output = {"data": result}
@ -4560,7 +4560,7 @@ class WebInterface(object):
``` ```
""" """
plex_tv = plextv.PlexTV() plex_tv = plextv.PlexTV()
result = plex_tv.get_synced_items(machine_id=machine_id, user_id=user_id) result = plex_tv.get_synced_items(machine_id=machine_id, user_id_filter=user_id)
if result: if result:
return result return result