Add identifying playback of synced items

This commit is contained in:
JonnyWong16 2017-11-02 18:33:18 -07:00
commit e1dc299cba
4 changed files with 61 additions and 35 deletions

View file

@ -92,10 +92,14 @@ DOCUMENTATION :: END
rating_key = data['grandparent_rating_key'] rating_key = data['grandparent_rating_key']
title = data['grandparent_title'] title = data['grandparent_title']
thumb = data['grandparent_thumb'] thumb = data['grandparent_thumb']
else:
rating_key = ''
title = ''
thumb = ''
%> %>
% if data['rating_key'] and data['media_type'] not in ('photo', 'clip'): % if data['rating_key'] and data['media_type'] not in ('photo', 'clip'):
<a id="poster-url-${data['session_key']}" href="info?rating_key=${rating_key}" title="${title}" class="hidden-xs"> <a id="poster-url-${data['session_key']}" href="info?rating_key=${rating_key}" title="${title}" class="hidden-xs">
<div id="poster-${data['session_key']}" class="dashboard-activity-poster" style="background-image: url(pms_image_proxy?img=${thumb}&width=300&height=450&fallback=poster&refresh=true);"></div> <div id="poster-${data['session_key']}" class="dashboard-activity-${'cover' if data['media_type'] == 'track' else 'poster'}" style="background-image: url(pms_image_proxy?img=${thumb}&width=300&height=450&fallback=poster&refresh=true);"></div>
</a> </a>
% elif data['media_type']: % elif data['media_type']:
<div id="poster-${data['session_key']}" class="dashboard-activity-poster" style="background-image: url(pms_image_proxy?img=${thumb}&width=300&height=450&fallback=poster&refresh=true);"></div> <div id="poster-${data['session_key']}" class="dashboard-activity-poster" style="background-image: url(pms_image_proxy?img=${thumb}&width=300&height=450&fallback=poster&refresh=true);"></div>
@ -103,7 +107,13 @@ DOCUMENTATION :: END
<div id="poster-${data['session_key']}" class="dashboard-activity-poster" style="background-image: url(images/art.png);"></div> <div id="poster-${data['session_key']}" class="dashboard-activity-poster" style="background-image: url(images/art.png);"></div>
% endif % endif
<div class="dashboard-activity-info-icon"> <div class="dashboard-activity-info-icon">
<div id="platform-${data['session_key']}" class="dashboard-activity-info-platform${'-no-terminate' if not _session['user_group'] == 'admin' else ''}" title="${data['platform']}"> <%
if not _session['user_group'] == 'admin' or data['synced_version'] == '1':
no_terminate = '-no-terminate'
else:
no_terminate = ''
%>
<div id="platform-${data['session_key']}" class="dashboard-activity-info-platform${no_terminate}" title="${data['platform']}">
<script> <script>
$("#platform-${data['session_key']}").css("background-image", "url(" + getPlatformImagePath('${data['platform']}') + ")"); $("#platform-${data['session_key']}").css("background-image", "url(" + getPlatformImagePath('${data['platform']}') + ")");
</script> </script>
@ -133,9 +143,9 @@ DOCUMENTATION :: END
br = helpers.cast_to_int(data['stream_bitrate']) or '' br = helpers.cast_to_int(data['stream_bitrate']) or ''
if br: if br:
if br > 1000: if br > 1000:
br = '(' + str(round(br / 1000.0, 1)) + 'Mbps)' br = '(' + str(round(br / 1000.0, 1)) + ' Mbps)'
else: else:
br = '(' + str(br) + 'kbps)' br = '(' + str(br) + ' kbps)'
%> %>
${data['quality_profile']} ${br} ${data['quality_profile']} ${br}
% else: % else:
@ -170,7 +180,7 @@ DOCUMENTATION :: END
% elif data['transcode_decision'] == 'copy': % elif data['transcode_decision'] == 'copy':
Direct Stream Direct Stream
% else: % else:
Direct Play Direct Play ${'(Synced)' if data['synced_version'] else ''}
% endif % endif
</div> </div>
</li> </li>
@ -214,11 +224,11 @@ DOCUMENTATION :: END
<div class="sub-heading">Audio</div> <div class="sub-heading">Audio</div>
<div class="sub-value" id="audio_decision-${data['session_key']}"> <div class="sub-value" id="audio_decision-${data['session_key']}">
% if data['stream_audio_decision'] == 'transcode': % if data['stream_audio_decision'] == 'transcode':
Transcode (${plexpy.common.AUDIO_CODEC_OVERRIDES.get(data['audio_codec'], data['audio_codec'].upper())} ${data['audio_channel_layout'].split('(')[0]} &rarr; ${plexpy.common.AUDIO_CODEC_OVERRIDES.get(data['stream_audio_codec'], data['stream_audio_codec'].upper())} ${data['stream_audio_channel_layout']}) Transcode (${plexpy.common.AUDIO_CODEC_OVERRIDES.get(data['audio_codec'], data['audio_codec'].upper())} ${data['audio_channel_layout'].split('(')[0].capitalize()} &rarr; ${plexpy.common.AUDIO_CODEC_OVERRIDES.get(data['stream_audio_codec'], data['stream_audio_codec'].upper())} ${data['stream_audio_channel_layout'].split('(')[0].capitalize()})
% elif data['stream_audio_decision'] == 'copy': % elif data['stream_audio_decision'] == 'copy':
Direct Stream (${plexpy.common.AUDIO_CODEC_OVERRIDES.get(data['stream_audio_codec'], data['stream_audio_codec'].upper())} ${data['stream_audio_channel_layout']}) Direct Stream (${plexpy.common.AUDIO_CODEC_OVERRIDES.get(data['stream_audio_codec'], data['stream_audio_codec'].upper())} ${data['stream_audio_channel_layout'].split('(')[0].capitalize()})
% else: % else:
Direct Play (${plexpy.common.AUDIO_CODEC_OVERRIDES.get(data['audio_codec'], data['audio_codec'].upper())} ${data['audio_channel_layout'].split('(')[0]}) Direct Play (${plexpy.common.AUDIO_CODEC_OVERRIDES.get(data['audio_codec'], data['audio_codec'].upper())} ${data['audio_channel_layout'].split('(')[0].capitalize()})
% endif % endif
</div> </div>
</li> </li>
@ -268,17 +278,21 @@ DOCUMENTATION :: END
<li class="dashboard-activity-info-item"> <li class="dashboard-activity-info-item">
<div class="sub-heading">Bandwidth</div> <div class="sub-heading">Bandwidth</div>
<div class="sub-value"> <div class="sub-value">
% if data['media_type'] != 'photo' and 'location' in data: % if data['media_type'] != 'photo' and data['bandwidth']:
<% <%
bw = helpers.cast_to_int(data['bandwidth']) or "Unknown" bw = helpers.cast_to_int(data['bandwidth']) or "Unknown"
if bw != "Unknown": if bw != "Unknown":
if bw > 1000: if bw > 1000:
bw = str(round(bw / 1000.0, 1)) + 'Mbps' bw = str(round(bw / 1000.0, 1)) + ' Mbps'
else: else:
bw = str(bw) + 'kbps' bw = str(bw) + ' kbps'
%> %>
<span id="stream-bandwidth-${data['session_key']}">${bw}</span> <span id="stream-bandwidth-${data['session_key']}">${bw}</span>
<span id="streaming-brain-${data['session_key']}" data-toggle="tooltip" title="Streaming Brain Estimate"><i class="fa fa-info-circle"></i></span> <span id="streaming-brain-${data['session_key']}" data-toggle="tooltip" title="Streaming Brain Estimate"><i class="fa fa-info-circle"></i></span>
% elif data['synced_version'] == '1':
<span id="stream-bandwidth-${data['session_key']}">None</span>
% else:
<span id="stream-bandwidth-${data['session_key']}">Unknown</span>
% endif % endif
</div> </div>
</li> </li>

View file

@ -324,7 +324,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'; transcode_decision = 'Direct Play' + ((s.synced_version == 1) ? ' (Synced)' : '');
} }
$('#transcode_decision-' + key).html(transcode_decision); $('#transcode_decision-' + key).html(transcode_decision);
@ -383,11 +383,11 @@
var a_codec = (s.audio_codec === 'truehd') ? 'TrueHD' : s.audio_codec.toUpperCase(); var a_codec = (s.audio_codec === 'truehd') ? 'TrueHD' : s.audio_codec.toUpperCase();
var sa_codec = (s.stream_audio_codec === 'truehd') ? 'TrueHD' : s.stream_audio_codec.toUpperCase(); var sa_codec = (s.stream_audio_codec === 'truehd') ? 'TrueHD' : s.stream_audio_codec.toUpperCase();
if (s.stream_audio_decision === 'transcode') { if (s.stream_audio_decision === 'transcode') {
audio_decision = 'Transcode (' + a_codec + ' ' + s.audio_channel_layout.split('(')[0] + ' &rarr; ' + sa_codec + ' ' + s.stream_audio_channel_layout + ')'; audio_decision = 'Transcode (' + a_codec + ' ' + capitalizeFirstLetter(s.audio_channel_layout.split('(')[0]) + ' &rarr; ' + sa_codec + ' ' + capitalizeFirstLetter(s.stream_audio_channel_layout.split('(')[0]) + ')';
} else if (s.stream_audio_decision === 'copy') { } else if (s.stream_audio_decision === 'copy') {
audio_decision = 'Direct Stream (' + sa_codec + ' ' + s.stream_audio_channel_layout + ')'; audio_decision = 'Direct Stream (' + sa_codec + ' ' + capitalizeFirstLetter(s.stream_audio_channel_layout.split('(')[0]) + ')';
} else { } else {
audio_decision = 'Direct Play (' + a_codec + ' ' + s.audio_channel_layout.split('(')[0] + ')'; audio_decision = 'Direct Play (' + a_codec + ' ' + capitalizeFirstLetter(s.audio_channel_layout.split('(')[0]) + ')';
} }
} }
$('#audio_decision-' + key).html(audio_decision); $('#audio_decision-' + key).html(audio_decision);
@ -411,9 +411,9 @@
var br = parseInt(s.stream_bitrate) || ''; var br = parseInt(s.stream_bitrate) || '';
if (br) { if (br) {
if (br > 1000) { if (br > 1000) {
br = ' (' + (br / 1000).toFixed(1) + 'Mbps)'; br = ' (' + (br / 1000).toFixed(1) + ' Mbps)';
} else { } else {
br = ' (' + br + 'kbps)'; br = ' (' + br + ' kbps)';
} }
} }
$('#stream_quality-' + key).html(s.quality_profile + br); $('#stream_quality-' + key).html(s.quality_profile + br);
@ -422,15 +422,17 @@
} }
$('#optimized_version-' + key).html(s.optimized_version_profile); $('#optimized_version-' + key).html(s.optimized_version_profile);
var bw = parseInt(s.bandwidth) || 'Unknown'; if (s.media_type != 'photo' && s.bandwidth) {
if (bw != "Unknown") { var bw = parseInt(s.bandwidth) || 'Unknown';
if (bw > 1000) { if (bw != "Unknown") {
bw = (bw / 1000).toFixed(1) + 'Mbps'; if (bw > 1000) {
} else { bw = (bw / 1000).toFixed(1) + ' Mbps';
bw = bw + ' kbps' } else {
bw = bw + ' kbps'
}
} }
$('#stream-bandwidth-' + key).html(bw);
} }
$('#stream-bandwidth-' + key).html(bw );
// Update the stream progress times // Update the stream progress times
$('#stream-eta-' + key).html(moment().add(parseInt(s.duration) - parseInt(s.view_offset), 'milliseconds').format(time_format)); $('#stream-eta-' + key).html(moment().add(parseInt(s.duration) - parseInt(s.view_offset), 'milliseconds').format(time_format));

View file

@ -231,6 +231,7 @@ NOTIFICATION_PARAMETERS = [
{'name': 'Quality Profile', 'type': 'str', 'value': 'quality_profile', 'description': 'The Plex quality profile of the stream.', 'example': 'e.g. Original, 4 Mbps 720p, etc.'}, {'name': 'Quality Profile', 'type': 'str', 'value': 'quality_profile', 'description': 'The Plex quality profile of the stream.', 'example': 'e.g. Original, 4 Mbps 720p, etc.'},
{'name': 'Optimized Version', 'type': 'int', 'value': 'optimized_version', 'description': 'If the stream is an optimized version.', 'example': '0 or 1'}, {'name': 'Optimized Version', 'type': 'int', 'value': 'optimized_version', 'description': 'If the stream is an optimized version.', 'example': '0 or 1'},
{'name': 'Optimized Version Profile', 'type': 'str', 'value': 'optimized_version_profile', 'description': 'The optimized version profile of the stream.'}, {'name': 'Optimized Version Profile', 'type': 'str', 'value': 'optimized_version_profile', 'description': 'The optimized version profile of the stream.'},
{'name': 'Synced Version', 'type': 'int', 'value': 'synced_version', 'description': 'If the stream is an synced version.', 'example': '0 or 1'},
{'name': 'Stream Local', 'type': 'int', 'value': 'stream_local', 'description': 'If the stream is local.', 'example': '0 or 1'}, {'name': 'Stream Local', 'type': 'int', 'value': 'stream_local', 'description': 'If the stream is local.', 'example': '0 or 1'},
{'name': 'Stream Location', 'type': 'str', 'value': 'stream_location', 'description': 'The network location of the stream.', 'example': 'lan or wan'}, {'name': 'Stream Location', 'type': 'str', 'value': 'stream_location', 'description': 'The network location of the stream.', 'example': 'lan or wan'},
{'name': 'Stream Bandwidth', 'type': 'int', 'value': 'stream_bandwidth', 'description': 'The required bandwidth (in kbps) of the stream.', 'help_text': 'not the used bandwidth'}, {'name': 'Stream Bandwidth', 'type': 'int', 'value': 'stream_bandwidth', 'description': 'The required bandwidth (in kbps) of the stream.', 'help_text': 'not the used bandwidth'},

View file

@ -1312,6 +1312,9 @@ class PmsConnect(object):
Output: dict Output: dict
""" """
# Get the source media type
media_type = helpers.get_xml_attr(session, 'type')
# Get the user details # Get the user details
user_info = session.getElementsByTagName('User')[0] user_info = session.getElementsByTagName('User')[0]
user_details = users.Users().get_details(user=helpers.get_xml_attr(user_info, 'title')) user_details = users.Users().get_details(user=helpers.get_xml_attr(user_info, 'title'))
@ -1406,6 +1409,20 @@ class PmsConnect(object):
'throttled': '0' # Keep for backwards compatibility 'throttled': '0' # Keep for backwards compatibility
} }
# Generate a combined transcode decision value
if transcode_details['video_decision'] == 'transcode' or transcode_details['audio_decision'] == 'transcode':
transcode_decision = 'transcode'
elif transcode_details['video_decision'] == 'copy' or transcode_details['audio_decision'] == 'copy':
transcode_decision = 'copy'
else:
transcode_decision = 'direct play'
# Determine if a synced version is being played
if media_type not in ('photo', 'clip') and not session.getElementsByTagName('Session') and transcode_decision == 'direct play':
synced_version = 1
else:
synced_version = 0
# Figure out which version is being played # Figure out which version is being played
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])
@ -1441,6 +1458,7 @@ class PmsConnect(object):
audio_details = {'stream_audio_bitrate': helpers.get_xml_attr(audio_stream_info, 'bitrate'), audio_details = {'stream_audio_bitrate': helpers.get_xml_attr(audio_stream_info, 'bitrate'),
'stream_audio_bitrate_mode': helpers.get_xml_attr(audio_stream_info, 'bitrateMode'), 'stream_audio_bitrate_mode': helpers.get_xml_attr(audio_stream_info, 'bitrateMode'),
'stream_audio_sample_rate': helpers.get_xml_attr(audio_stream_info, 'samplingRate'), 'stream_audio_sample_rate': helpers.get_xml_attr(audio_stream_info, 'samplingRate'),
'stream_audio_channel_layout_': helpers.get_xml_attr(audio_stream_info, 'audioChannelLayout'),
'stream_audio_language': helpers.get_xml_attr(audio_stream_info, 'language'), 'stream_audio_language': helpers.get_xml_attr(audio_stream_info, 'language'),
'stream_audio_language_code': helpers.get_xml_attr(audio_stream_info, 'languageCode'), 'stream_audio_language_code': helpers.get_xml_attr(audio_stream_info, 'languageCode'),
'stream_audio_decision': helpers.get_xml_attr(audio_stream_info, 'decision') or 'direct play' 'stream_audio_decision': helpers.get_xml_attr(audio_stream_info, 'decision') or 'direct play'
@ -1467,14 +1485,6 @@ class PmsConnect(object):
else: else:
bif_thumb = '' bif_thumb = ''
# Generate a combined transcode decision value
if transcode_details['video_decision'] == 'transcode' or transcode_details['audio_decision'] == 'transcode':
transcode_decision = 'transcode'
elif transcode_details['video_decision'] == 'copy' or transcode_details['audio_decision'] == 'copy':
transcode_decision = 'copy'
else:
transcode_decision = 'direct play'
stream_video_width = helpers.get_xml_attr(stream_media_info, 'width') stream_video_width = helpers.get_xml_attr(stream_media_info, 'width')
if helpers.cast_to_int(stream_video_width) >= 3840: if helpers.cast_to_int(stream_video_width) >= 3840:
stream_video_resolution = '4k' stream_video_resolution = '4k'
@ -1488,7 +1498,7 @@ class PmsConnect(object):
'stream_aspect_ratio': helpers.get_xml_attr(stream_media_info, 'aspectRatio'), 'stream_aspect_ratio': helpers.get_xml_attr(stream_media_info, 'aspectRatio'),
'stream_audio_codec': helpers.get_xml_attr(stream_media_info, 'audioCodec'), 'stream_audio_codec': helpers.get_xml_attr(stream_media_info, 'audioCodec'),
'stream_audio_channels': stream_audio_channels, 'stream_audio_channels': stream_audio_channels,
'stream_audio_channel_layout': common.AUDIO_CHANNELS.get(stream_audio_channels, stream_audio_channels), 'stream_audio_channel_layout': audio_details['stream_audio_channel_layout_'] or common.AUDIO_CHANNELS.get(stream_audio_channels, stream_audio_channels),
'stream_video_codec': helpers.get_xml_attr(stream_media_info, 'videoCodec'), 'stream_video_codec': helpers.get_xml_attr(stream_media_info, 'videoCodec'),
'stream_video_framerate': helpers.get_xml_attr(stream_media_info, 'videoFrameRate'), 'stream_video_framerate': helpers.get_xml_attr(stream_media_info, 'videoFrameRate'),
'stream_video_resolution': stream_video_resolution, 'stream_video_resolution': stream_video_resolution,
@ -1499,14 +1509,13 @@ class PmsConnect(object):
'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_profile': helpers.get_xml_attr(stream_media_info, 'title'),
'synced_version': synced_version,
'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_details else 0 'subtitles': 1 if subtitle_details else 0
} }
# Get the source media info # Get the source media info
media_type = helpers.get_xml_attr(session, 'type')
source_media_details = source_media_part_details = \ source_media_details = source_media_part_details = \
source_video_details = source_audio_details = source_subtitle_details = {} source_video_details = source_audio_details = source_subtitle_details = {}