Home Reference Source

src/demux/sample-aes.js

  1. /**
  2. * SAMPLE-AES decrypter
  3. */
  4.  
  5. import Decrypter from '../crypt/decrypter';
  6.  
  7. class SampleAesDecrypter {
  8. constructor (observer, config, decryptdata, discardEPB) {
  9. this.decryptdata = decryptdata;
  10. this.discardEPB = discardEPB;
  11. this.decrypter = new Decrypter(observer, config, { removePKCS7Padding: false });
  12. }
  13.  
  14. decryptBuffer (encryptedData, callback) {
  15. this.decrypter.decrypt(encryptedData, this.decryptdata.key.buffer, this.decryptdata.iv.buffer, callback);
  16. }
  17.  
  18. // AAC - encrypt all full 16 bytes blocks starting from offset 16
  19. decryptAacSample (samples, sampleIndex, callback, sync) {
  20. let curUnit = samples[sampleIndex].unit;
  21. let encryptedData = curUnit.subarray(16, curUnit.length - curUnit.length % 16);
  22. let encryptedBuffer = encryptedData.buffer.slice(
  23. encryptedData.byteOffset,
  24. encryptedData.byteOffset + encryptedData.length);
  25.  
  26. let localthis = this;
  27. this.decryptBuffer(encryptedBuffer, function (decryptedData) {
  28. decryptedData = new Uint8Array(decryptedData);
  29. curUnit.set(decryptedData, 16);
  30.  
  31. if (!sync) {
  32. localthis.decryptAacSamples(samples, sampleIndex + 1, callback);
  33. }
  34. });
  35. }
  36.  
  37. decryptAacSamples (samples, sampleIndex, callback) {
  38. for (;; sampleIndex++) {
  39. if (sampleIndex >= samples.length) {
  40. callback();
  41. return;
  42. }
  43.  
  44. if (samples[sampleIndex].unit.length < 32) {
  45. continue;
  46. }
  47.  
  48. let sync = this.decrypter.isSync();
  49.  
  50. this.decryptAacSample(samples, sampleIndex, callback, sync);
  51.  
  52. if (!sync) {
  53. return;
  54. }
  55. }
  56. }
  57.  
  58. // AVC - encrypt one 16 bytes block out of ten, starting from offset 32
  59. getAvcEncryptedData (decodedData) {
  60. let encryptedDataLen = Math.floor((decodedData.length - 48) / 160) * 16 + 16;
  61. let encryptedData = new Int8Array(encryptedDataLen);
  62. let outputPos = 0;
  63. for (let inputPos = 32; inputPos <= decodedData.length - 16; inputPos += 160, outputPos += 16) {
  64. encryptedData.set(decodedData.subarray(inputPos, inputPos + 16), outputPos);
  65. }
  66.  
  67. return encryptedData;
  68. }
  69.  
  70. getAvcDecryptedUnit (decodedData, decryptedData) {
  71. decryptedData = new Uint8Array(decryptedData);
  72. let inputPos = 0;
  73. for (let outputPos = 32; outputPos <= decodedData.length - 16; outputPos += 160, inputPos += 16) {
  74. decodedData.set(decryptedData.subarray(inputPos, inputPos + 16), outputPos);
  75. }
  76.  
  77. return decodedData;
  78. }
  79.  
  80. decryptAvcSample (samples, sampleIndex, unitIndex, callback, curUnit, sync) {
  81. let decodedData = this.discardEPB(curUnit.data);
  82. let encryptedData = this.getAvcEncryptedData(decodedData);
  83. let localthis = this;
  84.  
  85. this.decryptBuffer(encryptedData.buffer, function (decryptedData) {
  86. curUnit.data = localthis.getAvcDecryptedUnit(decodedData, decryptedData);
  87.  
  88. if (!sync) {
  89. localthis.decryptAvcSamples(samples, sampleIndex, unitIndex + 1, callback);
  90. }
  91. });
  92. }
  93.  
  94. decryptAvcSamples (samples, sampleIndex, unitIndex, callback) {
  95. for (;; sampleIndex++, unitIndex = 0) {
  96. if (sampleIndex >= samples.length) {
  97. callback();
  98. return;
  99. }
  100.  
  101. let curUnits = samples[sampleIndex].units;
  102. for (;; unitIndex++) {
  103. if (unitIndex >= curUnits.length) {
  104. break;
  105. }
  106.  
  107. let curUnit = curUnits[unitIndex];
  108. if (curUnit.length <= 48 || (curUnit.type !== 1 && curUnit.type !== 5)) {
  109. continue;
  110. }
  111.  
  112. let sync = this.decrypter.isSync();
  113.  
  114. this.decryptAvcSample(samples, sampleIndex, unitIndex, callback, curUnit, sync);
  115.  
  116. if (!sync) {
  117. return;
  118. }
  119. }
  120. }
  121. }
  122. }
  123.  
  124. export default SampleAesDecrypter;