Skip to content

Commit

Permalink
Simplify drm
Browse files Browse the repository at this point in the history
  • Loading branch information
mediaminister committed Oct 26, 2023
1 parent 7202ad2 commit 700a308
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 55 deletions.
5 changes: 3 additions & 2 deletions resources/lib/helperobjects.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,12 @@ def __init__(self, client, media_api_url, video_id, publication_id, is_live_stre
class StreamURLS:
"""This helper object holds all information to be used when playing streams"""

def __init__(self, stream_url, subtitle_url=None, license_key=None, use_inputstream_adaptive=False):
def __init__(self, stream_url, subtitle_url=None, license_url=None, license_headers=None, use_inputstream_adaptive=False):
"""The constructor for the StreamURLS class"""
self.stream_url = stream_url
self.subtitle_url = subtitle_url
self.license_key = license_key
self.license_url = license_url
self.license_headers = license_headers
self.use_inputstream_adaptive = use_inputstream_adaptive
self.video_id = None

Expand Down
24 changes: 21 additions & 3 deletions resources/lib/kodiutils.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,11 @@
from utils import from_unicode, to_unicode

try: # Python 3
from urllib.parse import quote, urlencode
from urllib.request import HTTPErrorProcessor
except ImportError: # Python 2
from urllib2 import HTTPErrorProcessor
from urllib import urlencode
from urllib2 import quote, HTTPErrorProcessor

ADDON = Addon()
DEFAULT_CACHE_DIR = 'cache'
Expand Down Expand Up @@ -309,12 +311,13 @@ def play(stream, video=None):
play_item.setProperty('inputstream.adaptive.manifest_type', 'hls')
play_item.setMimeType('application/vnd.apple.mpegurl')

if stream.license_key is not None:
if stream.license_url is not None:
import inputstreamhelper
is_helper = inputstreamhelper.Helper('mpd', drm='com.widevine.alpha')
if is_helper.check_inputstream():
play_item.setProperty('inputstream.adaptive.license_type', 'com.widevine.alpha')
play_item.setProperty('inputstream.adaptive.license_key', stream.license_key)
license_key = generate_ia_license_key(stream.license_url, license_headers=stream.license_headers)
play_item.setProperty('inputstream.adaptive.license_key', license_key)

subtitles_visible = get_setting_bool('showsubtitles', default=True)
# Separate subtitle url for hls-streams
Expand All @@ -339,6 +342,21 @@ def get_search_string(search_string=None):
return search_string


def generate_ia_license_key(license_url, license_headers='', postdata_type='R', postdata_value='', response_type=''):
"""Generates an InputStream Adaptive license_key"""
if license_headers:
license_headers = urlencode(license_headers)

if postdata_type in ('A', 'R', 'B'):
postdata_value = postdata_type + '{SSM}'
elif postdata_type == 'D':
if 'D{SSM}' not in postdata_value:
raise ValueError('Missing D{SSM} placeholder')
postdata_value = quote(postdata_value)

return '{}|{}|{}|{}'.format(license_url, license_headers, postdata_value, response_type)


def ok_dialog(heading='', message=''):
"""Show Kodi's OK dialog"""
from xbmcgui import Dialog
Expand Down
63 changes: 13 additions & 50 deletions resources/lib/streamservice.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,8 @@

try: # Python 3
from urllib.error import HTTPError
from urllib.parse import quote, urlencode
from urllib.parse import quote
except ImportError: # Python 2
from urllib import urlencode
from urllib2 import quote, HTTPError

from helperobjects import ApiData, StreamURLS
Expand Down Expand Up @@ -56,46 +55,6 @@ def _create_settings_dir():
if not exists(settingsdir):
mkdir(settingsdir)

@staticmethod
def _get_license_key(key_url, key_type='R', key_headers=None, key_value=None):
"""Generates a proper Widevine license key value
# A{SSM} -> not implemented
# R{SSM} -> raw format
# B{SSM} -> base64 format
# D{SSM} -> decimal format
The generic format for a LicenseKey is:
|<url>|<headers>|<key with placeholders|
The Widevine Decryption Key Identifier (KID) can be inserted via the placeholder {KID}
@type key_url: str
@param key_url: the URL where the license key can be obtained
@type key_type: str
@param key_type: the key type (A, R, B or D)
@type key_headers: dict
@param key_headers: A dictionary that contains the HTTP headers to pass
@type key_value: str
@param key_value: i
@return:
"""
header = ''
if key_headers:
header = urlencode(key_headers)

if key_type in ('A', 'R', 'B'):
key_value = key_type + '{SSM}'
elif key_type == 'D':
if 'D{SSM}' not in key_value:
raise ValueError('Missing D{SSM} placeholder')
key_value = quote(key_value)

return '{key_url}|{header}|{key_value}|'.format(key_url=key_url, header=header, key_value=key_value)

def _get_api_data(self, video):
"""Create api data object from video dictionary"""
api_data = None
Expand Down Expand Up @@ -261,15 +220,19 @@ def get_stream(self, video, roaming=False, api_data=None):
if protocol == 'mpeg_dash' and drm_stream:
log(2, 'Protocol: mpeg_dash drm')
if vudrm_token:
encryption_json = '{{"token":"{0}","drm_info":[D{{SSM}}],"kid":"{{KID}}"}}'.format(vudrm_token)
license_key = self._get_license_key(key_url=vualto_license_url,
key_type='D',
key_value=encryption_json,
key_headers={'Content-Type': 'text/plain;charset=UTF-8'})
stream = StreamURLS(
manifest_url,
license_url=vualto_license_url,
license_headers={'X-VUDRM-TOKEN': vudrm_token},
use_inputstream_adaptive=True
)
else:
license_key = self._get_license_key(key_url=self._UPLYNK_LICENSE_URL, key_type='R')

stream = StreamURLS(manifest_url, license_key=license_key, use_inputstream_adaptive=True)
stream = StreamURLS(
manifest_url,
license_url=self._UPLYNK_LICENSE_URL,
license_headers={},
use_inputstream_adaptive=True
)
elif protocol == 'mpeg_dash':
log(2, 'Protocol: mpeg_dash')
stream = StreamURLS(manifest_url, use_inputstream_adaptive=True)
Expand Down

0 comments on commit 700a308

Please sign in to comment.