Merge pull request #530 from 'BrandonOCasey-plugin-generator-squash'
Showing
161 changed files
with
686 additions
and
955 deletions
.editorconfig
0 → 100644
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 | ... | ... |
.jshintrc
deleted
100644 → 0
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 | 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 | ... | ... |
Gruntfile.js
deleted
100644 → 0
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,22 +41,32 @@ | ... | @@ -70,22 +41,32 @@ |
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'); | 58 | // hook up the video switcher |
77 | 59 | var loadUrl = document.getElementById('load-url'); | |
78 | // hook up the video switcher | 60 | var url = document.getElementById('url'); |
79 | var loadUrl = document.getElementById('load-url'); | 61 | loadUrl.addEventListener('submit', function(event) { |
80 | var url = document.getElementById('url'); | 62 | event.preventDefault(); |
81 | loadUrl.addEventListener('submit', function(event) { | 63 | player.src({ |
82 | event.preventDefault(); | 64 | src: url.value, |
83 | player.src({ | 65 | type: 'application/x-mpegURL' |
84 | src: url.value, | 66 | }); |
85 | type: 'application/x-mpegURL' | 67 | return false; |
86 | }); | 68 | }); |
87 | return false; | 69 | }(window, window.videojs)); |
88 | }); | ||
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.4", | 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 | } | ... | ... |
scripts/banner.ejs
0 → 100644
scripts/build-test.js
0 → 100644
scripts/manifest-data.js
0 → 100644
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 | console.log(e); | ||
68 | } | ||
69 | try { | ||
70 | fs.unlinkSync(expectedFilepath); | ||
71 | } catch(e) { | ||
72 | console.log(e); | ||
73 | } | ||
74 | } | ||
75 | |||
76 | module.exports = { | ||
77 | build: build, | ||
78 | watch: watch, | ||
79 | clean: clean | ||
80 | }; |
scripts/server.js
0 → 100644
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 | }); |
scripts/watch-test.js
0 → 100644
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 | }); |
... | @@ -90,6 +90,7 @@ | ... | @@ -90,6 +90,7 @@ |
90 | dispose, | 90 | dispose, |
91 | mediaUpdateTimeout, | 91 | mediaUpdateTimeout, |
92 | request, | 92 | request, |
93 | playlistRequestError, | ||
93 | haveMetadata; | 94 | haveMetadata; |
94 | 95 | ||
95 | PlaylistLoader.prototype.init.call(this); | 96 | PlaylistLoader.prototype.init.call(this); |
... | @@ -102,27 +103,36 @@ | ... | @@ -102,27 +103,36 @@ |
102 | throw new Error('A non-empty playlist URL is required'); | 103 | throw new Error('A non-empty playlist URL is required'); |
103 | } | 104 | } |
104 | 105 | ||
106 | playlistRequestError = function(xhr, url, startingState) { | ||
107 | loader.setBandwidth(request || xhr); | ||
108 | |||
109 | // any in-flight request is now finished | ||
110 | request = null; | ||
111 | |||
112 | if (startingState) { | ||
113 | loader.state = startingState; | ||
114 | } | ||
115 | |||
116 | loader.error = { | ||
117 | playlist: loader.master.playlists[url], | ||
118 | status: xhr.status, | ||
119 | message: 'HLS playlist request error at URL: ' + url, | ||
120 | responseText: xhr.responseText, | ||
121 | code: (xhr.status >= 500) ? 4 : 2 | ||
122 | }; | ||
123 | loader.trigger('error'); | ||
124 | }; | ||
125 | |||
105 | // update the playlist loader's state in response to a new or | 126 | // update the playlist loader's state in response to a new or |
106 | // updated playlist. | 127 | // updated playlist. |
107 | haveMetadata = function(error, xhr, url) { | 128 | |
129 | haveMetadata = function(xhr, url) { | ||
108 | var parser, refreshDelay, update; | 130 | var parser, refreshDelay, update; |
109 | 131 | ||
110 | loader.setBandwidth(request || xhr); | 132 | loader.setBandwidth(request || xhr); |
111 | 133 | ||
112 | // any in-flight request is now finished | 134 | // any in-flight request is now finished |
113 | request = null; | 135 | request = null; |
114 | |||
115 | if (error) { | ||
116 | loader.error = { | ||
117 | playlist: loader.master.playlists[url], | ||
118 | status: xhr.status, | ||
119 | message: 'HLS playlist request error at URL: ' + url, | ||
120 | responseText: xhr.responseText, | ||
121 | code: (xhr.status >= 500) ? 4 : 2 | ||
122 | }; | ||
123 | return loader.trigger('error'); | ||
124 | } | ||
125 | |||
126 | loader.state = 'HAVE_METADATA'; | 136 | loader.state = 'HAVE_METADATA'; |
127 | 137 | ||
128 | parser = new videojs.m3u8.Parser(); | 138 | parser = new videojs.m3u8.Parser(); |
... | @@ -252,12 +262,12 @@ | ... | @@ -252,12 +262,12 @@ |
252 | uri: resolveUrl(loader.master.uri, playlist.uri), | 262 | uri: resolveUrl(loader.master.uri, playlist.uri), |
253 | withCredentials: withCredentials | 263 | withCredentials: withCredentials |
254 | }, function(error, request) { | 264 | }, function(error, request) { |
255 | haveMetadata(error, request, playlist.uri); | ||
256 | |||
257 | if (error) { | 265 | if (error) { |
258 | return; | 266 | return playlistRequestError(request, playlist.uri, startingState); |
259 | } | 267 | } |
260 | 268 | ||
269 | haveMetadata(request, playlist.uri); | ||
270 | |||
261 | // fire loadedmetadata the first time a media playlist is loaded | 271 | // fire loadedmetadata the first time a media playlist is loaded |
262 | if (startingState === 'HAVE_MASTER') { | 272 | if (startingState === 'HAVE_MASTER') { |
263 | loader.trigger('loadedmetadata'); | 273 | loader.trigger('loadedmetadata'); |
... | @@ -289,7 +299,10 @@ | ... | @@ -289,7 +299,10 @@ |
289 | uri: resolveUrl(loader.master.uri, loader.media().uri), | 299 | uri: resolveUrl(loader.master.uri, loader.media().uri), |
290 | withCredentials: withCredentials | 300 | withCredentials: withCredentials |
291 | }, function(error, request) { | 301 | }, function(error, request) { |
292 | haveMetadata(error, request, loader.media().uri); | 302 | if (error) { |
303 | return playlistRequestError(request, loader.media().uri); | ||
304 | } | ||
305 | haveMetadata(request, loader.media().uri); | ||
293 | }); | 306 | }); |
294 | }); | 307 | }); |
295 | 308 | ||
... | @@ -349,7 +362,7 @@ | ... | @@ -349,7 +362,7 @@ |
349 | }] | 362 | }] |
350 | }; | 363 | }; |
351 | loader.master.playlists[srcUrl] = loader.master.playlists[0]; | 364 | loader.master.playlists[srcUrl] = loader.master.playlists[0]; |
352 | haveMetadata(null, req, srcUrl); | 365 | haveMetadata(req, srcUrl); |
353 | return loader.trigger('loadedmetadata'); | 366 | return loader.trigger('loadedmetadata'); |
354 | }); | 367 | }); |
355 | }; | 368 | }; | ... | ... |
test/.jshintrc
deleted
100644 → 0
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 | } |
File moved
... | @@ -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 | }, | ... | ... |
test/index.html
0 → 100644
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> |
test/karma-qunit-shim.js
deleted
100644 → 0
test/karma.conf.js
deleted
100644 → 0
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 | }; |
test/karma/chrome.js
0 → 100644
test/karma/common.js
0 → 100644
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 | }; |
test/karma/detected.js
0 → 100644
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 | }; |
test/karma/firefox.js
0 → 100644
test/karma/ie.js
0 → 100644
test/karma/safari.js
0 → 100644
test/localkarma.conf.js
deleted
100644 → 0
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; | ... | ... |
test/perf.html
deleted
100644 → 0
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 = { | ... | ... |
test/sanity.test.js
0 → 100644
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 | }); |
test/videojs-hls.html
deleted
100644 → 0
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; |
... | @@ -1296,6 +1296,28 @@ test('blacklists switching from video-only playlists to video+audio', function() | ... | @@ -1296,6 +1296,28 @@ test('blacklists switching from video-only playlists to video+audio', function() |
1296 | equal(videoAudioPlaylist.excludeUntil, Infinity, 'excluded incompatible playlist'); | 1296 | equal(videoAudioPlaylist.excludeUntil, Infinity, 'excluded incompatible playlist'); |
1297 | }); | 1297 | }); |
1298 | 1298 | ||
1299 | test('After an initial media playlist 404s, we fire loadedmetadata once we successfully load a playlist', function() { | ||
1300 | var count = 0; | ||
1301 | player.src({ | ||
1302 | src: 'manifest/master.m3u8', | ||
1303 | type: 'application/vnd.apple.mpegurl' | ||
1304 | }); | ||
1305 | openMediaSource(player); | ||
1306 | player.tech_.hls.bandwidth = 20000; | ||
1307 | player.on('loadedmetadata', function() { | ||
1308 | count += 1; | ||
1309 | }); | ||
1310 | standardXHRResponse(requests.shift()); //master | ||
1311 | equal(count, 0, | ||
1312 | 'loadedMedia not triggered before requesting playlist'); | ||
1313 | requests.shift().respond(404); //media | ||
1314 | equal(count, 0, | ||
1315 | 'loadedMedia not triggered after playlist 404'); | ||
1316 | standardXHRResponse(requests.shift()); //media | ||
1317 | equal(count, 1, | ||
1318 | 'loadedMedia triggered after successful recovery from 404'); | ||
1319 | }); | ||
1320 | |||
1299 | test('does not blacklist compatible H.264 codec strings', function() { | 1321 | test('does not blacklist compatible H.264 codec strings', function() { |
1300 | var master; | 1322 | var master; |
1301 | player.src({ | 1323 | player.src({ |
... | @@ -2884,7 +2906,7 @@ test('does not download segments if preload option set to none', function() { | ... | @@ -2884,7 +2906,7 @@ test('does not download segments if preload option set to none', function() { |
2884 | equal(requests.length, 0, 'did not download any segments'); | 2906 | equal(requests.length, 0, 'did not download any segments'); |
2885 | }); | 2907 | }); |
2886 | 2908 | ||
2887 | module('Buffer Inspection'); | 2909 | QUnit.module('Buffer Inspection'); |
2888 | 2910 | ||
2889 | test('detects time range end-point changed by updates', function() { | 2911 | test('detects time range end-point changed by updates', function() { |
2890 | var edge; | 2912 | var edge; | ... | ... |
No preview for this file type
No preview for this file type
No preview for this file type
File moved
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
... | @@ -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'; | ... | ... |
test/manifest/extXPlaylistTypeInvalidPlaylist.js
→
utils/manifest/extXPlaylistTypeInvalidPlaylist.js
File moved
File moved
File moved
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
test/manifest/playlist_allow_cache_template.m3u8
→
utils/manifest/playlist_allow_cache_template.m3u8
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
No preview for this file type
-
Please register or sign in to post a comment