feat(dolbySound): enable/disable dolby sound in addon settings
[plugin.video.netflix.git] / resources / lib / MSL.py
index bbe4e77e692ce38c9bcb853135caa4dcbc38e8ba..db9d68b4b94d5dfab0ab35a446f10303d07a04ce 100644 (file)
@@ -46,13 +46,11 @@ class MSL:
         '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)
@@ -85,9 +83,69 @@ class MSL:
             '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',
@@ -111,6 +169,12 @@ class MSL:
             '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)
 
@@ -205,6 +269,7 @@ class MSL:
                 pssh = manifest['psshb64'][0]
 
         seconds = manifest['runtime']/1000
+        init_length = seconds / 2 * 12 + 20*1000
         duration = "PT"+str(seconds)+".00S"
 
         root = ET.Element('MPD')
@@ -224,18 +289,30 @@ class MSL:
                 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))
 
 
 
@@ -246,8 +323,13 @@ class MSL:
                                                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')
 
@@ -259,8 +341,8 @@ class MSL:
                 #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')
@@ -308,7 +390,7 @@ class MSL:
         # 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)
 
@@ -379,12 +461,13 @@ class MSL:
             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']
                     }
                 }