create-test-data.js 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. /* global window */
  2. const fs = require('fs');
  3. const path = require('path');
  4. const baseDir = path.join(__dirname, '..');
  5. const manifestsDir = path.join(baseDir, 'test', 'manifests');
  6. const segmentsDir = path.join(baseDir, 'test', 'segments');
  7. const base64ToUint8Array = function(base64) {
  8. const decoded = window.atob(base64);
  9. const uint8Array = new Uint8Array(new ArrayBuffer(decoded.length));
  10. for (let i = 0; i < decoded.length; i++) {
  11. uint8Array[i] = decoded.charCodeAt(i);
  12. }
  13. return uint8Array;
  14. };
  15. const getManifests = () => (fs.readdirSync(manifestsDir) || [])
  16. .filter((f) => ((/\.(m3u8|mpd)/).test(path.extname(f))))
  17. .map((f) => path.resolve(manifestsDir, f));
  18. const getSegments = () => (fs.readdirSync(segmentsDir) || [])
  19. .filter((f) => ((/\.(ts|mp4|key|webm|aac|ac3|vtt)/).test(path.extname(f))))
  20. .map((f) => path.resolve(segmentsDir, f));
  21. const buildManifestString = function() {
  22. let manifests = 'export default {\n';
  23. getManifests().forEach((file) => {
  24. // translate this manifest
  25. manifests += ' \'' + path.basename(file, path.extname(file)) + '\': ';
  26. manifests += fs.readFileSync(file, 'utf8')
  27. .split(/\r\n|\n/)
  28. // quote and concatenate
  29. .map((line) => ' \'' + line + '\\n\' +\n')
  30. .join('')
  31. // strip leading spaces and the trailing '+'
  32. .slice(4, -3);
  33. manifests += ',\n';
  34. });
  35. // clean up and close the objects
  36. manifests = manifests.slice(0, -2);
  37. manifests += '\n};\n';
  38. return manifests;
  39. };
  40. const buildSegmentString = function() {
  41. const segmentData = {};
  42. getSegments().forEach((file) => {
  43. // read the file directly as a buffer before converting to base64
  44. const base64Segment = fs.readFileSync(file).toString('base64');
  45. segmentData[path.basename(file, path.extname(file))] = base64Segment;
  46. });
  47. const segmentDataExportStrings = Object.keys(segmentData).reduce((acc, key) => {
  48. // use a function since the segment may be cleared out on usage
  49. acc.push(`export const ${key} = () => {
  50. cache.${key} = cache.${key} || base64ToUint8Array('${segmentData[key]}');
  51. const dest = new Uint8Array(cache.${key}.byteLength);
  52. dest.set(cache.${key});
  53. return dest;
  54. };`);
  55. return acc;
  56. }, []);
  57. const segmentsFile =
  58. 'const cache = {};\n' +
  59. `const base64ToUint8Array = ${base64ToUint8Array.toString()};\n` +
  60. segmentDataExportStrings.join('\n');
  61. return segmentsFile;
  62. };
  63. /* we refer to them as .js, so that babel and other plugins can work on them */
  64. const segmentsKey = 'create-test-data!segments.js';
  65. const manifestsKey = 'create-test-data!manifests.js';
  66. module.exports = function() {
  67. return {
  68. name: 'createTestData',
  69. buildStart() {
  70. this.addWatchFile(segmentsDir);
  71. this.addWatchFile(manifestsDir);
  72. [].concat(getSegments())
  73. .concat(getManifests())
  74. .forEach((file) => this.addWatchFile(file));
  75. },
  76. resolveId(importee, importer) {
  77. // if this is not an id we can resolve return
  78. if (importee.indexOf('create-test-data!') !== 0) {
  79. return;
  80. }
  81. const name = importee.split('!')[1];
  82. return (name.indexOf('segments') === 0) ? segmentsKey : manifestsKey;
  83. },
  84. load(id) {
  85. if (id === segmentsKey) {
  86. return buildSegmentString.call(this);
  87. }
  88. if (id === manifestsKey) {
  89. return buildManifestString.call(this);
  90. }
  91. }
  92. };
  93. };