diff --git a/.gitignore b/.gitignore index b19f27a84..004531d7c 100644 --- a/.gitignore +++ b/.gitignore @@ -35,6 +35,7 @@ docs/api/ es5/ tmp test/test-manifests.js +test/test-segments.js test/test-expected.js coverage/ diff --git a/package.json b/package.json index a320928d9..1e72b0a70 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,7 @@ "build:webworker": "rollup -c scripts/webworker.rollup.config.js", "clean": "run-p clean:dist clean:test", "clean:dist": "rimraf dist dist-test", - "clean:test": "node -e \"var b=require('./scripts/manifest-data.js'); b.clean();\"", + "clean:test": "node scripts/clean-tests.js", "postclean": "mkdirp dist", "docs": "run-p docs:*", "docs:api": "jsdoc src -r -d docs/api", @@ -26,14 +26,16 @@ "start:server": "node scripts/server.js", "pretest": "run-s lint build:test:js", "test": "karma start test/karma.conf.js", - "prebuild:test:js": "run-s build:webworker build:test:manifest", + "prebuild:test:js": "run-s build:webworker build:test:manifest build:test:segments", "build:test:js": "rollup -c scripts/test.rollup.config.js", "build:test:manifest": "node -e \"var b=require('./scripts/manifest-data.js'); b.build();\"", - "watch": "run-p watch:js watch:test:manifest watch:test:js watch:js:switcher", + "build:test:segments": "node -e \"var b=require('./scripts/segments-data.js'); b.build();\"", + "watch": "run-p watch:js watch:test:manifest watch:test:segments watch:test:js watch:js:switcher", "watch:js": "rollup -c scripts/rollup.config.js -w", "watch:js:switcher": "rollup -c scripts/switcher.rollup.config.js -w", "watch:test:js": "rollup -c scripts/test.rollup.config.js -w", "watch:test:manifest": "node -e \"var b=require('./scripts/manifest-data.js'); b.watch();\"", + "watch:test:segments": "node -e \"var b=require('./scripts/segments-data.js'); b.watch();\"", "preversion": "npm test", "version": "node scripts/version.js", "prepublish": "in-publish && npm run build || not-in-publish" @@ -46,13 +48,16 @@ "license": "Apache-2.0", "vjsstandard": { "ignore": [ + "es5", "dist", "dist-test", "docs", "test/karma.conf.js", "scripts", "utils", - "test/test-manifests.js" + "test/test-manifests.js", + "test/test-segments.js", + "*.worker.*" ] }, "files": [ diff --git a/scripts/clean-tests.js b/scripts/clean-tests.js new file mode 100644 index 000000000..3f5ed48ae --- /dev/null +++ b/scripts/clean-tests.js @@ -0,0 +1,5 @@ +const manifestData = require('./manifest-data'); +const segmentsData = require('./segments-data'); + +manifestData.clean(); +segmentsData.clean(); diff --git a/scripts/segments-data.js b/scripts/segments-data.js new file mode 100644 index 000000000..a356cf0ab --- /dev/null +++ b/scripts/segments-data.js @@ -0,0 +1,70 @@ +const fs = require('fs'); +const path = require('path'); + +const basePath = path.resolve(__dirname, '..'); +const testDir = path.join(basePath, 'test'); +const segmentsDir = path.join(testDir, 'segments'); +const segmentsFilepath = path.join(testDir, 'test-segments.js'); + +const base64ToUint8Array = (base64) => { + const decoded = window.atob(base64); + const uint8Array = new Uint8Array(new ArrayBuffer(decoded.length)); + + for(let i = 0; i < decoded.length; i++) { + uint8Array[i] = decoded.charCodeAt(i); + } + + return uint8Array; +}; + +module.exports = { + build() { + const files = fs.readdirSync(segmentsDir); + const segmentData = {}; + + while (files.length > 0) { + const file = path.resolve(segmentsDir, files.shift()); + const extname = path.extname(file); + + if (extname === '.ts') { + // read the file directly as a buffer before converting to base64 + const base64Segment = fs.readFileSync(file).toString('base64'); + + segmentData[path.basename(file, extname)] = base64Segment; + } else { + console.log(`Unknown file ${file} found in segments dir ${segmentsDir}`); + } + } + + const segmentDataExportStrings = Object.keys(segmentData).reduce((acc, key) => { + // use a function since the segment may be cleared out on usage + acc.push(`export const ${key} = () => base64ToUint8Array('${segmentData[key]}');`); + return acc; + }, []); + + let segmentsFile = + `const base64ToUint8Array = ${base64ToUint8Array.toString()};\n` + + segmentDataExportStrings.join('\n'); + + fs.writeFileSync(segmentsFilepath, segmentsFile); + console.log('Wrote test data file ' + segmentsFilepath); + }, + + watch() { + this.build(); + fs.watch(segmentsDir, (event, filename) => { + console.log('files in segments dir were changed rebuilding segments data'); + this.build(); + }); + }, + + clean() { + if (fs.existsSync(segmentsFilepath)) { + try { + fs.unlinkSync(segmentsFilepath); + } catch(e) { + console.log(e); + } + } + } +}; diff --git a/test/master-playlist-controller.test.js b/test/master-playlist-controller.test.js index 07ce69aaf..9ed06431a 100644 --- a/test/master-playlist-controller.test.js +++ b/test/master-playlist-controller.test.js @@ -17,6 +17,7 @@ import Playlist from '../src/playlist'; import Config from '../src/config'; import PlaylistLoader from '../src/playlist-loader'; import DashPlaylistLoader from '../src/dash-playlist-loader'; +import { muxed as muxedSegment } from './test-segments'; QUnit.module('MasterPlaylistController', { beforeEach(assert) { @@ -585,8 +586,9 @@ function(assert) { this.standardXHRResponse(this.requests.shift(), audioMedia); // video segment - this.standardXHRResponse(this.requests.shift()); - + this.standardXHRResponse(this.requests.shift(), muxedSegment()); + // source buffer is mocked, so must manually trigger the video buffer + // video buffer is the first buffer created MPC.mediaSource.sourceBuffers[0].trigger('updateend'); assert.equal(videoEnded, 1, 'main segment loader triggered ended'); @@ -594,8 +596,9 @@ function(assert) { assert.equal(MPC.mediaSource.readyState, 'open', 'Media Source not yet ended'); // audio segment - this.standardXHRResponse(this.requests.shift()); - + this.standardXHRResponse(this.requests.shift(), muxedSegment()); + // source buffer is mocked, so must manually trigger the audio buffer + // audio buffer is the second buffer created MPC.mediaSource.sourceBuffers[1].trigger('updateend'); assert.equal(videoEnded, 1, 'main segment loader did not trigger ended again'); diff --git a/test/segments/muxed.ts b/test/segments/muxed.ts new file mode 100644 index 000000000..9a865cf9d Binary files /dev/null and b/test/segments/muxed.ts differ diff --git a/test/test-helpers.js b/test/test-helpers.js index 519e9c89e..d82114cc0 100644 --- a/test/test-helpers.js +++ b/test/test-helpers.js @@ -348,8 +348,12 @@ export const standardXHRResponse = function(request, data) { data = testDataManifests[manifestName]; } - request.response = new Uint8Array(1024).buffer; - request.respond(200, {'Content-Type': contentType}, data); + request.response = + // if segment data was passed, use that, otherwise use a placeholder + data instanceof Uint8Array ? data.buffer : new Uint8Array(1024).buffer; + request.respond(200, + { 'Content-Type': contentType }, + data instanceof Uint8Array ? '' : data); }; // return an absolute version of a page-relative URL diff --git a/test/videojs-http-streaming.test.js b/test/videojs-http-streaming.test.js index 543ec03f4..6a00d79b0 100644 --- a/test/videojs-http-streaming.test.js +++ b/test/videojs-http-streaming.test.js @@ -25,7 +25,6 @@ import { import window from 'global/window'; // we need this so the plugin registers itself import 'videojs-contrib-quality-levels'; -/* eslint-enable no-unused-vars */ const ogHlsHandlerSetupQualityLevels = videojs.HlsHandler.prototype.setupQualityLevels_;