title: HLS media file decryption is not working using VideoJs, FairPlay
body: <p>I've tried to play an encrypted HLS media file, but It was not played and occurred errors as below.</p>
  <p><a href="https://i.stack.imgur.com/9zJ5D.png" rel="nofollow noreferrer">enter image description here</a></p>
  <p>The executable environment was identified in <a href="https://docs.vdms.com/video/Content/Security/Apple-FairPlay-DRM.htm" rel="nofollow noreferrer">this link</a>, but it was not played</p>
  <p>And tested in <a href="https://sample.pallycon.com/dev/devconsole/player.do?lang=ko#html5-player" rel="nofollow noreferrer">test page</a> of Pallycon, but It was played without a problem.</p>
  <p>Execution environments and source code are as below.</p>
  <h1>execution environments:</h1>
  <ul>
  <li>OS: macOS High Sierra 10.13.6</li>
  <li>Safari: 13.1.2</li>
  </ul>
  <h1>using libraries</h1>
  <ul>
  <li>videojs: ^7.8.4</li>
  <li>videojs-contrib-eme: ^3.7.0</li>
  </ul>
  <h1>DRM Vendor</h1>
  <ul>
  <li>Pallycon</li>
  </ul>
  <h1>source code</h1>
  <pre><code>const playerConfig = {
                      src: &quot;https://mz-cm-transcoding-output.s3.ap-northeast-2.amazonaws.com/mz-cm-v1/assets/1604917161khae8nfj/Beach+-+19987.m3u8&quot;,
                      type: 'application/x-mpegurl',
                      keySystems: {
                          'com.apple.fps.1_0': {
                              getCertificate: function (emeOptions, callback) {
                                  videojs.xhr({
                                      url: &quot;https://license.pallycon.com/ri/fpsKeyManager.do?siteId=&lt;SITE_ID&gt;&quot;,
                                      method: 'GET',
                                  }, (err, response, responseBody) =&gt; {
                                      if (err) {
                                          callback(err)
                                          return
                                      }
                                      callback(null, base64DecodeUint8Array(responseBody));
                                  })
                              },
                              getContentId: function (emeOptions, initData) {
                                  const contentId = arrayToString(initData);
                                  return contentId.substring(contentId.indexOf('skd://') + 6);
                              },
                              // return content ID
                              getLicense: function (emeOptions, contentId, keyMessage, callback) {
                                  videojs.xhr({
                                      url: &lt;license_url&gt;,
                                      method: 'POST',
                                      responseType: 'text',
                                      body: 'spc=' + base64EncodeUint8Array(keyMessage),
                                      headers: {
                                          'Content-type': 'application/x-www-form-urlencoded',
                                          'pallycon-customdata-v2': &lt;token&gt;
                                      }
                                  }, (err, response, responseBody) =&gt; {
                                      if (err) {
                                          callback(err)
                                          return
                                      }
                                      callback(null, base64DecodeUint8Array(responseBody))
                                  })
                              }
                          }
                      }
                  };
  
                  player.src(playerConfig);
  </code></pre>