aed1155d by brandonocasey

converted the hls project to generator conventions

added notifications back to travis
fixed sinon version in package.json
got unit tests working by modifying the karma config
Added back manifest/expected.js to the build pipeline
Added a script to build/watch/clean them
Added script execution to package.json
got switcher partially working again
1 parent 64aecaee
Showing 160 changed files with 637 additions and 935 deletions
1 # http://editorconfig.org
2 root = true
3
4 [*]
5 charset = utf-8
6 end_of_line = lf
7 indent_style = space
8 indent_size = 2
9 insert_final_newline = true
10 trim_trailing_whitespace = true
11
12 [*.md]
13 trim_trailing_whitespace = false
1 # OS
2 Thumbs.db
3 ehthumbs.db
4 Desktop.ini
1 .DS_Store 5 .DS_Store
2 dist/* 6 ._*
3 /node_modules/ 7
8 # Editors
4 *~ 9 *~
5 *.iml
6 *.ipr
7 *.iws
8 *.swp 10 *.swp
9 tmp/**.*.swo 11 *.tmproj
12 *.tmproject
13 *.sublime-*
14 .idea/
15 .project/
16 .settings/
17 .vscode/
18
19 # Logs
20 logs
21 *.log
22 npm-debug.log*
23
24 # Dependency directories
25 bower_components/
26 node_modules/
27
28 # Yeoman meta-data
29 .yo-rc.json
30
31 # Build-related directories
32 dist/
33 dist-test/
34 docs/api/
35 es5/
36 tmp
37 test/data/manifests.js
38 test/data/expected.js
......
1 {
2 "curly": true,
3 "eqeqeq": true,
4 "immed": true,
5 "latedef": true,
6 "newcap": true,
7 "noarg": true,
8 "sub": true,
9 "undef": true,
10 "unused": true,
11 "boss": true,
12 "eqnull": true,
13 "node": true,
14
15 "camelcase": true,
16 "nonew": true,
17 "quotmark": "single",
18 "trailing": true,
19 "maxlen": 80
20 }
1 *~ 1 # Intentionally left blank, so that npm does not ignore anything by default,
2 *.iml 2 # but relies on the package.json "files" array to explicitly define what ends
3 *.swp 3 # up in the package.
4 tmp/**
5 test/**
......
1 language: node_js
2 sudo: false 1 sudo: false
2 language: node_js
3 node_js: 3 node_js:
4 - "stable" 4 - 'node'
5 install: 5 - '4.2'
6 - npm install -g grunt-cli && npm install 6 - '0.12'
7 - '0.10'
7 notifications: 8 notifications:
8 hipchat: 9 hipchat:
9 rooms: 10 rooms:
...@@ -12,12 +13,7 @@ notifications: ...@@ -12,12 +13,7 @@ notifications:
12 channels: 13 channels:
13 - "chat.freenode.net#videojs" 14 - "chat.freenode.net#videojs"
14 use_notice: true 15 use_notice: true
16 # Set up a virtual screen for Firefox.
15 before_script: 17 before_script:
16 - export DISPLAY=:99.0 18 - export DISPLAY=:99.0
17 - sh -e /etc/init.d/xvfb start 19 - sh -e /etc/init.d/xvfb start
18 env:
19 global:
20 - secure: dM7svnHPPu5IiUMeFWW5zg+iuWNpwt6SSDi3MmVvhSclNMRLesQoRB+7Qq5J/LiKhmjpv1/GlNVV0CTsHMRhZNwQ3fo38eEuTXv99aAflEITXwSEh/VntKViHbGFubn06EnVkJoH6MX3zJ6kbiwc2QdSQbywKzS6l6quUEpWpd0=
21 - secure: AnduYGXka5ft1x7V3SuVYqvlKLvJGhUaRNFdy4UDJr3ZVuwpQjE4TMDG8REmJIJvXfHbh4qY4N1cFSGnXkZ4bH21Xk0v9DLhsxbarKz+X2BvPgXs+Af9EQ6vLEy/5S1vMLxfT5+y+Ec5bVNGOsdUZby8Y21CRzSg6ADN9kwPGlE=
22 addons:
23 sauce_connect: true
......
1 'use strict';
2
3 var
4 basename = require('path').basename,
5 mediaSourcesPath = 'node_modules/videojs-contrib-media-sources/dist/',
6 mediaSourcesDebug = mediaSourcesPath + 'videojs-media-sources.js';
7
8 module.exports = function(grunt) {
9 var pkg = grunt.file.readJSON('package.json');
10
11 // Project configuration.
12 grunt.initConfig({
13 // Metadata.
14 pkg: pkg,
15 banner: '/*! <%= pkg.name %> - v<%= pkg.version %> - ' +
16 '<%= grunt.template.today("yyyy-mm-dd") %>\n' +
17 '* Copyright (c) <%= grunt.template.today("yyyy") %> Brightcove;' +
18 ' Licensed <%= _.pluck(pkg.licenses, "type").join(", ") %> */\n',
19 // Task configuration.
20 clean: {
21 files: ['build', 'dist', 'tmp']
22 },
23 concat: {
24 options: {
25 banner: '<%= banner %>',
26 stripBanners: true
27 },
28 dist: {
29 nonull: true,
30 src: [
31 mediaSourcesDebug,
32 'src/videojs-hls.js',
33 'src/xhr.js',
34 'src/stream.js',
35 'src/m3u8/m3u8-parser.js',
36 'src/playlist.js',
37 'src/playlist-loader.js',
38 'node_modules/pkcs7/dist/pkcs7.unpad.js',
39 'src/decrypter.js'
40 ],
41 dest: 'dist/videojs.hls.js'
42 }
43 },
44 uglify: {
45 options: {
46 banner: '<%= banner %>'
47 },
48 dist: {
49 src: '<%= concat.dist.dest %>',
50 dest: 'dist/videojs.hls.min.js'
51 }
52 },
53 jshint: {
54 gruntfile: {
55 options: {
56 jshintrc: '.jshintrc'
57 },
58 src: 'Gruntfile.js'
59 },
60 src: {
61 options: {
62 jshintrc: 'src/.jshintrc'
63 },
64 src: ['src/**/*.js']
65 },
66 test: {
67 options: {
68 jshintrc: 'test/.jshintrc'
69 },
70 src: ['test/**/*.js',
71 '!test/tsSegment.js',
72 '!test/fixtures/*.js',
73 '!test/manifest/**',
74 '!test/muxer/**',
75 '!test/switcher/**']
76 }
77 },
78 connect: {
79 dev: {
80 options: {
81 hostname: '*',
82 port: 9999,
83 keepalive: true
84 }
85 },
86 test: {
87 options: {
88 hostname: '*',
89 port: 9999
90 }
91 }
92 },
93 open : {
94 dev : {
95 path: 'http://127.0.0.1:<%= connect.dev.options.port %>/example.html',
96 app: 'Google Chrome'
97 }
98 },
99 watch: {
100 build: {
101 files: '<%= concat.dist.src %>',
102 tasks: ['clean', 'concat', 'uglify']
103 },
104 gruntfile: {
105 files: '<%= jshint.gruntfile.src %>',
106 tasks: ['jshint:gruntfile']
107 },
108 src: {
109 files: '<%= jshint.src.src %>',
110 tasks: ['jshint:src', 'test']
111 },
112 test: {
113 files: '<%= jshint.test.src %>',
114 tasks: ['jshint:test', 'test']
115 }
116 },
117 concurrent: {
118 dev: {
119 tasks: ['connect', 'open', 'watch'],
120 options: {
121 logConcurrentOutput: true
122 }
123 }
124 },
125 version: {
126 project: {
127 src: ['package.json']
128 }
129 },
130 'github-release': {
131 options: {
132 repository: 'videojs/videojs-contrib-hls',
133 auth: {
134 user: process.env.VJS_GITHUB_USER,
135 password: process.env.VJS_GITHUB_TOKEN
136 },
137 release: {
138 'tag_name': 'v' + pkg.version,
139 name: pkg.version,
140 body: require('chg').find(pkg.version).changesRaw
141 }
142 },
143 files: {
144 'dist': ['videojs.hls.min.js']
145 }
146 },
147 karma: {
148 options: {
149 frameworks: ['qunit']
150 },
151
152 saucelabs: {
153 configFile: 'test/karma.conf.js',
154 autoWatch: true
155 },
156
157 dev: {
158 browsers: ['Chrome', 'Safari', 'Firefox',
159 'Opera', 'IE', 'PhantomJS', 'ChromeCanary'],
160 configFile: 'test/localkarma.conf.js',
161 autoWatch: true
162 },
163
164 chromecanary: {
165 options: {
166 browsers: ['ChromeCanary'],
167 configFile: 'test/localkarma.conf.js',
168 autoWatch: true
169 }
170 },
171
172 phantomjs: {
173 options: {
174 browsers: ['PhantomJS'],
175 configFile: 'test/localkarma.conf.js',
176 autoWatch: true
177 }
178 },
179
180 opera: {
181 options: {
182 browsers: ['Opera'],
183 configFile: 'test/localkarma.conf.js',
184 autoWatch: true
185 }
186 },
187
188 chrome: {
189 options: {
190 browsers: ['Chrome'],
191 configFile: 'test/localkarma.conf.js',
192 autoWatch: true
193 }
194 },
195
196 safari: {
197 options: {
198 browsers: ['Safari'],
199 configFile: 'test/localkarma.conf.js',
200 autoWatch: true
201 }
202 },
203
204 firefox: {
205 options: {
206 browsers: ['Firefox'],
207 configFile: 'test/localkarma.conf.js',
208 autoWatch: true
209 }
210 },
211
212 ie: {
213 options: {
214 browsers: ['IE'],
215 configFile: 'test/localkarma.conf.js',
216 autoWatch: true
217 }
218 },
219
220 ci: {
221 configFile: 'test/karma.conf.js',
222 autoWatch: false
223 }
224 },
225 protractor: {
226 options: {
227 configFile: 'test/functional/protractor.config.js',
228 webdriverManagerUpdate: process.env.TRAVIS ? false : true
229 },
230
231 chrome: {
232 options: {
233 args: {
234 capabilities: {
235 browserName: 'chrome'
236 }
237 }
238 }
239 },
240
241 firefox: {
242 options: {
243 args: {
244 capabilities: {
245 browserName: 'firefox'
246 }
247 }
248 }
249 },
250
251 safari: {
252 options: {
253 args: {
254 capabilities: {
255 browserName: 'safari'
256 }
257 }
258 }
259 },
260
261 ie: {
262 options: {
263 args: {
264 capabilities: {
265 browserName: 'internet explorer'
266 }
267 }
268 }
269 },
270
271 saucelabs:{}
272 }
273 });
274
275 // These plugins provide necessary tasks.
276 grunt.loadNpmTasks('grunt-karma');
277 grunt.loadNpmTasks('grunt-contrib-clean');
278 grunt.loadNpmTasks('grunt-contrib-concat');
279 grunt.loadNpmTasks('grunt-contrib-uglify');
280 grunt.loadNpmTasks('grunt-contrib-jshint');
281 grunt.loadNpmTasks('grunt-contrib-watch');
282 grunt.loadNpmTasks('grunt-contrib-connect');
283 grunt.loadNpmTasks('grunt-open');
284 grunt.loadNpmTasks('grunt-concurrent');
285 grunt.loadNpmTasks('grunt-contrib-watch');
286 grunt.loadNpmTasks('grunt-github-releaser');
287 grunt.loadNpmTasks('grunt-version');
288 grunt.loadNpmTasks('grunt-protractor-runner');
289 grunt.loadNpmTasks('chg');
290
291
292 grunt.registerTask('manifests-to-js', 'Wrap the test fixtures and output' +
293 ' so they can be loaded in a browser',
294 function() {
295 var
296 jsManifests = 'window.manifests = {\n',
297 jsExpected = 'window.expected = {\n';
298 grunt.file.recurse('test/manifest/',
299 function(abspath, root, sub, filename) {
300 if ((/\.m3u8$/).test(abspath)) {
301
302 // translate this manifest
303 jsManifests += ' \'' + basename(filename, '.m3u8') + '\': ' +
304 grunt.file.read(abspath)
305 .split(/\r\n|\n/)
306
307 // quote and concatenate
308 .map(function(line) {
309 return ' \'' + line + '\\n\' +\n';
310 }).join('')
311
312 // strip leading spaces and the trailing '+'
313 .slice(4, -3);
314 jsManifests += ',\n';
315 }
316
317 if ((/\.js$/).test(abspath)) {
318
319 // append the expected parse
320 jsExpected += ' "' + basename(filename, '.js') + '": ' +
321 grunt.file.read(abspath) + ',\n';
322 }
323 });
324
325 // clean up and close the objects
326 jsManifests = jsManifests.slice(0, -2);
327 jsManifests += '\n};\n';
328 jsExpected = jsExpected.slice(0, -2);
329 jsExpected += '\n};\n';
330
331 // write out the manifests
332 grunt.file.write('tmp/manifests.js', jsManifests);
333 grunt.file.write('tmp/expected.js', jsExpected);
334 });
335
336 // Launch a Development Environment
337 grunt.registerTask('dev', 'Launching Dev Environment', 'concurrent:dev');
338
339 grunt.registerTask('build',
340 ['clean',
341 'concat',
342 'uglify']);
343
344 // Default task.
345 grunt.registerTask('default',
346 ['test',
347 'build']);
348
349 // The test task will run `karma:saucelabs` when running in travis,
350 // otherwise, it'll default to running karma in chrome.
351 // You can specify which browsers to build with by using grunt-style arguments
352 // or separating them with a comma:
353 // grunt test:chrome:firefox # grunt-style
354 // grunt test:chrome,firefox # comma-separated
355 grunt.registerTask('test', function() {
356 var tasks = this.args;
357
358 grunt.task.run(['jshint', 'manifests-to-js']);
359
360 if (process.env.TRAVIS) {
361 if (process.env.TRAVIS_PULL_REQUEST === 'false') {
362 grunt.task.run(['karma:saucelabs']);
363 grunt.task.run(['connect:test', 'protractor:saucelabs']);
364 } else {
365 grunt.task.run(['karma:firefox']);
366 }
367 } else {
368 if (tasks.length === 0) {
369 tasks.push('chrome');
370 }
371 if (tasks.length === 1) {
372 tasks = tasks[0].split(',');
373 }
374 tasks = tasks.reduce(function(acc, el) {
375 acc.push('karma:' + el);
376 if (/chrome|firefox|safari|ie/.test(el)) {
377 acc.push('protractor:' + el);
378 }
379 return acc;
380 }, ['connect:test']);
381
382 grunt.task.run(tasks);
383 }
384 });
385 };
1 <!-- START doctoc generated TOC please keep comment here to allow auto update -->
2 <!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
3 **Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)*
4
5 - [video.js HLS Source Handler](#videojs-hls-source-handler)
6 - [Getting Started](#getting-started)
7 - [Documentation](#documentation)
8 - [Options](#options)
9 - [withCredentials](#withcredentials)
10 - [Runtime Properties](#runtime-properties)
11 - [hls.playlists.master](#hlsplaylistsmaster)
12 - [hls.playlists.media](#hlsplaylistsmedia)
13 - [hls.segmentXhrTime](#hlssegmentxhrtime)
14 - [hls.bandwidth](#hlsbandwidth)
15 - [hls.bytesReceived](#hlsbytesreceived)
16 - [hls.selectPlaylist](#hlsselectplaylist)
17 - [Events](#events)
18 - [loadedmetadata](#loadedmetadata)
19 - [loadedplaylist](#loadedplaylist)
20 - [mediachange](#mediachange)
21 - [In-Band Metadata](#in-band-metadata)
22 - [Hosting Considerations](#hosting-considerations)
23 - [Testing](#testing)
24 - [Release History](#release-history)
25
26 <!-- END doctoc generated TOC please keep comment here to allow auto update -->
27
1 # video.js HLS Source Handler 28 # video.js HLS Source Handler
2 29
3 Play back HLS with video.js, even where it's not natively supported. 30 Play back HLS with video.js, even where it's not natively supported.
......
...@@ -2,31 +2,8 @@ ...@@ -2,31 +2,8 @@
2 <html> 2 <html>
3 <head> 3 <head>
4 <meta charset="utf-8"> 4 <meta charset="utf-8">
5 <title>video.js HLS Plugin Example</title> 5 <title>videojs-contrib-hls Demo</title>
6 6 <link href="/node_modules/video.js/dist/video-js.css" rel="stylesheet">
7 <link href="node_modules/video.js/dist/video-js.css" rel="stylesheet">
8
9 <!-- video.js -->
10 <script src="node_modules/video.js/dist/video.js"></script>
11
12 <!-- Media Sources plugin -->
13 <script src="node_modules/videojs-contrib-media-sources/dist/videojs-media-sources.js"></script>
14
15 <!-- HLS plugin -->
16 <script src="src/videojs-hls.js"></script>
17
18 <!-- m3u8 handling -->
19 <script src="src/xhr.js"></script>
20 <script src="src/stream.js"></script>
21 <script src="src/m3u8/m3u8-parser.js"></script>
22 <script src="src/playlist.js"></script>
23 <script src="src/playlist-loader.js"></script>
24
25 <script src="node_modules/pkcs7/dist/pkcs7.unpad.js"></script>
26 <script src="src/decrypter.js"></script>
27
28 <script src="src/bin-utils.js"></script>
29
30 <style> 7 <style>
31 body { 8 body {
32 font-family: Arial, sans-serif; 9 font-family: Arial, sans-serif;
...@@ -52,14 +29,8 @@ ...@@ -52,14 +29,8 @@
52 <p>The video below is an <a href="https://developer.apple.com/library/ios/documentation/networkinginternet/conceptual/streamingmediaguide/Introduction/Introduction.html#//apple_ref/doc/uid/TP40008332-CH1-SW1">HTTP Live Stream</a>. On desktop browsers other than Safari, the HLS plugin will polyfill support for the format on top of the video.js Flash tech.</p> 29 <p>The video below is an <a href="https://developer.apple.com/library/ios/documentation/networkinginternet/conceptual/streamingmediaguide/Introduction/Introduction.html#//apple_ref/doc/uid/TP40008332-CH1-SW1">HTTP Live Stream</a>. On desktop browsers other than Safari, the HLS plugin will polyfill support for the format on top of the video.js Flash tech.</p>
53 <p>Due to security restrictions in Flash, you will have to load this page over HTTP(S) to see the example in action.</p> 30 <p>Due to security restrictions in Flash, you will have to load this page over HTTP(S) to see the example in action.</p>
54 </div> 31 </div>
55 <video id="video" 32 <video id="videojs-contrib-hls-player" class="video-js vjs-default-skin" controls>
56 class="video-js vjs-default-skin" 33 <source src="http://solutions.brightcove.com/jwhisenant/hls/apple/bipbop/bipbopall.m3u8" type="application/x-mpegURL">
57 height="300"
58 width="600"
59 controls>
60 <source
61 src="http://solutions.brightcove.com/jwhisenant/hls/apple/bipbop/bipbopall.m3u8"
62 type="application/x-mpegURL">
63 </video> 34 </video>
64 35
65 <form id=load-url> 36 <form id=load-url>
...@@ -70,11 +41,20 @@ ...@@ -70,11 +41,20 @@
70 <button type=submit>Load</button> 41 <button type=submit>Load</button>
71 </form> 42 </form>
72 43
44 <script src="/node_modules/video.js/dist/video.js"></script>
45 <script src="/node_modules/videojs-contrib-media-sources/dist/videojs-media-sources.js"></script>
46 <script src="/node_modules/pkcs7/dist/pkcs7.unpad.js"></script>
47 <script src="/src/videojs-hls.js"></script>
48 <script src="/src/xhr.js"></script>
49 <script src="/src/stream.js"></script>
50 <script src="/src/m3u8/m3u8-parser.js"></script>
51 <script src="/src/playlist.js"></script>
52 <script src="/src/playlist-loader.js"></script>
53 <script src="/src/decrypter.js"></script>
54 <script src="/src/bin-utils.js"></script>
73 <script> 55 <script>
74 videojs.options.flash.swf = 'node_modules/videojs-swf/dist/video-js.swf'; 56 (function(window, videojs) {
75 // initialize the player 57 var player = window.player = videojs('videojs-contrib-hls-player');
76 var player = videojs('video');
77
78 // hook up the video switcher 58 // hook up the video switcher
79 var loadUrl = document.getElementById('load-url'); 59 var loadUrl = document.getElementById('load-url');
80 var url = document.getElementById('url'); 60 var url = document.getElementById('url');
...@@ -86,6 +66,7 @@ ...@@ -86,6 +66,7 @@
86 }); 66 });
87 return false; 67 return false;
88 }); 68 });
69 }(window, window.videojs));
89 </script> 70 </script>
90 </body> 71 </body>
91 </html> 72 </html>
......
1 { 1 {
2 "name": "videojs-contrib-hls", 2 "name": "videojs-contrib-hls",
3 "version": "1.3.5", 3 "version": "1.3.5",
4 "description": "Play back HLS with video.js, even where it's not natively supported",
5 "main": "es5/videojs-hls.js",
4 "engines": { 6 "engines": {
5 "node": ">= 0.10.12" 7 "node": ">= 0.10.12"
6 }, 8 },
...@@ -8,47 +10,116 @@ ...@@ -8,47 +10,116 @@
8 "type": "git", 10 "type": "git",
9 "url": "git@github.com:videojs/videojs-contrib-hls.git" 11 "url": "git@github.com:videojs/videojs-contrib-hls.git"
10 }, 12 },
11 "license": "Apache-2.0",
12 "scripts": { 13 "scripts": {
13 "test": "grunt test", 14 "prebuild": "npm run clean",
14 "prepublish": "if [ -z \"$TRAVIS\" ]; then grunt; fi" 15 "build": "npm-run-all -p build:*",
16 "build:manifest": "node -e \"var b=require('./scripts/manifest-data.js'); b.build();\"",
17 "build:js": "npm-run-all build:js:babel build:js:browserify build:js:bannerize build:js:uglify",
18 "build:js:babel": "babel src -d es5",
19 "build:js:bannerize": "bannerize dist/videojs-contrib-hls.js --banner=scripts/banner.ejs",
20 "build:js:browserify": "browserify . -s src/videojs-hls.js -o dist/videojs-contrib-hls.js",
21 "build:js:uglify": "uglifyjs dist/videojs-contrib-hls.js --comments --mangle --compress -o dist/videojs-contrib-hls.min.js",
22 "build:test": "node scripts/build-test.js",
23 "clean": "npm-run-all clean:*",
24 "clean:build": "node -e \"var s=require('shelljs'),d=['dist','dist-test','es5'];s.rm('-rf',d);s.mkdir('-p',d);\"",
25 "clean:manifest": "node -e \"var b=require('./scripts/manifest-data.js'); b.clean();\"",
26 "docs": "npm-run-all docs:*",
27 "docs:api": "jsdoc src -r -d docs/api",
28 "docs:toc": "doctoc README.md",
29 "lint": "vjsstandard :",
30 "prestart": "npm-run-all docs build",
31 "start": "npm-run-all -p start:* watch:*",
32 "start:serve": "babel-node scripts/server.js",
33 "pretest": "npm-run-all lint build",
34 "test": "karma start test/karma/detected.js",
35 "test:chrome": "npm run pretest && karma start test/karma/chrome.js",
36 "test:firefox": "npm run pretest && karma start test/karma/firefox.js",
37 "test:ie": "npm run pretest && karma start test/karma/ie.js",
38 "test:safari": "npm run pretest && karma start test/karma/safari.js",
39 "preversion": "npm test",
40 "version": "npm run build",
41 "watch": "npm-run-all -p watch:*",
42 "watch:manifest": "node -e \"var b=require('./scripts/manifest-data.js'); b.watch();\"",
43 "watch:js": "watchify src/videojs-hls.js -t babelify -v -o dist/videojs-contrib-hls.js",
44 "watch:test": "node scripts/watch-test.js",
45 "prepublish": "npm run build"
15 }, 46 },
16 "keywords": [ 47 "keywords": [
17 "videojs", 48 "videojs",
18 "videojs-plugin" 49 "videojs-plugin"
19 ], 50 ],
20 "devDependencies": { 51 "author": "Brightcove, Inc",
21 "chg": "^0.2.0", 52 "license": "Apache-2.0",
22 "grunt": "^0.4.5", 53 "browserify": {
23 "grunt-concurrent": "0.4.3", 54 "transform": [
24 "grunt-contrib-clean": "~0.4.0", 55 "browserify-shim"
25 "grunt-contrib-concat": "~0.3.0", 56 ]
26 "grunt-contrib-connect": "~0.6.0", 57 },
27 "grunt-contrib-jshint": "~0.6.0", 58 "browserify-shim": {
28 "grunt-contrib-uglify": "~0.2.0", 59 "qunit": "global:QUnit",
29 "grunt-contrib-watch": "~0.4.0", 60 "sinon": "global:sinon",
30 "grunt-github-releaser": "^0.1.17", 61 "video.js": "global:videojs"
31 "grunt-karma": "~0.6.2",
32 "grunt-open": "0.2.3",
33 "grunt-protractor-runner": "forbesjo/grunt-protractor-runner.git#webdriverManagerUpdate",
34 "grunt-shell": "0.6.1",
35 "grunt-version": "^1.0.0",
36 "karma": "~0.10.0",
37 "karma-chrome-launcher": "~0.1.2",
38 "karma-firefox-launcher": "~0.1.3",
39 "karma-ie-launcher": "~0.1.1",
40 "karma-opera-launcher": "~0.1.0",
41 "karma-phantomjs-launcher": "^0.1.4",
42 "karma-qunit": "~0.1.1",
43 "karma-safari-launcher": "~0.1.1",
44 "karma-sauce-launcher": "~0.1.8",
45 "qunitjs": "^1.18.0",
46 "sinon": "1.10.2",
47 "video.js": "^5.2.1"
48 }, 62 },
63 "vjsstandard": {
64 "ignore": [
65 "dist",
66 "dist-test",
67 "docs",
68 "es5",
69 "test/karma",
70 "scripts",
71 "utils",
72 "test/data"
73 ]
74 },
75 "files": [
76 "CONTRIBUTING.md",
77 "dist-test/",
78 "dist/",
79 "docs/",
80 "es5/",
81 "index.html",
82 "scripts/",
83 "src/",
84 "test/",
85 "utils/"
86 ],
49 "dependencies": { 87 "dependencies": {
50 "pkcs7": "^0.2.2", 88 "pkcs7": "^0.2.3",
51 "videojs-contrib-media-sources": "^2.4.0", 89 "video.js": "^5.0.0",
52 "videojs-swf": "^5.0.0" 90 "videojs-contrib-media-sources": "^2.4.4",
91 "videojs-swf": "^5.0.1"
92 },
93 "devDependencies": {
94 "babel": "^5.8.0",
95 "babelify": "^6.0.0",
96 "bannerize": "^1.0.0",
97 "browserify": "^11.0.0",
98 "browserify-shim": "^3.0.0",
99 "connect": "^3.4.0",
100 "cowsay": "^1.1.0",
101 "doctoc": "^0.15.0",
102 "glob": "^6.0.3",
103 "global": "^4.3.0",
104 "jsdoc": "^3.4.0",
105 "karma": "^0.13.0",
106 "karma-browserify": "^4.4.0",
107 "karma-chrome-launcher": "^0.2.0",
108 "karma-detect-browsers": "^2.0.0",
109 "karma-firefox-launcher": "^0.1.0",
110 "karma-ie-launcher": "^0.2.0",
111 "karma-qunit": "^0.1.9",
112 "karma-safari-launcher": "^0.1.0",
113 "lodash-compat": "^3.10.0",
114 "minimist": "^1.2.0",
115 "npm-run-all": "^1.2.0",
116 "portscanner": "^1.0.0",
117 "qunitjs": "^1.0.0",
118 "serve-static": "^1.10.0",
119 "shelljs": "^0.5.3",
120 "sinon": "1.10.2",
121 "uglify-js": "^2.5.0",
122 "videojs-standard": "^4.0.0",
123 "watchify": "^3.6.0"
53 } 124 }
54 } 125 }
......
1 /**
2 * <%- pkg.name %>
3 * @version <%- pkg.version %>
4 * @copyright <%- date.getFullYear() %> <%- pkg.author %>
5 * @license <%- pkg.license %>
6 */
1 var browserify = require('browserify');
2 var fs = require('fs');
3 var glob = require('glob');
4
5 glob('test/**/*.test.js', function(err, files) {
6 browserify(files)
7 .transform('babelify')
8 .bundle()
9 .pipe(fs.createWriteStream('dist-test/videojs-contrib-hls.js'));
10 });
1 var fs = require('fs');
2 var path = require('path');
3
4 var basePath = path.resolve(__dirname + '/..');
5 var testDataDir = basePath + '/test/data';
6 var manifestDir = basePath + '/utils/manifest';
7 var manifestFilepath = testDataDir + '/manifests.js';
8 var expectedFilepath = testDataDir + '/expected.js';
9
10
11 var build = function() {
12 var manifests = 'window.manifests = {\n';
13 var expected = 'window.expected = {\n';
14
15 var files = fs.readdirSync(manifestDir);
16 while (files.length > 0) {
17 var file = path.resolve(manifestDir, files.shift());
18 var extname = path.extname(file);
19
20 if (extname === '.m3u8') {
21 // translate this manifest
22 manifests += ' \'' + path.basename(file, '.m3u8') + '\': ';
23 manifests += fs.readFileSync(file, 'utf8')
24 .split(/\r\n|\n/)
25 // quote and concatenate
26 .map(function(line) {
27 return ' \'' + line + '\\n\' +\n';
28 }).join('')
29 // strip leading spaces and the trailing '+'
30 .slice(4, -3);
31 manifests += ',\n';
32 } else if (extname === '.js') {
33 // append the expected parse
34 expected += ' "' + path.basename(file, '.js') + '": ';
35 expected += fs.readFileSync(file, 'utf8');
36 expected += ',\n';
37 } else {
38 console.log('Unknown file ' + file + ' found in manifest dir ' + manifestDir);
39 }
40
41 }
42
43 // clean up and close the objects
44 manifests = manifests.slice(0, -2);
45 manifests += '\n};\n';
46 expected = expected.slice(0, -2);
47 expected += '\n};\n';
48
49 fs.writeFileSync(manifestFilepath, manifests);
50 fs.writeFileSync(expectedFilepath, expected);
51 console.log('Wrote test data file ' + manifestFilepath);
52 console.log('Wrote test data file ' + expectedFilepath);
53 };
54
55 var watch = function() {
56 build();
57 fs.watch(manifestDir, function(event, filename) {
58 console.log('files in manifest dir were changed rebuilding manifest data');
59 build();
60 });
61 };
62
63 var clean = function() {
64 try {
65 fs.unlinkSync(manifestFilepath);
66 } catch(e) {
67 // ignore error, must not exist
68 }
69 try {
70 fs.unlinkSync(expectedFilepath);
71 } catch(e) {
72 // ignore error, must not exist
73 }
74 }
75
76 module.exports = {
77 build: build,
78 watch: watch,
79 clean: clean
80 };
1 import connect from 'connect';
2 import cowsay from 'cowsay';
3 import path from 'path';
4 import portscanner from 'portscanner';
5 import serveStatic from 'serve-static';
6
7 // Configuration for the server.
8 const PORT = 9999;
9 const MAX_PORT = PORT + 100;
10 const HOST = '127.0.0.1';
11
12 const app = connect();
13
14 const verbs = [
15 'Chewing the cud',
16 'Grazing',
17 'Mooing',
18 'Lowing',
19 'Churning the cream'
20 ];
21
22 app.use(serveStatic(path.join(__dirname, '..')));
23
24 portscanner.findAPortNotInUse(PORT, MAX_PORT, HOST, (error, port) => {
25 if (error) {
26 throw error;
27 }
28
29 process.stdout.write(cowsay.say({
30 text: `${verbs[Math.floor(Math.random() * 5)]} on ${HOST}:${port}`
31 }) + '\n\n');
32
33 app.listen(port);
34 });
1 var browserify = require('browserify');
2 var fs = require('fs');
3 var glob = require('glob');
4 var watchify = require('watchify');
5
6 glob('test/**/*.test.js', function(err, files) {
7 var b = browserify(files, {
8 cache: {},
9 packageCache: {},
10 plugin: [watchify]
11 }).transform('babelify');
12
13 var bundle = function() {
14 b.bundle().pipe(fs.createWriteStream('dist-test/videojs-contrib-hls.js'));
15 };
16
17 b.on('log', function(msg) {
18 process.stdout.write(msg + '\n');
19 });
20
21 b.on('update', bundle);
22 bundle();
23 });
1 {
2 "curly": true,
3 "eqeqeq": true,
4 "immed": true,
5 "latedef": true,
6 "newcap": true,
7 "noarg": true,
8 "sub": true,
9 "undef": true,
10 "unused": true,
11 "boss": true,
12 "eqnull": true,
13 "browser": true,
14 "node": true,
15 "predef": [
16 "QUnit",
17 "module",
18 "test",
19 "asyncTest",
20 "expect",
21 "start",
22 "stop",
23 "ok",
24 "equal",
25 "notEqual",
26 "deepEqual",
27 "notDeepEqual",
28 "strictEqual",
29 "notStrictEqual",
30 "throws",
31 "sinon",
32 "process"
33 ]
34 }
...@@ -32,7 +32,7 @@ var stringFromBytes = function(bytes) { ...@@ -32,7 +32,7 @@ var stringFromBytes = function(bytes) {
32 return result; 32 return result;
33 }; 33 };
34 34
35 module('Decryption'); 35 QUnit.module('Decryption');
36 36
37 test('decrypts a single AES-128 with PKCS7 block', function() { 37 test('decrypts a single AES-128 with PKCS7 block', function() {
38 var 38 var
...@@ -74,7 +74,7 @@ test('decrypts multiple AES-128 blocks with CBC', function() { ...@@ -74,7 +74,7 @@ test('decrypts multiple AES-128 blocks with CBC', function() {
74 74
75 var clock; 75 var clock;
76 76
77 module('Incremental Processing', { 77 QUnit.module('Incremental Processing', {
78 setup: function() { 78 setup: function() {
79 clock = sinon.useFakeTimers(); 79 clock = sinon.useFakeTimers();
80 }, 80 },
...@@ -114,7 +114,7 @@ test('executes callback in series', function() { ...@@ -114,7 +114,7 @@ test('executes callback in series', function() {
114 114
115 var decrypter; 115 var decrypter;
116 116
117 module('Incremental Decryption', { 117 QUnit.module('Incremental Decryption', {
118 setup: function() { 118 setup: function() {
119 clock = sinon.useFakeTimers(); 119 clock = sinon.useFakeTimers();
120 }, 120 },
......
1 <!DOCTYPE html>
2 <html>
3 <head>
4 <meta charset="utf-8">
5 <title>video.js HLS Plugin Test Suite</title>
6 <link rel="stylesheet" href="/node_modules/qunitjs/qunit/qunit.css" media="screen">
7 <link rel="stylesheet" href="/node_modules/video.js/dist/video-js.css" media="screen">
8 </head>
9 <body>
10 <div id="qunit"></div>
11 <div id="qunit-fixture"></div>
12 <!-- NOTE in order for test to pass we require sinon 1.10.2 exactly -->
13 <script src="/node_modules/sinon/pkg/sinon.js"></script>
14 <script src="/node_modules/qunitjs/qunit/qunit.js"></script>
15 <script src="/node_modules/pkcs7/dist/pkcs7.unpad.js"></script>
16 <script src="/node_modules/video.js/dist/video.js"></script>
17 <script src="/node_modules/videojs-contrib-media-sources/src/videojs-media-sources.js"></script>
18
19 <script src="/src/videojs-hls.js"></script>
20 <script src="/src/xhr.js"></script>
21 <script src="/src/stream.js"></script>
22 <script src="/src/m3u8/m3u8-parser.js"></script>
23 <script src="/src/playlist.js"></script>
24 <script src="/src/playlist-loader.js"></script>
25 <script src="/src/decrypter.js"></script>
26 <script src="/src/bin-utils.js"></script>
27
28 <script src="/test/data/manifests.js"></script>
29 <script src="/test/data/expected.js"></script>
30 <script src="/test/data/ts-segment-bc.js"></script>
31
32
33 <script src="/test/videojs-hls.test.js"></script>
34 <script src="/test/m3u8.test.js"></script>
35 <script src="/test/playlist.test.js"></script>
36 <script src="/test/playlist-loader.test.js"></script>
37 <script src="/test/decrypter.test.js"></script>
38
39 </body>
40 </html>
1
2
3 var fixture = document.createElement('div');
4 fixture.id = 'qunit-fixture';
5 document.body.appendChild(fixture);
1 // Karma example configuration file
2 // NOTE: To configure Karma tests, do the following:
3 // 1. Copy this file and rename the copy with a .conf.js extension, for example: karma.conf.js
4 // 2. Configure the properties below in your conf.js copy
5 // 3. Run your tests
6
7 module.exports = function(config) {
8 var customLaunchers = {
9 chrome_sl: {
10 singleRun: true,
11 base: 'SauceLabs',
12 browserName: 'chrome',
13 platform: 'Windows 7'
14 },
15
16 firefox_sl: {
17 singleRun: true,
18 base: 'SauceLabs',
19 browserName: 'firefox',
20 platform: 'Windows 8'
21 },
22
23 safari_sl: {
24 singleRun: true,
25 base: 'SauceLabs',
26 browserName: 'safari',
27 platform: 'OS X 10.8'
28 },
29
30 ipad_sl: {
31 singleRun: true,
32 base: 'SauceLabs',
33 browserName: 'ipad',
34 platform:'OS X 10.9',
35 version: '7.1'
36 },
37
38 android_sl: {
39 singleRun: true,
40 base: 'SauceLabs',
41 browserName: 'android',
42 platform:'Linux'
43 }
44 };
45
46 config.set({
47 // base path, that will be used to resolve files and exclude
48 basePath: '',
49
50 frameworks: ['qunit'],
51
52 // Set autoWatch to true if you plan to run `grunt karma` continuously, to automatically test changes as you make them.
53 autoWatch: false,
54
55 // Setting singleRun to true here will start up your specified browsers, run tests, and then shut down the browsers. Helpful to have in a CI environment, where you don't want to leave browsers running continuously.
56 singleRun: true,
57
58 // custom launchers for sauce labs
59 //define SL browsers
60 customLaunchers: customLaunchers,
61
62 // Start these browsers
63 browsers: ['chrome_sl'], //Object.keys(customLaunchers),
64
65 // List of files / patterns to load in the browser
66 // Add any new src files to this list.
67 // If you add new unit tests, they will be picked up automatically by Karma,
68 // unless you've added them to a nested directory, in which case you should
69 // add their paths to this list.
70
71 files: [
72 '../node_modules/sinon/pkg/sinon.js',
73 '../node_modules/video.js/dist/video-js.css',
74 '../node_modules/video.js/dist/video.js',
75 '../node_modules/videojs-contrib-media-sources/src/videojs-media-sources.js',
76 '../node_modules/pkcs7/dist/pkcs7.unpad.js',
77 '../test/karma-qunit-shim.js',
78 '../src/videojs-hls.js',
79 '../src/stream.js',
80 '../src/m3u8/m3u8-parser.js',
81 '../src/xhr.js',
82 '../src/playlist.js',
83 '../src/playlist-loader.js',
84 '../src/decrypter.js',
85 '../tmp/manifests.js',
86 '../tmp/expected.js',
87 'tsSegment-bc.js',
88 '../src/bin-utils.js',
89 '../test/*.js',
90 ],
91
92 plugins: [
93 'karma-qunit',
94 'karma-chrome-launcher',
95 'karma-firefox-launcher',
96 'karma-ie-launcher',
97 'karma-opera-launcher',
98 'karma-phantomjs-launcher',
99 'karma-safari-launcher',
100 'karma-sauce-launcher'
101 ],
102
103 // test results reporter to use
104 // possible values: 'dots', 'progress', 'junit'
105 reporters: ['dots', 'progress'],
106
107 // web server port
108 port: 9876,
109
110 // cli runner port
111 runnerPort: 9100,
112
113 // enable / disable colors in the output (reporters and logs)
114 colors: true,
115
116 // level of logging
117 // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
118 //logLevel: config.LOG_INFO,
119
120 // If browser does not capture in given timeout [ms], kill it
121 captureTimeout: 60000,
122
123 // global config for SauceLabs
124 sauceLabs: {
125 startConnect: false,
126 tunnelIdentifier: process.env.TRAVIS_JOB_NUMBER,
127 build: process.env.TRAVIS_BUILD_NUMBER,
128 testName: process.env.TRAVIS_BUILD_NUMBER + process.env.TRAVIS_BRANCH,
129 recordScreenshots: false
130 }
131 });
132 };
1 var common = require('./common');
2
3 module.exports = function(config) {
4 config.set(common({
5 plugins: ['karma-chrome-launcher'],
6 browsers: ['Chrome']
7 }));
8 };
1 var merge = require('lodash-compat/object/merge');
2
3 var DEFAULTS = {
4 basePath: '../..',
5 //frameworks: ['browserify', 'qunit'],
6 frameworks: ['qunit'],
7
8
9 files: [
10 'node_modules/sinon/pkg/sinon.js',
11 'node_modules/sinon/pkg/sinon-ie.js',
12 'node_modules/video.js/dist/video.js',
13 'node_modules/video.js/dist/video-js.css',
14
15 // REMOVE ME WHEN BROWSERIFIED
16 'node_modules/pkcs7/dist/pkcs7.unpad.js',
17 'node_modules/videojs-contrib-media-sources/src/videojs-media-sources.js',
18
19 'src/videojs-hls.js',
20 'src/xhr.js',
21 'src/stream.js',
22 'src/m3u8/m3u8-parser.js',
23 'src/playlist.js',
24 'src/playlist-loader.js',
25 'src/decrypter.js',
26 'src/bin-utils.js',
27
28 'test/data/manifests.js',
29 'test/data/expected.js',
30 'test/data/ts-segment-bc.js',
31
32 'test/videojs-hls.test.js',
33 'test/m3u8.test.js',
34 'test/playlist.test.js',
35 'test/playlist-loader.test.js',
36 'test/decrypter.test.js',
37 // END REMOVE ME
38 // 'test/**/*.js'
39 ],
40
41 exclude: [
42 'test/bundle.js',
43 // 'test/data/**'
44 ],
45
46 plugins: [
47 // 'karma-browserify',
48 'karma-qunit'
49 ],
50
51 preprocessors: {
52 // 'test/**/*.js': ['browserify']
53 },
54
55 reporters: ['dots'],
56 port: 9876,
57 colors: true,
58 autoWatch: false,
59 singleRun: true,
60 concurrency: Infinity,
61
62 /*
63 browserify: {
64 debug: true,
65 transform: [
66 'babelify',
67 'browserify-shim'
68 ],
69 noparse: [
70 'test/data/**',
71 ]
72 }
73 */
74 };
75
76 /**
77 * Customizes target/source merging with lodash merge.
78 *
79 * @param {Mixed} target
80 * @param {Mixed} source
81 * @return {Mixed}
82 */
83 var customizer = function(target, source) {
84 if (Array.isArray(target)) {
85 return target.concat(source);
86 }
87 };
88
89 /**
90 * Generates a new Karma config with a common set of base configuration.
91 *
92 * @param {Object} custom
93 * Configuration that will be deep-merged. Arrays will be
94 * concatenated.
95 * @return {Object}
96 */
97 module.exports = function(custom) {
98 return merge({}, custom, DEFAULTS, customizer);
99 };
1 var common = require('./common');
2
3 // Runs default testing configuration in multiple environments.
4
5 module.exports = function(config) {
6
7 // Travis CI should run in its available Firefox headless browser.
8 if (process.env.TRAVIS) {
9
10 config.set(common({
11 browsers: ['Firefox'],
12 plugins: ['karma-firefox-launcher']
13 }))
14 } else {
15 config.set(common({
16
17 frameworks: ['detectBrowsers'],
18
19 plugins: [
20 'karma-chrome-launcher',
21 'karma-detect-browsers',
22 'karma-firefox-launcher',
23 'karma-ie-launcher',
24 'karma-safari-launcher'
25 ],
26
27 detectBrowsers: {
28 // disable safari as it was not previously supported and causes test failures
29 postDetection: function(availableBrowsers) {
30 var safariIndex = availableBrowsers.indexOf('Safari');
31 if(safariIndex !== -1) {
32 availableBrowsers.splice(safariIndex, 1);
33 }
34 return availableBrowsers;
35 },
36 usePhantomJS: false
37 }
38 }));
39 }
40 };
1 var common = require('./common');
2
3 module.exports = function(config) {
4 config.set(common({
5 plugins: ['karma-firefox-launcher'],
6 browsers: ['Firefox']
7 }));
8 };
1 var common = require('./common');
2
3 module.exports = function(config) {
4 config.set(common({
5 plugins: ['karma-ie-launcher'],
6 browsers: ['IE']
7 }));
8 };
1 var common = require('./common');
2
3 module.exports = function(config) {
4 config.set(common({
5 plugins: ['karma-safari-launcher'],
6 browsers: ['Safari']
7 }));
8 };
1 // Karma example configuration file
2 // NOTE: To configure Karma tests, do the following:
3 // 1. Copy this file and rename the copy with a .conf.js extension, for example: karma.conf.js
4 // 2. Configure the properties below in your conf.js copy
5 // 3. Run your tests
6
7 module.exports = function(config) {
8 config.set({
9 // base path, that will be used to resolve files and exclude
10 basePath: '',
11
12 frameworks: ['qunit'],
13
14 // Set autoWatch to true if you plan to run `grunt karma` continuously, to automatically test changes as you make them.
15 autoWatch: false,
16
17 // Setting singleRun to true here will start up your specified browsers, run tests, and then shut down the browsers. Helpful to have in a CI environment, where you don't want to leave browsers running continuously.
18 singleRun: true,
19
20 // Start these browsers, currently available:
21 // - Chrome
22 // - ChromeCanary
23 // - Firefox
24 // - Opera
25 // - Safari (only Mac)
26 // - PhantomJS
27 // - IE (only Windows)
28 // Example usage:
29 // browsers: [],
30 // List of files / patterns to load in the browser
31 // Add any new src files to this list.
32 // If you add new unit tests, they will be picked up automatically by Karma,
33 // unless you've added them to a nested directory, in which case you should
34 // add their paths to this list.
35
36 files: [
37 '../node_modules/sinon/pkg/sinon.js',
38 '../node_modules/video.js/dist/video-js.css',
39 '../node_modules/video.js/dist/video.js',
40 '../node_modules/videojs-contrib-media-sources/src/videojs-media-sources.js',
41 '../node_modules/pkcs7/dist/pkcs7.unpad.js',
42 '../test/karma-qunit-shim.js',
43 '../src/videojs-hls.js',
44 '../src/stream.js',
45 '../src/m3u8/m3u8-parser.js',
46 '../src/xhr.js',
47 '../src/playlist.js',
48 '../src/playlist-loader.js',
49 '../src/decrypter.js',
50 '../tmp/manifests.js',
51 '../tmp/expected.js',
52 'tsSegment-bc.js',
53 '../src/bin-utils.js',
54 '../test/*.js',
55 ],
56
57 plugins: [
58 'karma-qunit',
59 'karma-chrome-launcher',
60 'karma-firefox-launcher',
61 'karma-ie-launcher',
62 'karma-opera-launcher',
63 'karma-phantomjs-launcher',
64 'karma-safari-launcher'
65 ],
66
67 // list of files to exclude
68 exclude: [
69
70 ],
71
72
73 // test results reporter to use
74 // possible values: 'dots', 'progress', 'junit'
75 reporters: ['progress'],
76
77
78 // web server port
79 port: 9876,
80
81
82 // cli runner port
83 runnerPort: 9100,
84
85
86 // enable / disable colors in the output (reporters and logs)
87 colors: true,
88
89
90 // level of logging
91 // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
92 logLevel: config.LOG_DISABLE,
93
94 // If browser does not capture in given timeout [ms], kill it
95 captureTimeout: 60000
96 });
97 };
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
13 M3U8 Test Suite 13 M3U8 Test Suite
14 */ 14 */
15 15
16 module('LineStream', { 16 QUnit.module('LineStream', {
17 setup: function() { 17 setup: function() {
18 lineStream = new LineStream(); 18 lineStream = new LineStream();
19 } 19 }
...@@ -83,7 +83,7 @@ ...@@ -83,7 +83,7 @@
83 strictEqual(2, permanentLines.length, 'new events are still received'); 83 strictEqual(2, permanentLines.length, 'new events are still received');
84 }); 84 });
85 85
86 module('ParseStream', { 86 QUnit.module('ParseStream', {
87 setup: function() { 87 setup: function() {
88 lineStream = new LineStream(); 88 lineStream = new LineStream();
89 parseStream = new ParseStream(); 89 parseStream = new ParseStream();
...@@ -622,13 +622,13 @@ ...@@ -622,13 +622,13 @@
622 ok(!event, 'no event is triggered'); 622 ok(!event, 'no event is triggered');
623 }); 623 });
624 624
625 module('m3u8 parser'); 625 QUnit.module('m3u8 parser');
626 626
627 test('can be constructed', function() { 627 test('can be constructed', function() {
628 notStrictEqual(new Parser(), undefined, 'parser is defined'); 628 notStrictEqual(new Parser(), undefined, 'parser is defined');
629 }); 629 });
630 630
631 module('m3u8s'); 631 QUnit.module('m3u8s');
632 632
633 test('parses static manifests as expected', function() { 633 test('parses static manifests as expected', function() {
634 var key; 634 var key;
......
1 <!doctype html>
2 <html>
3 <head>
4 <title>MPEG-TS Parser Performance Workbench</title>
5 <!-- video.js -->
6 <script src="../node_modules/video.js/video.dev.js"></script>
7
8 <!-- HLS plugin -->
9 <script src="../src/video-js-hls.js"></script>
10 <script src="../src/flv-tag.js"></script>
11 <script src="../src/exp-golomb.js"></script>
12 <script src="../src/h264-stream.js"></script>
13 <script src="../src/aac-stream.js"></script>
14 <script src="../src/segment-parser.js"></script>
15
16 <!-- MPEG-TS segment -->
17 <script src="tsSegment-bc.js"></script>
18 <style>
19 .desc {
20 background-color: #ddd;
21 border: thin solid #333;
22 padding: 8px;
23 }
24 </style>
25 </head>
26 <body>
27 <p class="desc">Select your number of iterations and then press "Run" to begin parsing MPEG-TS packets into FLV tags. This page can be handy for identifying segment parser performance bottlenecks.</p>
28 <form>
29 <input name="iterations" min="1" type="number" value="1">
30 <button type="sumbit">Run</button>
31 </form>
32 <table>
33 <thead>
34 <th>Iterations</th><th>Time</th><th>MB/second</th>
35 </thead>
36 <tbody class="results"></tbody>
37 </table>
38 <script>
39 var
40 button = document.querySelector('button'),
41 input = document.querySelector('input'),
42 results = document.querySelector('.results'),
43
44 reportResults = function(count, elapsed) {
45 var
46 row = document.createElement('tr'),
47 countCell = document.createElement('td'),
48 elapsedCell = document.createElement('td'),
49 throughputCell = document.createElement('td');
50
51 countCell.innerText = count;
52 elapsedCell.innerText = elapsed;
53 throughputCell.innerText = (((bcSegment.byteLength * count * 1000) / elapsed) / (Math.pow(2, 20))).toFixed(3);
54 row.appendChild(countCell);
55 row.appendChild(elapsedCell);
56 row.appendChild(throughputCell);
57
58 results.insertBefore(row, results.firstChild);
59 };
60
61 button.addEventListener('click', function(event) {
62 var
63 iterations = input.value,
64 parser = new window.videojs.hls.SegmentParser(),
65 start;
66
67 // setup
68 start = +new Date();
69
70 while (iterations--) {
71
72 // parse the segment
73 parser.parseSegmentBinaryData(window.bcSegment);
74
75 // finalize all the FLV tags
76 while (parser.tagsAvailable()) {
77 parser.getNextTag();
78 }
79 }
80
81 // report
82 reportResults(input.value, (+new Date()) - start);
83
84 // don't actually submit the form
85 event.preventDefault();
86 }, false);
87 </script>
88 </body>
89 </html>
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
16 .join('/'); 16 .join('/');
17 }; 17 };
18 18
19 module('Playlist Loader', { 19 QUnit.module('Playlist Loader', {
20 setup: function() { 20 setup: function() {
21 // fake XHRs 21 // fake XHRs
22 sinonXhr = sinon.useFakeXMLHttpRequest(); 22 sinonXhr = sinon.useFakeXMLHttpRequest();
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
3 'use strict'; 3 'use strict';
4 var Playlist = videojs.Hls.Playlist; 4 var Playlist = videojs.Hls.Playlist;
5 5
6 module('Playlist Duration'); 6 QUnit.module('Playlist Duration');
7 7
8 test('total duration for live playlists is Infinity', function() { 8 test('total duration for live playlists is Infinity', function() {
9 var duration = Playlist.duration({ 9 var duration = Playlist.duration({
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
16 equal(duration, Infinity, 'duration is infinity'); 16 equal(duration, Infinity, 'duration is infinity');
17 }); 17 });
18 18
19 module('Playlist Interval Duration'); 19 QUnit.module('Playlist Interval Duration');
20 20
21 test('accounts for non-zero starting VOD media sequences', function() { 21 test('accounts for non-zero starting VOD media sequences', function() {
22 var duration = Playlist.duration({ 22 var duration = Playlist.duration({
...@@ -266,7 +266,7 @@ ...@@ -266,7 +266,7 @@
266 equal(Playlist.duration(playlist, -1), 0, 'negative length duration is zero'); 266 equal(Playlist.duration(playlist, -1), 0, 'negative length duration is zero');
267 }); 267 });
268 268
269 module('Playlist Seekable'); 269 QUnit.module('Playlist Seekable');
270 270
271 test('calculates seekable time ranges from the available segments', function() { 271 test('calculates seekable time ranges from the available segments', function() {
272 var playlist = { 272 var playlist = {
......
1 import document from 'global/document';
2
3 import QUnit from 'qunit';
4 import sinon from 'sinon';
5 import videojs from 'video.js';
6
7 QUnit.module('videojs-contrib-hls - sanity', {
8 beforeEach() {
9 this.fixture = document.getElementById('qunit-fixture');
10 this.video = document.createElement('video');
11 this.fixture.appendChild(this.video);
12 this.player = videojs(this.video);
13
14 // Mock the environment's timers because certain things - particularly
15 // player readiness - are asynchronous in video.js 5.
16 this.clock = sinon.useFakeTimers();
17 },
18
19 afterEach() {
20
21 // The clock _must_ be restored before disposing the player; otherwise,
22 // certain timeout listeners that happen inside video.js may throw errors.
23 this.clock.restore();
24 this.player.dispose();
25 }
26 });
27
28 QUnit.test('the environment is sane', function(assert) {
29 assert.strictEqual(typeof Array.isArray, 'function', 'es5 exists');
30 assert.strictEqual(typeof sinon, 'object', 'sinon exists');
31 assert.strictEqual(typeof videojs, 'function', 'videojs exists');
32 assert.strictEqual(typeof videojs.MediaSource, 'object', 'MediaSource is an object');
33 assert.strictEqual(typeof videojs.URL, 'object', 'URL is an object');
34 assert.strictEqual(typeof videojs.Hls, 'object', 'Hls is an object');
35 assert.strictEqual(typeof videojs.HlsSourceHandler,'function', 'HlsSourceHandler is a function');
36 assert.strictEqual(typeof videojs.HlsHandler, 'function', 'HlsHandler is a function');
37 });
1 <!DOCTYPE html>
2 <html>
3 <head>
4 <meta charset="utf-8">
5 <title>video.js HLS Plugin Test Suite</title>
6 <!-- Load sinon server for fakeXHR -->
7 <script src="../node_modules/sinon/pkg/sinon.js"></script>
8
9 <!-- Load local QUnit. -->
10 <link rel="stylesheet" href="../node_modules/qunitjs/qunit/qunit.css" media="screen">
11 <script src="../node_modules/qunitjs/qunit/qunit.js"></script>
12
13 <!-- video.js -->
14 <script src="../node_modules/video.js/dist/video.js"></script>
15 <link rel="stylesheet" href="../node_modules/video.js/dist/video-js.css" media="screen">
16 <script src="../node_modules/videojs-contrib-media-sources/src/videojs-media-sources.js"></script>
17
18 <!-- HLS plugin -->
19 <script src="../src/videojs-hls.js"></script>
20 <script src="../src/xhr.js"></script>
21 <script src="../src/stream.js"></script>
22
23 <!-- M3U8 -->
24 <script src="../src/m3u8/m3u8-parser.js"></script>
25 <script src="../src/playlist.js"></script>
26 <script src="../src/playlist-loader.js"></script>
27 <script src="../node_modules/pkcs7/dist/pkcs7.unpad.js"></script>
28 <script src="../src/decrypter.js"></script>
29 <!-- M3U8 TEST DATA -->
30 <script src="../tmp/manifests.js"></script>
31 <script src="../tmp/expected.js"></script>
32
33 <!-- M3U8 -->
34 <!-- SEGMENT -->
35 <script src="tsSegment-bc.js"></script>
36 <script src="../src/bin-utils.js"></script>
37
38 <!-- Test cases -->
39 <script>
40 module('environment');
41 test('is sane', function() {
42 expect(1);
43 ok(true);
44 });
45 </script>
46 <script src="videojs-hls_test.js"></script>
47 <script src="m3u8_test.js"></script>
48 <script src="playlist_test.js"></script>
49 <script src="playlist-loader_test.js"></script>
50 <script src="decrypter_test.js"></script>
51 </head>
52 <body>
53 <div id="qunit"></div>
54 <div id="qunit-fixture">
55 <span>test markup</span>
56 </div>
57 </body>
58 </html>
...@@ -206,7 +206,7 @@ var ...@@ -206,7 +206,7 @@ var
206 206
207 MockMediaSource.open = function() {}; 207 MockMediaSource.open = function() {};
208 208
209 module('HLS', { 209 QUnit.module('HLS', {
210 beforeEach: function() { 210 beforeEach: function() {
211 oldMediaSource = videojs.MediaSource; 211 oldMediaSource = videojs.MediaSource;
212 videojs.MediaSource = MockMediaSource; 212 videojs.MediaSource = MockMediaSource;
...@@ -2906,7 +2906,7 @@ test('does not download segments if preload option set to none', function() { ...@@ -2906,7 +2906,7 @@ test('does not download segments if preload option set to none', function() {
2906 equal(requests.length, 0, 'did not download any segments'); 2906 equal(requests.length, 0, 'did not download any segments');
2907 }); 2907 });
2908 2908
2909 module('Buffer Inspection'); 2909 QUnit.module('Buffer Inspection');
2910 2910
2911 test('detects time range end-point changed by updates', function() { 2911 test('detects time range end-point changed by updates', function() {
2912 var edge; 2912 var edge;
......
...@@ -20,7 +20,7 @@ if (process.env.SAUCE_USERNAME) { ...@@ -20,7 +20,7 @@ if (process.env.SAUCE_USERNAME) {
20 config.maxDuration = 300; 20 config.maxDuration = 300;
21 } 21 }
22 22
23 config.baseUrl = 'http://127.0.0.1:9999/example.html'; 23 config.baseUrl = 'http://127.0.0.1:9999/';
24 config.specs = ['spec.js']; 24 config.specs = ['spec.js'];
25 25
26 config.framework = 'jasmine2'; 26 config.framework = 'jasmine2';
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
12 12
13 <link rel="stylesheet" href="css/normalize.min.css"> 13 <link rel="stylesheet" href="css/normalize.min.css">
14 <link rel="stylesheet" href="css/main.css"> 14 <link rel="stylesheet" href="css/main.css">
15 <link rel="stylesheet" href="../../node_modules/video.js/dist/video-js/video-js.css"> 15 <link rel="stylesheet" href="../../node_modules/video.js/dist/video-js.css">
16 16
17 <script src="js/vendor/modernizr-2.6.2.min.js"></script> 17 <script src="js/vendor/modernizr-2.6.2.min.js"></script>
18 </head> 18 </head>
...@@ -120,13 +120,17 @@ ...@@ -120,13 +120,17 @@
120 <script src="../../node_modules/sinon/lib/sinon/util/fake_timers.js"></script> 120 <script src="../../node_modules/sinon/lib/sinon/util/fake_timers.js"></script>
121 <script src="js/vendor/d3.min.js"></script> 121 <script src="js/vendor/d3.min.js"></script>
122 122
123 <script src="../../node_modules/video.js/dist/video-js/video.js"></script> 123 <script src="/node_modules/video.js/dist/video.js"></script>
124 <script src="../../node_modules/videojs-contrib-media-sources/src/videojs-media-sources.js"></script> 124 <script src="/node_modules/videojs-contrib-media-sources/dist/videojs-media-sources.js"></script>
125 <script src="../../src/videojs-hls.js"></script> 125 <script src="/node_modules/pkcs7/dist/pkcs7.unpad.js"></script>
126 <script src="../../src/xhr.js"></script> 126 <script src="/src/videojs-hls.js"></script>
127 <script src="../../src/stream.js"></script> 127 <script src="/src/xhr.js"></script>
128 <script src="../../src/m3u8/m3u8-parser.js"></script> 128 <script src="/src/stream.js"></script>
129 <script src="../../src/playlist-loader.js"></script> 129 <script src="/src/m3u8/m3u8-parser.js"></script>
130 <script src="/src/playlist.js"></script>
131 <script src="/src/playlist-loader.js"></script>
132 <script src="/src/decrypter.js"></script>
133 <script src="/src/bin-utils.js"></script>
130 134
131 <script src="js/switcher.js"></script> 135 <script src="js/switcher.js"></script>
132 </body> 136 </body>
......
...@@ -142,6 +142,7 @@ ...@@ -142,6 +142,7 @@
142 // mock out the environment 142 // mock out the environment
143 clock = sinon.useFakeTimers(); 143 clock = sinon.useFakeTimers();
144 fakeXhr = sinon.useFakeXMLHttpRequest(); 144 fakeXhr = sinon.useFakeXMLHttpRequest();
145 videojs.xhr.XMLHttpRequest = fakeXhr;
145 requests = []; 146 requests = [];
146 fakeXhr.onCreate = function(xhr) { 147 fakeXhr.onCreate = function(xhr) {
147 xhr.startTime = +new Date(); 148 xhr.startTime = +new Date();
...@@ -156,7 +157,6 @@ ...@@ -156,7 +157,6 @@
156 video.controls = true; 157 video.controls = true;
157 fixture.appendChild(video); 158 fixture.appendChild(video);
158 player = videojs(video, { 159 player = videojs(video, {
159 techOrder: ['hls'],
160 sources: [{ 160 sources: [{
161 src: 'http://example.com/master.m3u8', 161 src: 'http://example.com/master.m3u8',
162 type: 'application/x-mpegurl' 162 type: 'application/x-mpegurl'
...@@ -295,6 +295,8 @@ ...@@ -295,6 +295,8 @@
295 done(null, results); 295 done(null, results);
296 }, 0); 296 }, 0);
297 }); 297 });
298 /// trigger the ready function through set timeout
299 clock.tick(1);
298 }; 300 };
299 runButton = document.getElementById('run-simulation'); 301 runButton = document.getElementById('run-simulation');
300 runButton.addEventListener('click', function() { 302 runButton.addEventListener('click', function() {
......