Skip to content

Commit 00458f9

Browse files
Implement automatic Widevine download methods
1 parent 671ddf9 commit 00458f9

File tree

4 files changed

+107
-4
lines changed

4 files changed

+107
-4
lines changed

addon.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
provider-name="emilsvennesson">
66
<requires>
77
<import addon="xbmc.python" version="2.25.0"/>
8+
<import addon="script.module.requests" version="2.9.1"/>
89
</requires>
910
<extension library="lib" point="xbmc.python.module"/>
1011
<extension point="xbmc.addon.metadata">

lib/config.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
}
3333
}
3434

35-
WIDEVINE_CDM_EXTENSIONS = ['.so', '.dll', '.dylib']
35+
WIDEVINE_CDM_EXTENSIONS = ('.so', '.dll', '.dylib')
3636

3737
WIDEVINE_SUPPORTED_ARCHS = ['x86_64', 'x86', 'aarch64', 'aarch64_be', 'armv7', 'armv8', 'arm64']
3838

lib/inputstreamhelper.py

Lines changed: 87 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
import json
55
from distutils.version import LooseVersion
66

7+
import requests
8+
79
import config
810
import xbmc
911
import xbmcaddon
@@ -63,7 +65,7 @@ def _has_widevine_cdm(self):
6365
self._log('Found Widevine binary at {0}'.format(os.path.join(self._cdm_path(), filename)))
6466
return True
6567

66-
self.log('Widevine is not installed.')
68+
self._log('Widevine is not installed.')
6769
return False
6870

6971
def _json_rpc_request(self, payload):
@@ -73,6 +75,46 @@ def _json_rpc_request(self, payload):
7375

7476
return json.loads(response)
7577

78+
def _http_request(self, url, download=False, download_path=None):
79+
busy_dialog = xbmcgui.DialogBusy()
80+
dialog = xbmcgui.Dialog()
81+
filename = url.split('/')[-1]
82+
self._log('Request URL: {0}'.format(url))
83+
try:
84+
busy_dialog.create()
85+
req = requests.get(url, stream=download, verify=False)
86+
self._log('Response code: {0}'.format(req.status_code))
87+
if not download:
88+
self._log('Response: {0}'.format(req.content))
89+
req.raise_for_status()
90+
except requests.exceptions.HTTPError:
91+
busy_dialog.close()
92+
dialog.ok(self._language(30004), self._language(30013).format(filename))
93+
return False
94+
95+
busy_dialog.close()
96+
if download:
97+
total_length = float(req.headers.get('content-length'))
98+
progress_dialog = xbmcgui.DialogProgress()
99+
progress_dialog.create(self._language(30014), self._language(30015).format(filename))
100+
101+
with open(download_path, 'wb') as f:
102+
dl = 0
103+
for chunk in req.iter_content(chunk_size=1024):
104+
f.write(chunk)
105+
dl += len(chunk)
106+
percent = int(dl * 100/ total_length)
107+
if progress_dialog.iscanceled():
108+
progress_dialog.close()
109+
req.close()
110+
return False
111+
progress_dialog.update(percent)
112+
progress_dialog.close()
113+
return True
114+
else:
115+
return req.content
116+
117+
76118
def _has_inputstream(self):
77119
"""Checks if selected InputStream add-on is installed."""
78120
payload = {
@@ -145,6 +187,50 @@ def _supports_widevine(self):
145187

146188
return True
147189

190+
def _install_widevine_cdm(self):
191+
dialog = xbmcgui.Dialog()
192+
download_path = os.path.join(xbmc.translatePath('special://temp'), 'widevine_cdm.zip')
193+
cdm_platform = config.WIDEVINE_DOWNLOAD_MAP[self._arch][self._os]
194+
cdm_source = json.loads(self._http_request(config.WIDEVINE_CDM_SOURCE))['vendors']['gmp-widevinecdm']['platforms']
195+
cdm_zip_url = cdm_source[cdm_platform]['fileUrl']
196+
197+
downloaded = self._http_request(cdm_zip_url, download=True, download_path=download_path)
198+
if downloaded:
199+
if self._unzip_widevine_cdm(download_path):
200+
dialog.ok(self._language(30001), self._language(30003))
201+
else:
202+
return False
203+
else:
204+
return False
205+
206+
def _unzip_widevine_cdm(self, zip_path):
207+
busy_dialog = xbmcgui.DialogBusy()
208+
zip_obj = zipfile.ZipFile(zip_path)
209+
busy_dialog.create()
210+
for filename in zip_obj.namelist():
211+
if filename.endswith(config.WIDEVINE_CDM_EXTENSIONS):
212+
zip_obj.extract(filename, self._cdm_path())
213+
busy_dialog.close()
214+
return True
215+
216+
busy_dialog.close()
217+
dialog = xbmcgui.Dialog()
218+
dialog.ok(self._language(30004), self._language(30016))
219+
return False
220+
221+
def check_for_widevine(self):
222+
if not self._supports_widevine():
223+
return False
224+
if not self._has_widevine_cdm():
225+
dialog = xbmcgui.Dialog()
226+
ok = dialog.yesno(self._language(30001), self._language(30002))
227+
if ok:
228+
return self._install_widevine_cdm()
229+
else:
230+
return False
231+
else:
232+
return True
233+
148234
def check_for_inputstream(self):
149235
"""Ensures that selected InputStream add-on is installed and enabled.
150236
Displays a select dialog if add-on is installed but not enabled."""

resources/language/resource.language.en_gb/strings.po

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,15 @@ msgid "You do not have Widevine DRM installed. This is required for playback of
2222
msgstr ""
2323

2424
msgctxt "#30003"
25-
msgid "Widevine DRM was successfully installed!"
25+
msgid "[B]Widevine DRM[/B] was successfully installed!"
2626
msgstr ""
2727

2828
msgctxt "#30004"
2929
msgid "Error"
3030
msgstr ""
3131

3232
msgctxt "#30005"
33-
msgid "An error occurred while installing Widevine DRM. Please enable debug logging and file a bug report on [B]github.com/emilsvennesson/script.module.inputstreamhelper[/B]."
33+
msgid "An error occurred while installing Widevine DRM. Please enable debug logging and file a bug report at:[CR][CR]github.com/emilsvennesson/script.module.inputstreamhelper"
3434
msgstr ""
3535

3636
msgctxt "#30006"
@@ -60,3 +60,19 @@ msgstr ""
6060
msgctxt "#30012"
6161
msgid "The Windows Store version of Kodi does not support Widevine DRM. Please use the installer from kodi.tv instead."
6262
msgstr ""
63+
64+
msgctxt "#30013"
65+
msgid "Failed to retrieve [B]{0}[/B]."
66+
msgstr ""
67+
68+
msgctxt "#30014"
69+
msgid "Download in progress..."
70+
msgstr ""
71+
72+
msgctxt "#30015"
73+
msgid "Downloading [B]{0}[/B]..."
74+
msgstr ""
75+
76+
msgctxt "#30016"
77+
msgid "Failed to extract Widevine CDM from zip file."
78+
msgstr ""

0 commit comments

Comments
 (0)