Attempt to fix HW transcoding indicator

This commit is contained in:
JonnyWong16 2018-01-02 16:13:27 -08:00
parent 1aee3b6c8f
commit ad041a1691
8 changed files with 84 additions and 45 deletions

View file

@ -64,6 +64,7 @@ DOCUMENTATION :: END
from collections import defaultdict from collections import defaultdict
from urllib import quote from urllib import quote
from plexpy import helpers from plexpy import helpers
from plexpy.common import VIDEO_RESOLUTION_OVERRIDES, AUDIO_CODEC_OVERRIDES
import plexpy import plexpy
%> %>
<% data = defaultdict(lambda: 'Unknown', **session) %> <% data = defaultdict(lambda: 'Unknown', **session) %>
@ -214,17 +215,14 @@ DOCUMENTATION :: END
% if data['media_type'] in ('movie', 'episode', 'clip'): % if data['media_type'] in ('movie', 'episode', 'clip'):
% if data.get('stream_video_decision') == 'transcode': % if data.get('stream_video_decision') == 'transcode':
<% <%
hw_d = hw_e = '' hw_d = ' (HW)' if data['transcode_hw_decoding'] else ''
if data['transcode_hw_requested'] == 1 and data['transcode_hw_full_pipeline'] == 0: hw_e = ' (HW)' if data['transcode_hw_encoding'] else ''
hw_d = ' (HW)'
elif data['transcode_hw_requested'] == 1 and data['transcode_hw_full_pipeline'] == 1:
hw_d = hw_e = ' (HW)'
%> %>
Transcode (${data['video_codec'].upper()}${hw_d} ${plexpy.common.VIDEO_RESOLUTION_OVERRIDES.get(data['video_resolution'], data['video_resolution'])} &rarr; ${data['stream_video_codec'].upper()}${hw_e} ${plexpy.common.VIDEO_RESOLUTION_OVERRIDES.get(data['stream_video_resolution'], data['stream_video_resolution'])}) Transcode (${data['video_codec'].upper()}${hw_d} ${VIDEO_RESOLUTION_OVERRIDES.get(data['video_resolution'], data['video_resolution'])} &rarr; ${data['stream_video_codec'].upper()}${hw_e} ${VIDEO_RESOLUTION_OVERRIDES.get(data['stream_video_resolution'], data['stream_video_resolution'])})
% elif data.get('stream_video_decision') == 'copy': % elif data.get('stream_video_decision') == 'copy':
Direct Stream (${data['stream_video_codec'].upper()} ${plexpy.common.VIDEO_RESOLUTION_OVERRIDES.get(data['stream_video_resolution'], data['stream_video_resolution'])}) Direct Stream (${data['stream_video_codec'].upper()} ${VIDEO_RESOLUTION_OVERRIDES.get(data['stream_video_resolution'], data['stream_video_resolution'])})
% else: % else:
Direct Play (${data['video_codec'].upper()} ${plexpy.common.VIDEO_RESOLUTION_OVERRIDES.get(data['video_resolution'], data['video_resolution'])}) Direct Play (${data['video_codec'].upper()} ${VIDEO_RESOLUTION_OVERRIDES.get(data['video_resolution'], data['video_resolution'])})
% endif % endif
% elif data['media_type'] == 'photo': % elif data['media_type'] == 'photo':
Direct Play (${data['width']}x${data['height']}) Direct Play (${data['width']}x${data['height']})
@ -237,11 +235,11 @@ DOCUMENTATION :: END
<div class="sub-heading">Audio</div> <div class="sub-heading">Audio</div>
<div class="sub-value" id="audio_decision-${sk}"> <div class="sub-value" id="audio_decision-${sk}">
% if data.get('stream_audio_decision') == 'transcode': % if data.get('stream_audio_decision') == 'transcode':
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()}) Transcode (${AUDIO_CODEC_OVERRIDES.get(data['audio_codec'], data['audio_codec'].upper())} ${data['audio_channel_layout'].split('(')[0].capitalize()} &rarr; ${AUDIO_CODEC_OVERRIDES.get(data['stream_audio_codec'], data['stream_audio_codec'].upper())} ${data['stream_audio_channel_layout'].split('(')[0].capitalize()})
% elif data.get('stream_audio_decision') == 'copy': % elif data.get('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'].split('(')[0].capitalize()}) Direct Stream (${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].capitalize()}) Direct Play (${AUDIO_CODEC_OVERRIDES.get(data['audio_codec'], data['audio_codec'].upper())} ${data['audio_channel_layout'].split('(')[0].capitalize()})
% endif % endif
</div> </div>
</li> </li>

View file

@ -39,7 +39,7 @@ DOCUMENTATION :: END
% if data: % if data:
<% <%
import plexpy from plexpy.common import VIDEO_RESOLUTION_OVERRIDES, AUDIO_CODEC_OVERRIDES
%> %>
<div class="modal-dialog" role="document"> <div class="modal-dialog" role="document">
<div class="modal-content"> <div class="modal-content">
@ -85,8 +85,8 @@ DOCUMENTATION :: END
% if data['media_type'] != 'track': % if data['media_type'] != 'track':
<tr> <tr>
<td>Resolution</td> <td>Resolution</td>
<td>${plexpy.common.VIDEO_RESOLUTION_OVERRIDES.get(data['stream_video_resolution'], data['stream_video_resolution'])}</td> <td>${VIDEO_RESOLUTION_OVERRIDES.get(data['stream_video_resolution'], data['stream_video_resolution'])}</td>
<td>${plexpy.common.VIDEO_RESOLUTION_OVERRIDES.get(data['video_resolution'], data['video_resolution'])}</td> <td>${VIDEO_RESOLUTION_OVERRIDES.get(data['video_resolution'], data['video_resolution'])}</td>
</tr> </tr>
% endif % endif
<tr> <tr>
@ -124,8 +124,8 @@ DOCUMENTATION :: END
<tbody> <tbody>
<tr> <tr>
<td>Container</td> <td>Container</td>
<td>${data['stream_container']}</td> <td>${data['stream_container'].upper()}</td>
<td>${data['container']}</td> <td>${data['container'].upper()}</td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
@ -144,8 +144,8 @@ DOCUMENTATION :: END
<tbody> <tbody>
<tr> <tr>
<td>Codec</td> <td>Codec</td>
<td>${data['stream_video_codec']}</td> <td>${data['stream_video_codec'].upper()} ${'(HW)' if data['transcode_hw_encoding'] else ''}</td>
<td>${data['video_codec']}</td> <td>${data['video_codec'].upper()} ${'(HW)' if data['transcode_hw_decoding'] else ''}</td>
</tr> </tr>
<tr> <tr>
<td>Bitrate</td> <td>Bitrate</td>
@ -189,8 +189,8 @@ DOCUMENTATION :: END
<tbody> <tbody>
<tr> <tr>
<td>Codec</td> <td>Codec</td>
<td>${data['stream_audio_codec']}</td> <td>${AUDIO_CODEC_OVERRIDES.get(data['stream_audio_codec'], data['stream_audio_codec'].upper())}</td>
<td>${data['audio_codec']}</td> <td>${AUDIO_CODEC_OVERRIDES.get(data['audio_codec'], data['audio_codec'].upper())}</td>
</tr> </tr>
<tr> <tr>
<td>Bitrate</td> <td>Bitrate</td>
@ -219,8 +219,8 @@ DOCUMENTATION :: END
<tbody> <tbody>
<tr> <tr>
<td>Codec</td> <td>Codec</td>
<td>${data['stream_subtitle_codec']}</td> <td>${data['stream_subtitle_codec'].upper()}</td>
<td>${data['subtitle_codec']}</td> <td>${data['subtitle_codec'].upper()}</td>
</tr> </tr>
</tbody> </tbody>
</table> </table>

View file

@ -443,6 +443,7 @@ 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, '
'transcode_hw_decoding INTEGER, transcode_hw_encoding INTEGER, '
'optimized_version INTEGER, optimized_version_profile TEXT, optimized_version_title TEXT, ' 'optimized_version INTEGER, optimized_version_profile TEXT, optimized_version_title TEXT, '
'synced_version INTEGER, synced_version_profile 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, '
@ -468,8 +469,9 @@ def dbcheck():
'audio_bitrate INTEGER, audio_codec TEXT, audio_channels INTEGER, transcode_protocol TEXT, ' 'audio_bitrate INTEGER, audio_codec TEXT, audio_channels INTEGER, transcode_protocol TEXT, '
'transcode_container TEXT, transcode_video_codec TEXT, transcode_audio_codec TEXT, ' 'transcode_container TEXT, transcode_video_codec TEXT, transcode_audio_codec TEXT, '
'transcode_audio_channels INTEGER, transcode_width INTEGER, transcode_height INTEGER, ' 'transcode_audio_channels INTEGER, transcode_width INTEGER, transcode_height INTEGER, '
'transcode_hw_requested INTEGER, transcode_hw_full_pipeline INTEGER, transcode_hw_decode TEXT, ' 'transcode_hw_requested INTEGER, transcode_hw_full_pipeline INTEGER, '
'transcode_hw_decode_title TEXT, transcode_hw_encode TEXT, transcode_hw_encode_title TEXT, ' 'transcode_hw_decode TEXT, transcode_hw_decode_title TEXT, transcode_hw_decoding INTEGER, '
'transcode_hw_encode TEXT, transcode_hw_encode_title TEXT, transcode_hw_encoding INTEGER, '
'stream_container TEXT, stream_container_decision TEXT, stream_bitrate INTEGER, ' 'stream_container TEXT, stream_container_decision TEXT, stream_bitrate INTEGER, '
'stream_video_decision TEXT, stream_video_bitrate INTEGER, stream_video_codec TEXT, stream_video_codec_level TEXT, ' 'stream_video_decision TEXT, stream_video_bitrate INTEGER, stream_video_codec TEXT, stream_video_codec_level TEXT, '
'stream_video_bit_depth INTEGER, stream_video_height INTEGER, stream_video_width INTEGER, stream_video_resolution TEXT, ' 'stream_video_bit_depth INTEGER, stream_video_height INTEGER, stream_video_width INTEGER, stream_video_resolution TEXT, '
@ -917,6 +919,18 @@ def dbcheck():
'ALTER TABLE sessions ADD COLUMN optimized_version_title TEXT' 'ALTER TABLE sessions ADD COLUMN optimized_version_title TEXT'
) )
# Upgrade sessions table from earlier versions
try:
c_db.execute('SELECT transcode_hw_decoding FROM sessions')
except sqlite3.OperationalError:
logger.debug(u"Altering database. Updating database table sessions.")
c_db.execute(
'ALTER TABLE sessions ADD COLUMN transcode_hw_decoding INTEGER'
)
c_db.execute(
'ALTER TABLE sessions ADD COLUMN transcode_hw_encoding INTEGER'
)
# Upgrade session_history table from earlier versions # Upgrade session_history table from earlier versions
try: try:
c_db.execute('SELECT reference_id FROM session_history') c_db.execute('SELECT reference_id FROM session_history')
@ -1159,6 +1173,22 @@ def dbcheck():
'ALTER TABLE session_history_media_info ADD COLUMN optimized_version_title TEXT ' 'ALTER TABLE session_history_media_info ADD COLUMN optimized_version_title TEXT '
) )
# Upgrade session_history_media_info table from earlier versions
try:
c_db.execute('SELECT transcode_hw_decoding 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 transcode_hw_decoding INTEGER '
)
c_db.execute(
'ALTER TABLE session_history_media_info ADD COLUMN transcode_hw_encoding INTEGER '
)
c_db.execute(
'UPDATE session_history_media_info SET subtitle_codec = "" WHERE subtitle_codec IS NULL '
)
# 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

@ -436,12 +436,12 @@ def force_stop_stream(session_key):
ap.delete_session(session_key=session_key) ap.delete_session(session_key=session_key)
else: else:
sessions['write_attempts'] += 1 session['write_attempts'] += 1
if sessions['write_attempts'] < plexpy.CONFIG.SESSION_DB_WRITE_ATTEMPTS: if session['write_attempts'] < plexpy.CONFIG.SESSION_DB_WRITE_ATTEMPTS:
logger.warn(u"Tautulli ActivityHandler :: Failed to write stream with sessionKey %s ratingKey %s to the database. " \ logger.warn(u"Tautulli ActivityHandler :: Failed to write stream with sessionKey %s ratingKey %s to the database. " \
"Will try again in 30 seconds. Write attempt %s." "Will try again in 30 seconds. Write attempt %s."
% (sessions['session_key'], sessions['rating_key'], str(sessions['write_attempts']))) % (session['session_key'], session['rating_key'], str(session['write_attempts'])))
ap.increment_write_attempts(session_key=session_key) ap.increment_write_attempts(session_key=session_key)
# Reschedule for 30 seconds later # Reschedule for 30 seconds later
@ -451,9 +451,9 @@ def force_stop_stream(session_key):
else: else:
logger.warn(u"Tautulli Monitor :: Failed to write stream with sessionKey %s ratingKey %s to the database. " \ logger.warn(u"Tautulli Monitor :: Failed to write stream with sessionKey %s ratingKey %s to the database. " \
"Removing session from the database. Write attempt %s." "Removing session from the database. Write attempt %s."
% (sessions['session_key'], sessions['rating_key'], str(sessions['write_attempts']))) % (session['session_key'], session['rating_key'], str(session['write_attempts'])))
logger.info(u"Tautulli Monitor :: Removing stale stream with sessionKey %s ratingKey %s from session queue" logger.info(u"Tautulli Monitor :: Removing stale stream with sessionKey %s ratingKey %s from session queue"
% (sessions['session_key'], sessions['rating_key'])) % (session['session_key'], session['rating_key']))
ap.delete_session(session_key=session_key) ap.delete_session(session_key=session_key)

View file

@ -58,7 +58,7 @@ class ActivityProcessor(object):
'grandparent_thumb': session.get('grandparent_thumb', ''), 'grandparent_thumb': session.get('grandparent_thumb', ''),
'year': session.get('year', ''), 'year': session.get('year', ''),
'friendly_name': session.get('friendly_name', ''), 'friendly_name': session.get('friendly_name', ''),
#'ip_address': session.get('ip_address', ''), 'ip_address': session.get('ip_address', ''),
'player': session.get('player', ''), 'player': session.get('player', ''),
'platform': session.get('platform', ''), 'platform': session.get('platform', ''),
'parent_rating_key': session.get('parent_rating_key', ''), 'parent_rating_key': session.get('parent_rating_key', ''),
@ -90,6 +90,8 @@ 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', ''),
'transcode_hw_decoding': session.get('transcode_hw_decoding', ''),
'transcode_hw_encoding': session.get('transcode_hw_encoding', ''),
'synced_version': session.get('synced_version', ''), 'synced_version': session.get('synced_version', ''),
'synced_version_profile': session.get('synced_version_profile', ''), 'synced_version_profile': session.get('synced_version_profile', ''),
'optimized_version': session.get('optimized_version', ''), 'optimized_version': session.get('optimized_version', ''),
@ -117,10 +119,6 @@ class ActivityProcessor(object):
'stopped': int(time.time()) 'stopped': int(time.time())
} }
# Add ip_address back into values
if session['ip_address']:
values.update({'ip_address': session.get('ip_address', 'N/A')})
keys = {'session_key': session.get('session_key', ''), keys = {'session_key': session.get('session_key', ''),
'rating_key': session.get('rating_key', '')} 'rating_key': session.get('rating_key', '')}
@ -129,7 +127,6 @@ class ActivityProcessor(object):
if result == 'insert': if result == 'insert':
# Check if any notification agents have notifications enabled # Check if any notification agents have notifications enabled
if notify: if notify:
values.update({'ip_address': session.get('ip_address', 'N/A')})
plexpy.NOTIFY_QUEUE.put({'stream_data': values, 'notify_action': 'on_play'}) plexpy.NOTIFY_QUEUE.put({'stream_data': values, 'notify_action': 'on_play'})
# If it's our first write then time stamp it. # If it's our first write then time stamp it.
@ -324,6 +321,7 @@ class ActivityProcessor(object):
'audio_codec': session['audio_codec'], 'audio_codec': session['audio_codec'],
'audio_bitrate': session['audio_bitrate'], 'audio_bitrate': session['audio_bitrate'],
'audio_channels': session['audio_channels'], 'audio_channels': session['audio_channels'],
'subtitle_codec': session['subtitle_codec'],
'transcode_protocol': session['transcode_protocol'], 'transcode_protocol': session['transcode_protocol'],
'transcode_container': session['transcode_container'], 'transcode_container': session['transcode_container'],
'transcode_video_codec': session['transcode_video_codec'], 'transcode_video_codec': session['transcode_video_codec'],
@ -333,9 +331,11 @@ class ActivityProcessor(object):
'transcode_height': session['transcode_height'], 'transcode_height': session['transcode_height'],
'transcode_hw_requested': session['transcode_hw_requested'], 'transcode_hw_requested': session['transcode_hw_requested'],
'transcode_hw_full_pipeline': session['transcode_hw_full_pipeline'], 'transcode_hw_full_pipeline': session['transcode_hw_full_pipeline'],
'transcode_hw_decoding': session['transcode_hw_decoding'],
'transcode_hw_decode': session['transcode_hw_decode'], 'transcode_hw_decode': session['transcode_hw_decode'],
'transcode_hw_encode': session['transcode_hw_encode'],
'transcode_hw_decode_title': session['transcode_hw_decode_title'], 'transcode_hw_decode_title': session['transcode_hw_decode_title'],
'transcode_hw_encoding': session['transcode_hw_encoding'],
'transcode_hw_encode': session['transcode_hw_encode'],
'transcode_hw_encode_title': session['transcode_hw_encode_title'], 'transcode_hw_encode_title': session['transcode_hw_encode_title'],
'stream_container': session['stream_container'], 'stream_container': session['stream_container'],
'stream_container_decision': session['stream_container_decision'], 'stream_container_decision': session['stream_container_decision'],

View file

@ -135,6 +135,9 @@ AUDIO_QUALITY_PROFILES = {512: '512 kbps',
} }
AUDIO_QUALITY_PROFILES = OrderedDict(sorted(AUDIO_QUALITY_PROFILES.items(), key=lambda k: k[0], reverse=True)) AUDIO_QUALITY_PROFILES = OrderedDict(sorted(AUDIO_QUALITY_PROFILES.items(), key=lambda k: k[0], reverse=True))
HW_DECODERS = ['dxva2', 'videotoolbox', 'mediacodecndk', 'vaapi']
HW_ENCODERS = ['qsv', 'nvenc', 'mf', 'videotoolbox', 'mediacodecndk', 'vaapi', 'nvenc']
SCHEDULER_LIST = ['Check GitHub for updates', SCHEDULER_LIST = ['Check GitHub for updates',
'Check for active sessions', 'Check for active sessions',
'Check for recently added items', 'Check for recently added items',

View file

@ -882,6 +882,7 @@ class DataFactory(object):
'stream_video_framerate, ' \ 'stream_video_framerate, ' \
'stream_audio_decision, stream_audio_codec, stream_audio_bitrate, stream_audio_channels, ' \ 'stream_audio_decision, stream_audio_codec, stream_audio_bitrate, stream_audio_channels, ' \
'subtitles, stream_subtitle_decision, stream_subtitle_codec, ' \ 'subtitles, stream_subtitle_decision, stream_subtitle_codec, ' \
'transcode_hw_decoding, transcode_hw_encoding, ' \
'session_history_metadata.media_type, title, grandparent_title ' \ 'session_history_metadata.media_type, title, grandparent_title ' \
'FROM session_history_media_info ' \ 'FROM session_history_media_info ' \
'JOIN session_history ON session_history_media_info.id = session_history.id ' \ 'JOIN session_history ON session_history_media_info.id = session_history.id ' \
@ -899,6 +900,7 @@ class DataFactory(object):
'stream_video_framerate, ' \ 'stream_video_framerate, ' \
'stream_audio_decision, stream_audio_codec, stream_audio_bitrate, stream_audio_channels, ' \ 'stream_audio_decision, stream_audio_codec, stream_audio_bitrate, stream_audio_channels, ' \
'subtitles, stream_subtitle_decision, stream_subtitle_codec, ' \ 'subtitles, stream_subtitle_decision, stream_subtitle_codec, ' \
'transcode_hw_decoding, transcode_hw_encoding, ' \
'media_type, title, grandparent_title ' \ 'media_type, title, grandparent_title ' \
'FROM sessions ' \ 'FROM sessions ' \
'WHERE session_key = ? %s' % user_cond 'WHERE session_key = ? %s' % user_cond
@ -945,6 +947,8 @@ class DataFactory(object):
'subtitles': item['subtitles'], 'subtitles': item['subtitles'],
'stream_subtitle_decision': item['stream_subtitle_decision'], 'stream_subtitle_decision': item['stream_subtitle_decision'],
'stream_subtitle_codec': item['stream_subtitle_codec'], 'stream_subtitle_codec': item['stream_subtitle_codec'],
'transcode_hw_decoding': item['transcode_hw_decoding'],
'transcode_hw_encoding': item['transcode_hw_encoding'],
'media_type': item['media_type'], 'media_type': item['media_type'],
'title': item['title'], 'title': item['title'],
'grandparent_title': item['grandparent_title'] 'grandparent_title': item['grandparent_title']

View file

@ -1102,7 +1102,7 @@ class PmsConnect(object):
'subtitle_codec': helpers.get_xml_attr(stream, 'codec'), 'subtitle_codec': helpers.get_xml_attr(stream, 'codec'),
'subtitle_container': helpers.get_xml_attr(stream, 'container'), 'subtitle_container': helpers.get_xml_attr(stream, 'container'),
'subtitle_format': helpers.get_xml_attr(stream, 'format'), 'subtitle_format': helpers.get_xml_attr(stream, 'format'),
'subtitle_forced': 1 if helpers.get_xml_attr(stream, 'forced') == '1' else 0, 'subtitle_forced': int(helpers.get_xml_attr(stream, 'forced') == '1'),
'subtitle_location': 'external' if helpers.get_xml_attr(stream, 'key') else 'embedded', 'subtitle_location': 'external' if helpers.get_xml_attr(stream, 'key') else 'embedded',
'subtitle_language': helpers.get_xml_attr(stream, 'language'), 'subtitle_language': helpers.get_xml_attr(stream, 'language'),
'subtitle_language_code': helpers.get_xml_attr(stream, 'languageCode') 'subtitle_language_code': helpers.get_xml_attr(stream, 'languageCode')
@ -1111,7 +1111,7 @@ class PmsConnect(object):
parts.append({'id': helpers.get_xml_attr(part, 'id'), parts.append({'id': helpers.get_xml_attr(part, 'id'),
'file': helpers.get_xml_attr(part, 'file'), 'file': helpers.get_xml_attr(part, 'file'),
'file_size': helpers.get_xml_attr(part, 'size'), 'file_size': helpers.get_xml_attr(part, 'size'),
'indexes': 1 if helpers.get_xml_attr(part, 'indexes') == 'sd' else 0, 'indexes': int(helpers.get_xml_attr(part, 'indexes') == 'sd'),
'streams': streams 'streams': streams
}) })
@ -1131,7 +1131,7 @@ class PmsConnect(object):
'audio_channels': audio_channels, 'audio_channels': audio_channels,
'audio_channel_layout': common.AUDIO_CHANNELS.get(audio_channels, audio_channels), 'audio_channel_layout': common.AUDIO_CHANNELS.get(audio_channels, audio_channels),
'audio_profile': helpers.get_xml_attr(media, 'audioProfile'), 'audio_profile': helpers.get_xml_attr(media, 'audioProfile'),
'optimized_version': 1 if helpers.get_xml_attr(media, 'proxyType') == '42' else 0, 'optimized_version': int(helpers.get_xml_attr(media, 'proxyType') == '42'),
'parts': parts 'parts': parts
}) })
@ -1352,7 +1352,7 @@ class PmsConnect(object):
transcode_speed = helpers.get_xml_attr(transcode_info, 'speed') transcode_speed = helpers.get_xml_attr(transcode_info, 'speed')
transcode_details = {'transcode_key': helpers.get_xml_attr(transcode_info, 'key'), transcode_details = {'transcode_key': helpers.get_xml_attr(transcode_info, 'key'),
'transcode_throttled': 1 if helpers.get_xml_attr(transcode_info, 'throttled') == '1' else 0, 'transcode_throttled': int(helpers.get_xml_attr(transcode_info, 'throttled') == '1'),
'transcode_progress': int(round(helpers.cast_to_float(transcode_progress), 0)), 'transcode_progress': int(round(helpers.cast_to_float(transcode_progress), 0)),
'transcode_speed': str(round(helpers.cast_to_float(transcode_speed), 1)), 'transcode_speed': str(round(helpers.cast_to_float(transcode_speed), 1)),
'transcode_audio_channels': helpers.get_xml_attr(transcode_info, 'audioChannels'), 'transcode_audio_channels': helpers.get_xml_attr(transcode_info, 'audioChannels'),
@ -1362,12 +1362,12 @@ class PmsConnect(object):
'transcode_height': helpers.get_xml_attr(transcode_info, 'height'), # Blank but keep backwards compatibility 'transcode_height': helpers.get_xml_attr(transcode_info, 'height'), # Blank but keep backwards compatibility
'transcode_container': helpers.get_xml_attr(transcode_info, 'container'), 'transcode_container': helpers.get_xml_attr(transcode_info, 'container'),
'transcode_protocol': helpers.get_xml_attr(transcode_info, 'protocol'), 'transcode_protocol': helpers.get_xml_attr(transcode_info, 'protocol'),
'transcode_hw_requested': 1 if helpers.get_xml_attr(transcode_info, 'transcodeHwRequested') == '1' else 0, 'transcode_hw_requested': int(helpers.get_xml_attr(transcode_info, 'transcodeHwRequested') == '1'),
'transcode_hw_decode': helpers.get_xml_attr(transcode_info, 'transcodeHwDecoding'), 'transcode_hw_decode': helpers.get_xml_attr(transcode_info, 'transcodeHwDecoding'),
'transcode_hw_decode_title': helpers.get_xml_attr(transcode_info, 'transcodeHwDecodingTitle'), 'transcode_hw_decode_title': helpers.get_xml_attr(transcode_info, 'transcodeHwDecodingTitle'),
'transcode_hw_encode': helpers.get_xml_attr(transcode_info, 'transcodeHwEncoding'), 'transcode_hw_encode': helpers.get_xml_attr(transcode_info, 'transcodeHwEncoding'),
'transcode_hw_encode_title': helpers.get_xml_attr(transcode_info, 'transcodeHwEncodingTitle'), 'transcode_hw_encode_title': helpers.get_xml_attr(transcode_info, 'transcodeHwEncodingTitle'),
'transcode_hw_full_pipeline': 1 if helpers.get_xml_attr(transcode_info, 'transcodeHwFullPipeline') == '1' else 0, 'transcode_hw_full_pipeline': int(helpers.get_xml_attr(transcode_info, 'transcodeHwFullPipeline') == '1'),
'audio_decision': helpers.get_xml_attr(transcode_info, 'audioDecision'), 'audio_decision': helpers.get_xml_attr(transcode_info, 'audioDecision'),
'video_decision': helpers.get_xml_attr(transcode_info, 'videoDecision'), 'video_decision': helpers.get_xml_attr(transcode_info, 'videoDecision'),
'subtitle_decision': helpers.get_xml_attr(transcode_info, 'subtitleDecision'), 'subtitle_decision': helpers.get_xml_attr(transcode_info, 'subtitleDecision'),
@ -1397,6 +1397,10 @@ class PmsConnect(object):
'throttled': '0' # Keep for backwards compatibility 'throttled': '0' # Keep for backwards compatibility
} }
# Check HW decoding/encoding
transcode_details['transcode_hw_decoding'] = int(transcode_details['transcode_hw_decode'].lower() in common.HW_DECODERS)
transcode_details['transcode_hw_encoding'] = int(transcode_details['transcode_hw_encode'].lower() in common.HW_ENCODERS)
# Generate a combined transcode decision value # Generate a combined transcode decision value
if transcode_details['video_decision'] == 'transcode' or transcode_details['audio_decision'] == 'transcode': if transcode_details['video_decision'] == 'transcode' or transcode_details['audio_decision'] == 'transcode':
transcode_decision = 'transcode' transcode_decision = 'transcode'
@ -1489,7 +1493,7 @@ class PmsConnect(object):
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'),
'stream_subtitle_forced': 1 if helpers.get_xml_attr(subtitle_stream_info, 'forced') == '1' else 0, 'stream_subtitle_forced': int(helpers.get_xml_attr(subtitle_stream_info, 'forced') == '1'),
'stream_subtitle_location': helpers.get_xml_attr(subtitle_stream_info, 'location'), 'stream_subtitle_location': helpers.get_xml_attr(subtitle_stream_info, 'location'),
'stream_subtitle_language': helpers.get_xml_attr(subtitle_stream_info, 'language'), 'stream_subtitle_language': helpers.get_xml_attr(subtitle_stream_info, 'language'),
'stream_subtitle_language_code': helpers.get_xml_attr(subtitle_stream_info, 'languageCode'), 'stream_subtitle_language_code': helpers.get_xml_attr(subtitle_stream_info, 'languageCode'),
@ -1537,10 +1541,10 @@ class PmsConnect(object):
'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': 'direct play' if sync_id else 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': int(helpers.get_xml_attr(stream_media_info, 'proxyType') == '42'),
'optimized_version_title': helpers.get_xml_attr(stream_media_info, 'title'), 'optimized_version_title': helpers.get_xml_attr(stream_media_info, 'title'),
'synced_version': 1 if sync_id else 0, 'synced_version': 1 if sync_id else 0,
'indexes': 1 if indexes == 'sd' else 0, 'indexes': int(indexes == 'sd'),
'bif_thumb': bif_thumb, 'bif_thumb': bif_thumb,
'subtitles': 1 if subtitle_id and subtitle_selected else 0 'subtitles': 1 if subtitle_id and subtitle_selected else 0
} }