'license': 'http://www.netflix.com/api/msl/NFCDCH-LX/cadmium/license'
}
- def __init__(self, email, password, kodi_helper):
+ def __init__(self, kodi_helper):
"""
The Constructor checks for already existing crypto Keys.
If they exist it will load the existing keys
"""
- self.email = email
- self.password = password
self.kodi_helper = kodi_helper
try:
os.mkdir(self.kodi_helper.msl_data_path)
'lookupType': 'PREPARE',
'viewableIds': [viewable_id],
'profiles': [
- 'playready-h264mpl30-dash',
- 'playready-h264mpl31-dash',
- 'playready-h264mpl40-dash',
+ "playready-h264bpl30-dash",
+ "playready-h264mpl30-dash",
+ "playready-h264mpl31-dash",
+ "playready-h264mpl40-dash",
+ # "hevc-main-L30-dash-cenc",
+ # "hevc-main-L31-dash-cenc",
+ # "hevc-main-L40-dash-cenc",
+ # "hevc-main-L41-dash-cenc",
+ # "hevc-main-L50-dash-cenc",
+ # "hevc-main-L51-dash-cenc",
+ # "hevc-main10-L30-dash-cenc",
+ # "hevc-main10-L31-dash-cenc",
+ # "hevc-main10-L40-dash-cenc",
+ # "hevc-main10-L41-dash-cenc",
+ # "hevc-main10-L50-dash-cenc",
+ # "hevc-main10-L51-dash-cenc",
+ # "hevc-main10-L30-dash-cenc-prk",
+ # "hevc-main10-L31-dash-cenc-prk",
+ # "hevc-main10-L40-dash-cenc-prk",
+ # "hevc-main10-L41-dash-cenc-prk",
+ # "hevc-main-L30-L31-dash-cenc-tl",
+ # "hevc-main-L31-L40-dash-cenc-tl",
+ # "hevc-main-L40-L41-dash-cenc-tl",
+ # "hevc-main-L50-L51-dash-cenc-tl",
+ # "hevc-main10-L30-L31-dash-cenc-tl",
+ # "hevc-main10-L31-L40-dash-cenc-tl",
+ # "hevc-main10-L40-L41-dash-cenc-tl",
+ # "hevc-main10-L50-L51-dash-cenc-tl",
+ # "hevc-dv-main10-L30-dash-cenc",
+ # "hevc-dv-main10-L31-dash-cenc",
+ # "hevc-dv-main10-L40-dash-cenc",
+ # "hevc-dv-main10-L41-dash-cenc",
+ # "hevc-dv-main10-L50-dash-cenc",
+ # "hevc-dv-main10-L51-dash-cenc",
+ # "hevc-dv5-main10-L30-dash-cenc-prk",
+ # "hevc-dv5-main10-L31-dash-cenc-prk",
+ # "hevc-dv5-main10-L40-dash-cenc-prk",
+ # "hevc-dv5-main10-L41-dash-cenc-prk",
+ # "hevc-dv5-main10-L50-dash-cenc-prk",
+ # "hevc-dv5-main10-L51-dash-cenc-prk",
+ # "hevc-hdr-main10-L30-dash-cenc",
+ # "hevc-hdr-main10-L31-dash-cenc",
+ # "hevc-hdr-main10-L40-dash-cenc",
+ # "hevc-hdr-main10-L41-dash-cenc",
+ # "hevc-hdr-main10-L50-dash-cenc",
+ # "hevc-hdr-main10-L51-dash-cenc",
+ # "hevc-hdr-main10-L30-dash-cenc-prk",
+ # "hevc-hdr-main10-L31-dash-cenc-prk",
+ # "hevc-hdr-main10-L40-dash-cenc-prk",
+ # "hevc-hdr-main10-L41-dash-cenc-prk",
+ # "hevc-hdr-main10-L50-dash-cenc-prk",
+ # "hevc-hdr-main10-L51-dash-cenc-prk"
+
+ # 'playready-h264mpl30-dash',
+ #'playready-h264mpl31-dash',
+ #'playready-h264mpl40-dash',
+ #'hevc-main10-L41-dash-cenc',
+ #'hevc-main10-L50-dash-cenc',
+ #'hevc-main10-L51-dash-cenc',
+
+
+
+ # Audio
'heaac-2-dash',
'dfxp-ls-sdh',
'simplesdh',
'clientVersion': '4.0004.899.011',
'uiVersion': 'akira'
}
+
+ # Check if dolby sound is enabled and add to profles
+ if self.kodi_helper.get_dolby_setting():
+ manifest_request_data['profiles'].append('ddplus-2.0-dash')
+ manifest_request_data['profiles'].append('ddplus-5.1-dash')
+
request_data = self.__generate_msl_request_data(manifest_request_data)
resp = self.session.post(self.endpoints['manifest'], request_data)
pssh = manifest['psshb64'][0]
seconds = manifest['runtime']/1000
+ init_length = seconds / 2 * 12 + 20*1000
duration = "PT"+str(seconds)+".00S"
root = ET.Element('MPD')
ET.SubElement(protection, 'cenc:pssh').text = pssh
for downloadable in video_track['downloadables']:
+
+ codec = 'h264'
+ if 'hevc' in downloadable['contentProfile']:
+ codec = 'hevc'
+
+ hdcp_versions = '0.0'
+ for hdcp in downloadable['hdcpVersions']:
+ if hdcp != 'none':
+ hdcp_versions = hdcp
+
rep = ET.SubElement(video_adaption_set, 'Representation',
width=str(downloadable['width']),
height=str(downloadable['height']),
bandwidth=str(downloadable['bitrate']*1024),
- codecs='h264',
+ hdcp=hdcp_versions,
+ nflxContentProfile=str(downloadable['contentProfile']),
+ codecs=codec,
mimeType='video/mp4')
#BaseURL
ET.SubElement(rep, 'BaseURL').text = self.__get_base_url(downloadable['urls'])
# Init an Segment block
- segment_base = ET.SubElement(rep, 'SegmentBase', indexRange="0-60000", indexRangeExact="true")
- ET.SubElement(segment_base, 'Initialization', range='0-60000')
+ segment_base = ET.SubElement(rep, 'SegmentBase', indexRange="0-"+str(init_length), indexRangeExact="true")
+ ET.SubElement(segment_base, 'Initialization', range='0-'+str(init_length))
contentType='audio',
mimeType='audio/mp4')
for downloadable in audio_track['downloadables']:
+ codec = 'aac'
+ print downloadable
+ if downloadable['contentProfile'] == 'ddplus-2.0-dash' or downloadable['contentProfile'] == 'ddplus-5.1-dash':
+ codec = 'ec-3'
+ print "codec is: " + codec
rep = ET.SubElement(audio_adaption_set, 'Representation',
- codecs='aac',
+ codecs=codec,
bandwidth=str(downloadable['bitrate']*1024),
mimeType='audio/mp4')
#BaseURL
ET.SubElement(rep, 'BaseURL').text = self.__get_base_url(downloadable['urls'])
# Index range
- segment_base = ET.SubElement(rep, 'SegmentBase', indexRange="0-60000", indexRangeExact="true")
- ET.SubElement(segment_base, 'Initialization', range='0-60000')
+ segment_base = ET.SubElement(rep, 'SegmentBase', indexRange="0-"+str(init_length), indexRangeExact="true")
+ ET.SubElement(segment_base, 'Initialization', range='0-'+str(init_length))
xml = ET.tostring(root, encoding='utf-8', method='xml')
# Serialize the given Data
serialized_data = json.dumps(data)
serialized_data = serialized_data.replace('"', '\\"')
- serialized_data = '[{},{"headers":{},"path":"/cbp/cadmium-11","payload":{"data":"' + serialized_data + '"},"query":""}]\n'
+ serialized_data = '[{},{"headers":{},"path":"/cbp/cadmium-13","payload":{"data":"' + serialized_data + '"},"query":""}]\n'
compressed_data = self.__compress_data(serialized_data)
if 'usertoken' in self.tokens:
pass
else:
+ account = self.kodi_helper.get_credentials()
# Auth via email and password
header_data['userauthdata'] = {
'scheme': 'EMAIL_PASSWORD',
'authdata': {
- 'email': self.email,
- 'password': self.password
+ 'email': account['email'],
+ 'password': account['password']
}
}