## Netflix Plugin for Kodi 18
-###Prerequisites
-----------------
+Disclaimer
+-------------
+This plugin is not officially commisioned/supported by Netflix.
+The trademark "Netflix" is registered by "Netflix, Inc."
+
+Prerequisites
+-------------
- Kodi 18 [agile build](https://github.com/FernetMenta/kodi-agile)
- Libwidevine 1.4.8.962 (A german description how to get/install it, can be found [here](https://www.kodinerds.net/index.php/Thread/51486-Kodi-17-Inputstream-HowTo-AddOns-f%C3%BCr-Kodi-17-ab-Beta-6-aktuelle-Git-builds-Updat/))
- Inputstream.adaptive [agile branch build](https://github.com/liberty-developer/inputstream.adaptive/tree/agile)
-###Functionality
-----------------
+FAQ
+---
+
+- [Does it work with Kodi 17](https://github.com/asciidisco/plugin.video.netflix/issues/25)
+- [Does it work on a RPI](https://github.com/asciidisco/plugin.video.netflix/issues/28)
+- [Which video resolutions are supported](https://github.com/asciidisco/plugin.video.netflix/issues/27)
+
+Functionality
+-------------
- Multiple profiles
- Search Netflix (incl. suggestions)
- Netflix categories, recommendations, "my list" & continue watching
- Add & remove to/from "my list"
- Export of complete shows & movies in local database (custom library folder can be configured, by default the .strm files are stored in `userdata/addon_data/plugin.video.netflix` )
-###ToDo
-----------------
+ToDo
+----
> Note: Those Todos are considered enhancements, they´re not issues, nor they prevent the usage of the plugin for everyday business
- [ ] If a new user has been created, they need to select their movie/show preferences to actually get started, we could provide the same mechanisms in Kodi
- [ ] Enable aggressive fetching of data in background (maybe using Futures), like the Netflix website does, to enhance the speed and the user experience when browsing the frontend
-###Something doesn't work
--------------------------
+Something doesn't work
+----------------------
If something doesn't work for you, please:
- Libwedevine version
- A Kodi debug log that represents your issue
-###Licence
------------------
+Licence
+-------
Licenced under The MIT License.
Includes [pyjsparser](https://github.com/PiotrDabkowski/pyjsparser) by [Piotr Dabkowski](https://github.com/PiotrDabkowski)
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
-<addon id="plugin.video.netflix" name="Netflix" version="0.11.8" provider-name="libdev + jojo + asciidisco">
+<addon id="plugin.video.netflix" name="Netflix" version="0.11.9" provider-name="libdev + jojo + asciidisco">
<requires>
<import addon="xbmc.python" version="2.24.0"/>
<import addon="script.module.beautifulsoup4" version="4.3.2"/>
# Kodi Media Center language file
# Addon Name: Netflix
# Addon id: plugin.video.netflix
-# Addon version: 0.11.8
+# Addon version: 0.11.9
# Addon Provider: libdev + jojo + asciidisco
msgid ""
msgstr ""
# Kodi Media Center language file
# Addon Name: Netflix
# Addon id: plugin.video.netflix
-# Addon version: 0.11.8
+# Addon version: 0.11.9
# Addon Provider: libdev + jojo + asciidisco
msgid ""
msgstr ""
# Kodi Media Center language file
# Addon Name: Netflix
# Addon id: plugin.video.netflix
-# Addon version: 0.11.8
+# Addon version: 0.11.9
# Addon Provider: libdev + jojo + asciidisco
msgid ""
msgstr ""
# Kodi Media Center language file
# Addon Name: Netflix
# Addon id: plugin.video.netflix
-# Addon version: 0.11.8
+# Addon version: 0.11.9
# Addon Provider: libdev + jojo + asciidisco
msgid ""
msgstr ""
import pprint
import random
from StringIO import StringIO
+
+from datetime import datetime
import requests
import zlib
# Audio
'heaac-2-dash',
+
+ #subtiltes
'dfxp-ls-sdh',
- 'simplesdh',
- 'nflx-cmisc',
+ #'simplesdh',
+ #'nflx-cmisc',
+
+ #unkown
'BIF240',
'BIF320'
],
segment_base = ET.SubElement(rep, 'SegmentBase', indexRange="0-"+str(init_length), indexRangeExact="true")
ET.SubElement(segment_base, 'Initialization', range='0-'+str(init_length))
+ # Multiple Adaption Sets for subtiles
+ for text_track in manifest['textTracks']:
+ if 'downloadables' not in text_track or text_track['downloadables'] is None:
+ continue
+ subtiles_adaption_set = ET.SubElement(period, 'AdaptationSet',
+ lang=text_track['bcp47'],
+ codecs='stpp',
+ contentType='text',
+ mimeType='application/ttml+xml')
+ for downloadable in text_track['downloadables']:
+ rep = ET.SubElement(subtiles_adaption_set, 'Representation',
+ nflxProfile=downloadable['contentProfile']
+ )
+ ET.SubElement(rep, 'BaseURL').text = self.__get_base_url(downloadable['urls'])
+
xml = ET.tostring(root, encoding='utf-8', method='xml')
xml = xml.replace('\n', '').replace('\r', '')
def __load_msl_data(self):
msl_data = json.JSONDecoder().decode(self.load_file(self.kodi_helper.msl_data_path, 'msl_data.json'))
+ #Check expire date of the token
+ master_token = json.JSONDecoder().decode(base64.standard_b64decode(msl_data['tokens']['mastertoken']['tokendata']))
+ valid_until = datetime.utcfromtimestamp(int(master_token['expiration']))
+ present = datetime.now()
+ difference = valid_until - present
+ difference = difference.total_seconds() / 60 / 60
+ # If token expires in less then 10 hours or is expires renew it
+ if difference < 10:
+ self.__load_rsa_keys()
+ self.__perform_key_handshake()
+ return
+
self.__set_master_token(msl_data['tokens']['mastertoken'])
self.encryption_key = base64.standard_b64decode(msl_data['encryption_key'])
self.sign_key = base64.standard_b64decode(msl_data['sign_key'])