b0caca88 by David LaPalomento

Merge pull request #530 from 'BrandonOCasey-plugin-generator-squash'

2 parents 25033e31 8582ba38
Showing 161 changed files with 686 additions and 955 deletions
# http://editorconfig.org
root = true
[*]
charset = utf-8
end_of_line = lf
indent_style = space
indent_size = 2
insert_final_newline = true
trim_trailing_whitespace = true
[*.md]
trim_trailing_whitespace = false
# OS
Thumbs.db
ehthumbs.db
Desktop.ini
.DS_Store
dist/*
/node_modules/
._*
# Editors
*~
*.iml
*.ipr
*.iws
*.swp
tmp/**.*.swo
*.tmproj
*.tmproject
*.sublime-*
.idea/
.project/
.settings/
.vscode/
# Logs
logs
*.log
npm-debug.log*
# Dependency directories
bower_components/
node_modules/
# Yeoman meta-data
.yo-rc.json
# Build-related directories
dist/
dist-test/
docs/api/
es5/
tmp
test/data/manifests.js
test/data/expected.js
......
{
"curly": true,
"eqeqeq": true,
"immed": true,
"latedef": true,
"newcap": true,
"noarg": true,
"sub": true,
"undef": true,
"unused": true,
"boss": true,
"eqnull": true,
"node": true,
"camelcase": true,
"nonew": true,
"quotmark": "single",
"trailing": true,
"maxlen": 80
}
*~
*.iml
*.swp
tmp/**
test/**
# Intentionally left blank, so that npm does not ignore anything by default,
# but relies on the package.json "files" array to explicitly define what ends
# up in the package.
......
language: node_js
sudo: false
language: node_js
node_js:
- "stable"
install:
- npm install -g grunt-cli && npm install
- 'node'
- '4.2'
- '0.12'
- '0.10'
notifications:
hipchat:
rooms:
......@@ -12,12 +13,7 @@ notifications:
channels:
- "chat.freenode.net#videojs"
use_notice: true
# Set up a virtual screen for Firefox.
before_script:
- export DISPLAY=:99.0
- sh -e /etc/init.d/xvfb start
env:
global:
- secure: dM7svnHPPu5IiUMeFWW5zg+iuWNpwt6SSDi3MmVvhSclNMRLesQoRB+7Qq5J/LiKhmjpv1/GlNVV0CTsHMRhZNwQ3fo38eEuTXv99aAflEITXwSEh/VntKViHbGFubn06EnVkJoH6MX3zJ6kbiwc2QdSQbywKzS6l6quUEpWpd0=
- secure: AnduYGXka5ft1x7V3SuVYqvlKLvJGhUaRNFdy4UDJr3ZVuwpQjE4TMDG8REmJIJvXfHbh4qY4N1cFSGnXkZ4bH21Xk0v9DLhsxbarKz+X2BvPgXs+Af9EQ6vLEy/5S1vMLxfT5+y+Ec5bVNGOsdUZby8Y21CRzSg6ADN9kwPGlE=
addons:
sauce_connect: true
......
'use strict';
var
basename = require('path').basename,
mediaSourcesPath = 'node_modules/videojs-contrib-media-sources/dist/',
mediaSourcesDebug = mediaSourcesPath + 'videojs-media-sources.js';
module.exports = function(grunt) {
var pkg = grunt.file.readJSON('package.json');
// Project configuration.
grunt.initConfig({
// Metadata.
pkg: pkg,
banner: '/*! <%= pkg.name %> - v<%= pkg.version %> - ' +
'<%= grunt.template.today("yyyy-mm-dd") %>\n' +
'* Copyright (c) <%= grunt.template.today("yyyy") %> Brightcove;' +
' Licensed <%= _.pluck(pkg.licenses, "type").join(", ") %> */\n',
// Task configuration.
clean: {
files: ['build', 'dist', 'tmp']
},
concat: {
options: {
banner: '<%= banner %>',
stripBanners: true
},
dist: {
nonull: true,
src: [
mediaSourcesDebug,
'src/videojs-hls.js',
'src/xhr.js',
'src/stream.js',
'src/m3u8/m3u8-parser.js',
'src/playlist.js',
'src/playlist-loader.js',
'node_modules/pkcs7/dist/pkcs7.unpad.js',
'src/decrypter.js'
],
dest: 'dist/videojs.hls.js'
}
},
uglify: {
options: {
banner: '<%= banner %>'
},
dist: {
src: '<%= concat.dist.dest %>',
dest: 'dist/videojs.hls.min.js'
}
},
jshint: {
gruntfile: {
options: {
jshintrc: '.jshintrc'
},
src: 'Gruntfile.js'
},
src: {
options: {
jshintrc: 'src/.jshintrc'
},
src: ['src/**/*.js']
},
test: {
options: {
jshintrc: 'test/.jshintrc'
},
src: ['test/**/*.js',
'!test/tsSegment.js',
'!test/fixtures/*.js',
'!test/manifest/**',
'!test/muxer/**',
'!test/switcher/**']
}
},
connect: {
dev: {
options: {
hostname: '*',
port: 9999,
keepalive: true
}
},
test: {
options: {
hostname: '*',
port: 9999
}
}
},
open : {
dev : {
path: 'http://127.0.0.1:<%= connect.dev.options.port %>/example.html',
app: 'Google Chrome'
}
},
watch: {
build: {
files: '<%= concat.dist.src %>',
tasks: ['clean', 'concat', 'uglify']
},
gruntfile: {
files: '<%= jshint.gruntfile.src %>',
tasks: ['jshint:gruntfile']
},
src: {
files: '<%= jshint.src.src %>',
tasks: ['jshint:src', 'test']
},
test: {
files: '<%= jshint.test.src %>',
tasks: ['jshint:test', 'test']
}
},
concurrent: {
dev: {
tasks: ['connect', 'open', 'watch'],
options: {
logConcurrentOutput: true
}
}
},
version: {
project: {
src: ['package.json']
}
},
'github-release': {
options: {
repository: 'videojs/videojs-contrib-hls',
auth: {
user: process.env.VJS_GITHUB_USER,
password: process.env.VJS_GITHUB_TOKEN
},
release: {
'tag_name': 'v' + pkg.version,
name: pkg.version,
body: require('chg').find(pkg.version).changesRaw
}
},
files: {
'dist': ['videojs.hls.min.js']
}
},
karma: {
options: {
frameworks: ['qunit']
},
saucelabs: {
configFile: 'test/karma.conf.js',
autoWatch: true
},
dev: {
browsers: ['Chrome', 'Safari', 'Firefox',
'Opera', 'IE', 'PhantomJS', 'ChromeCanary'],
configFile: 'test/localkarma.conf.js',
autoWatch: true
},
chromecanary: {
options: {
browsers: ['ChromeCanary'],
configFile: 'test/localkarma.conf.js',
autoWatch: true
}
},
phantomjs: {
options: {
browsers: ['PhantomJS'],
configFile: 'test/localkarma.conf.js',
autoWatch: true
}
},
opera: {
options: {
browsers: ['Opera'],
configFile: 'test/localkarma.conf.js',
autoWatch: true
}
},
chrome: {
options: {
browsers: ['Chrome'],
configFile: 'test/localkarma.conf.js',
autoWatch: true
}
},
safari: {
options: {
browsers: ['Safari'],
configFile: 'test/localkarma.conf.js',
autoWatch: true
}
},
firefox: {
options: {
browsers: ['Firefox'],
configFile: 'test/localkarma.conf.js',
autoWatch: true
}
},
ie: {
options: {
browsers: ['IE'],
configFile: 'test/localkarma.conf.js',
autoWatch: true
}
},
ci: {
configFile: 'test/karma.conf.js',
autoWatch: false
}
},
protractor: {
options: {
configFile: 'test/functional/protractor.config.js',
webdriverManagerUpdate: process.env.TRAVIS ? false : true
},
chrome: {
options: {
args: {
capabilities: {
browserName: 'chrome'
}
}
}
},
firefox: {
options: {
args: {
capabilities: {
browserName: 'firefox'
}
}
}
},
safari: {
options: {
args: {
capabilities: {
browserName: 'safari'
}
}
}
},
ie: {
options: {
args: {
capabilities: {
browserName: 'internet explorer'
}
}
}
},
saucelabs:{}
}
});
// These plugins provide necessary tasks.
grunt.loadNpmTasks('grunt-karma');
grunt.loadNpmTasks('grunt-contrib-clean');
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-jshint');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-contrib-connect');
grunt.loadNpmTasks('grunt-open');
grunt.loadNpmTasks('grunt-concurrent');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-github-releaser');
grunt.loadNpmTasks('grunt-version');
grunt.loadNpmTasks('grunt-protractor-runner');
grunt.loadNpmTasks('chg');
grunt.registerTask('manifests-to-js', 'Wrap the test fixtures and output' +
' so they can be loaded in a browser',
function() {
var
jsManifests = 'window.manifests = {\n',
jsExpected = 'window.expected = {\n';
grunt.file.recurse('test/manifest/',
function(abspath, root, sub, filename) {
if ((/\.m3u8$/).test(abspath)) {
// translate this manifest
jsManifests += ' \'' + basename(filename, '.m3u8') + '\': ' +
grunt.file.read(abspath)
.split(/\r\n|\n/)
// quote and concatenate
.map(function(line) {
return ' \'' + line + '\\n\' +\n';
}).join('')
// strip leading spaces and the trailing '+'
.slice(4, -3);
jsManifests += ',\n';
}
if ((/\.js$/).test(abspath)) {
// append the expected parse
jsExpected += ' "' + basename(filename, '.js') + '": ' +
grunt.file.read(abspath) + ',\n';
}
});
// clean up and close the objects
jsManifests = jsManifests.slice(0, -2);
jsManifests += '\n};\n';
jsExpected = jsExpected.slice(0, -2);
jsExpected += '\n};\n';
// write out the manifests
grunt.file.write('tmp/manifests.js', jsManifests);
grunt.file.write('tmp/expected.js', jsExpected);
});
// Launch a Development Environment
grunt.registerTask('dev', 'Launching Dev Environment', 'concurrent:dev');
grunt.registerTask('build',
['clean',
'concat',
'uglify']);
// Default task.
grunt.registerTask('default',
['test',
'build']);
// The test task will run `karma:saucelabs` when running in travis,
// otherwise, it'll default to running karma in chrome.
// You can specify which browsers to build with by using grunt-style arguments
// or separating them with a comma:
// grunt test:chrome:firefox # grunt-style
// grunt test:chrome,firefox # comma-separated
grunt.registerTask('test', function() {
var tasks = this.args;
grunt.task.run(['jshint', 'manifests-to-js']);
if (process.env.TRAVIS) {
if (process.env.TRAVIS_PULL_REQUEST === 'false') {
grunt.task.run(['karma:saucelabs']);
grunt.task.run(['connect:test', 'protractor:saucelabs']);
} else {
grunt.task.run(['karma:firefox']);
}
} else {
if (tasks.length === 0) {
tasks.push('chrome');
}
if (tasks.length === 1) {
tasks = tasks[0].split(',');
}
tasks = tasks.reduce(function(acc, el) {
acc.push('karma:' + el);
if (/chrome|firefox|safari|ie/.test(el)) {
acc.push('protractor:' + el);
}
return acc;
}, ['connect:test']);
grunt.task.run(tasks);
}
});
};
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)*
- [video.js HLS Source Handler](#videojs-hls-source-handler)
- [Getting Started](#getting-started)
- [Documentation](#documentation)
- [Options](#options)
- [withCredentials](#withcredentials)
- [Runtime Properties](#runtime-properties)
- [hls.playlists.master](#hlsplaylistsmaster)
- [hls.playlists.media](#hlsplaylistsmedia)
- [hls.segmentXhrTime](#hlssegmentxhrtime)
- [hls.bandwidth](#hlsbandwidth)
- [hls.bytesReceived](#hlsbytesreceived)
- [hls.selectPlaylist](#hlsselectplaylist)
- [Events](#events)
- [loadedmetadata](#loadedmetadata)
- [loadedplaylist](#loadedplaylist)
- [mediachange](#mediachange)
- [In-Band Metadata](#in-band-metadata)
- [Hosting Considerations](#hosting-considerations)
- [Testing](#testing)
- [Release History](#release-history)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
# video.js HLS Source Handler
Play back HLS with video.js, even where it's not natively supported.
......
......@@ -2,31 +2,8 @@
<html>
<head>
<meta charset="utf-8">
<title>video.js HLS Plugin Example</title>
<link href="node_modules/video.js/dist/video-js.css" rel="stylesheet">
<!-- video.js -->
<script src="node_modules/video.js/dist/video.js"></script>
<!-- Media Sources plugin -->
<script src="node_modules/videojs-contrib-media-sources/dist/videojs-media-sources.js"></script>
<!-- HLS plugin -->
<script src="src/videojs-hls.js"></script>
<!-- m3u8 handling -->
<script src="src/xhr.js"></script>
<script src="src/stream.js"></script>
<script src="src/m3u8/m3u8-parser.js"></script>
<script src="src/playlist.js"></script>
<script src="src/playlist-loader.js"></script>
<script src="node_modules/pkcs7/dist/pkcs7.unpad.js"></script>
<script src="src/decrypter.js"></script>
<script src="src/bin-utils.js"></script>
<title>videojs-contrib-hls Demo</title>
<link href="/node_modules/video.js/dist/video-js.css" rel="stylesheet">
<style>
body {
font-family: Arial, sans-serif;
......@@ -52,14 +29,8 @@
<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>
<p>Due to security restrictions in Flash, you will have to load this page over HTTP(S) to see the example in action.</p>
</div>
<video id="video"
class="video-js vjs-default-skin"
height="300"
width="600"
controls>
<source
src="http://solutions.brightcove.com/jwhisenant/hls/apple/bipbop/bipbopall.m3u8"
type="application/x-mpegURL">
<video id="videojs-contrib-hls-player" class="video-js vjs-default-skin" controls>
<source src="http://solutions.brightcove.com/jwhisenant/hls/apple/bipbop/bipbopall.m3u8" type="application/x-mpegURL">
</video>
<form id=load-url>
......@@ -70,22 +41,32 @@
<button type=submit>Load</button>
</form>
<script src="/node_modules/video.js/dist/video.js"></script>
<script src="/node_modules/videojs-contrib-media-sources/dist/videojs-media-sources.js"></script>
<script src="/node_modules/pkcs7/dist/pkcs7.unpad.js"></script>
<script src="/src/videojs-hls.js"></script>
<script src="/src/xhr.js"></script>
<script src="/src/stream.js"></script>
<script src="/src/m3u8/m3u8-parser.js"></script>
<script src="/src/playlist.js"></script>
<script src="/src/playlist-loader.js"></script>
<script src="/src/decrypter.js"></script>
<script src="/src/bin-utils.js"></script>
<script>
videojs.options.flash.swf = 'node_modules/videojs-swf/dist/video-js.swf';
// initialize the player
var player = videojs('video');
// hook up the video switcher
var loadUrl = document.getElementById('load-url');
var url = document.getElementById('url');
loadUrl.addEventListener('submit', function(event) {
event.preventDefault();
player.src({
src: url.value,
type: 'application/x-mpegURL'
(function(window, videojs) {
var player = window.player = videojs('videojs-contrib-hls-player');
// hook up the video switcher
var loadUrl = document.getElementById('load-url');
var url = document.getElementById('url');
loadUrl.addEventListener('submit', function(event) {
event.preventDefault();
player.src({
src: url.value,
type: 'application/x-mpegURL'
});
return false;
});
return false;
});
}(window, window.videojs));
</script>
</body>
</html>
......
{
"name": "videojs-contrib-hls",
"version": "1.3.4",
"version": "1.3.5",
"description": "Play back HLS with video.js, even where it's not natively supported",
"main": "es5/videojs-hls.js",
"engines": {
"node": ">= 0.10.12"
},
......@@ -8,47 +10,116 @@
"type": "git",
"url": "git@github.com:videojs/videojs-contrib-hls.git"
},
"license": "Apache-2.0",
"scripts": {
"test": "grunt test",
"prepublish": "if [ -z \"$TRAVIS\" ]; then grunt; fi"
"prebuild": "npm run clean",
"build": "npm-run-all -p build:*",
"build:manifest": "node -e \"var b=require('./scripts/manifest-data.js'); b.build();\"",
"build:js": "npm-run-all build:js:babel build:js:browserify build:js:bannerize build:js:uglify",
"build:js:babel": "babel src -d es5",
"build:js:bannerize": "bannerize dist/videojs-contrib-hls.js --banner=scripts/banner.ejs",
"build:js:browserify": "browserify . -s src/videojs-hls.js -o dist/videojs-contrib-hls.js",
"build:js:uglify": "uglifyjs dist/videojs-contrib-hls.js --comments --mangle --compress -o dist/videojs-contrib-hls.min.js",
"build:test": "node scripts/build-test.js",
"clean": "npm-run-all clean:*",
"clean:build": "node -e \"var s=require('shelljs'),d=['dist','dist-test','es5'];s.rm('-rf',d);s.mkdir('-p',d);\"",
"clean:manifest": "node -e \"var b=require('./scripts/manifest-data.js'); b.clean();\"",
"docs": "npm-run-all docs:*",
"docs:api": "jsdoc src -r -d docs/api",
"docs:toc": "doctoc README.md",
"lint": "vjsstandard :",
"prestart": "npm-run-all docs build",
"start": "npm-run-all -p start:* watch:*",
"start:serve": "babel-node scripts/server.js",
"pretest": "npm-run-all lint build",
"test": "karma start test/karma/detected.js",
"test:chrome": "npm run pretest && karma start test/karma/chrome.js",
"test:firefox": "npm run pretest && karma start test/karma/firefox.js",
"test:ie": "npm run pretest && karma start test/karma/ie.js",
"test:safari": "npm run pretest && karma start test/karma/safari.js",
"preversion": "npm test",
"version": "npm run build",
"watch": "npm-run-all -p watch:*",
"watch:manifest": "node -e \"var b=require('./scripts/manifest-data.js'); b.watch();\"",
"watch:js": "watchify src/videojs-hls.js -t babelify -v -o dist/videojs-contrib-hls.js",
"watch:test": "node scripts/watch-test.js",
"prepublish": "npm run build"
},
"keywords": [
"videojs",
"videojs-plugin"
],
"devDependencies": {
"chg": "^0.2.0",
"grunt": "^0.4.5",
"grunt-concurrent": "0.4.3",
"grunt-contrib-clean": "~0.4.0",
"grunt-contrib-concat": "~0.3.0",
"grunt-contrib-connect": "~0.6.0",
"grunt-contrib-jshint": "~0.6.0",
"grunt-contrib-uglify": "~0.2.0",
"grunt-contrib-watch": "~0.4.0",
"grunt-github-releaser": "^0.1.17",
"grunt-karma": "~0.6.2",
"grunt-open": "0.2.3",
"grunt-protractor-runner": "forbesjo/grunt-protractor-runner.git#webdriverManagerUpdate",
"grunt-shell": "0.6.1",
"grunt-version": "^1.0.0",
"karma": "~0.10.0",
"karma-chrome-launcher": "~0.1.2",
"karma-firefox-launcher": "~0.1.3",
"karma-ie-launcher": "~0.1.1",
"karma-opera-launcher": "~0.1.0",
"karma-phantomjs-launcher": "^0.1.4",
"karma-qunit": "~0.1.1",
"karma-safari-launcher": "~0.1.1",
"karma-sauce-launcher": "~0.1.8",
"qunitjs": "^1.18.0",
"sinon": "1.10.2",
"video.js": "^5.2.1"
"author": "Brightcove, Inc",
"license": "Apache-2.0",
"browserify": {
"transform": [
"browserify-shim"
]
},
"browserify-shim": {
"qunit": "global:QUnit",
"sinon": "global:sinon",
"video.js": "global:videojs"
},
"vjsstandard": {
"ignore": [
"dist",
"dist-test",
"docs",
"es5",
"test/karma",
"scripts",
"utils",
"test/data"
]
},
"files": [
"CONTRIBUTING.md",
"dist-test/",
"dist/",
"docs/",
"es5/",
"index.html",
"scripts/",
"src/",
"test/",
"utils/"
],
"dependencies": {
"pkcs7": "^0.2.2",
"videojs-contrib-media-sources": "^2.4.0",
"videojs-swf": "^5.0.0"
"pkcs7": "^0.2.3",
"video.js": "^5.0.0",
"videojs-contrib-media-sources": "^2.4.4",
"videojs-swf": "^5.0.1"
},
"devDependencies": {
"babel": "^5.8.0",
"babelify": "^6.0.0",
"bannerize": "^1.0.0",
"browserify": "^11.0.0",
"browserify-shim": "^3.0.0",
"connect": "^3.4.0",
"cowsay": "^1.1.0",
"doctoc": "^0.15.0",
"glob": "^6.0.3",
"global": "^4.3.0",
"jsdoc": "^3.4.0",
"karma": "^0.13.0",
"karma-browserify": "^4.4.0",
"karma-chrome-launcher": "^0.2.0",
"karma-detect-browsers": "^2.0.0",
"karma-firefox-launcher": "^0.1.0",
"karma-ie-launcher": "^0.2.0",
"karma-qunit": "^0.1.9",
"karma-safari-launcher": "^0.1.0",
"lodash-compat": "^3.10.0",
"minimist": "^1.2.0",
"npm-run-all": "^1.2.0",
"portscanner": "^1.0.0",
"qunitjs": "^1.0.0",
"serve-static": "^1.10.0",
"shelljs": "^0.5.3",
"sinon": "1.10.2",
"uglify-js": "^2.5.0",
"videojs-standard": "^4.0.0",
"watchify": "^3.6.0"
}
}
......
/**
* <%- pkg.name %>
* @version <%- pkg.version %>
* @copyright <%- date.getFullYear() %> <%- pkg.author %>
* @license <%- pkg.license %>
*/
var browserify = require('browserify');
var fs = require('fs');
var glob = require('glob');
glob('test/**/*.test.js', function(err, files) {
browserify(files)
.transform('babelify')
.bundle()
.pipe(fs.createWriteStream('dist-test/videojs-contrib-hls.js'));
});
var fs = require('fs');
var path = require('path');
var basePath = path.resolve(__dirname + '/..');
var testDataDir = basePath + '/test/data';
var manifestDir = basePath + '/utils/manifest';
var manifestFilepath = testDataDir + '/manifests.js';
var expectedFilepath = testDataDir + '/expected.js';
var build = function() {
var manifests = 'window.manifests = {\n';
var expected = 'window.expected = {\n';
var files = fs.readdirSync(manifestDir);
while (files.length > 0) {
var file = path.resolve(manifestDir, files.shift());
var extname = path.extname(file);
if (extname === '.m3u8') {
// translate this manifest
manifests += ' \'' + path.basename(file, '.m3u8') + '\': ';
manifests += fs.readFileSync(file, 'utf8')
.split(/\r\n|\n/)
// quote and concatenate
.map(function(line) {
return ' \'' + line + '\\n\' +\n';
}).join('')
// strip leading spaces and the trailing '+'
.slice(4, -3);
manifests += ',\n';
} else if (extname === '.js') {
// append the expected parse
expected += ' "' + path.basename(file, '.js') + '": ';
expected += fs.readFileSync(file, 'utf8');
expected += ',\n';
} else {
console.log('Unknown file ' + file + ' found in manifest dir ' + manifestDir);
}
}
// clean up and close the objects
manifests = manifests.slice(0, -2);
manifests += '\n};\n';
expected = expected.slice(0, -2);
expected += '\n};\n';
fs.writeFileSync(manifestFilepath, manifests);
fs.writeFileSync(expectedFilepath, expected);
console.log('Wrote test data file ' + manifestFilepath);
console.log('Wrote test data file ' + expectedFilepath);
};
var watch = function() {
build();
fs.watch(manifestDir, function(event, filename) {
console.log('files in manifest dir were changed rebuilding manifest data');
build();
});
};
var clean = function() {
try {
fs.unlinkSync(manifestFilepath);
} catch(e) {
console.log(e);
}
try {
fs.unlinkSync(expectedFilepath);
} catch(e) {
console.log(e);
}
}
module.exports = {
build: build,
watch: watch,
clean: clean
};
import connect from 'connect';
import cowsay from 'cowsay';
import path from 'path';
import portscanner from 'portscanner';
import serveStatic from 'serve-static';
// Configuration for the server.
const PORT = 9999;
const MAX_PORT = PORT + 100;
const HOST = '127.0.0.1';
const app = connect();
const verbs = [
'Chewing the cud',
'Grazing',
'Mooing',
'Lowing',
'Churning the cream'
];
app.use(serveStatic(path.join(__dirname, '..')));
portscanner.findAPortNotInUse(PORT, MAX_PORT, HOST, (error, port) => {
if (error) {
throw error;
}
process.stdout.write(cowsay.say({
text: `${verbs[Math.floor(Math.random() * 5)]} on ${HOST}:${port}`
}) + '\n\n');
app.listen(port);
});
var browserify = require('browserify');
var fs = require('fs');
var glob = require('glob');
var watchify = require('watchify');
glob('test/**/*.test.js', function(err, files) {
var b = browserify(files, {
cache: {},
packageCache: {},
plugin: [watchify]
}).transform('babelify');
var bundle = function() {
b.bundle().pipe(fs.createWriteStream('dist-test/videojs-contrib-hls.js'));
};
b.on('log', function(msg) {
process.stdout.write(msg + '\n');
});
b.on('update', bundle);
bundle();
});
......@@ -90,6 +90,7 @@
dispose,
mediaUpdateTimeout,
request,
playlistRequestError,
haveMetadata;
PlaylistLoader.prototype.init.call(this);
......@@ -102,27 +103,36 @@
throw new Error('A non-empty playlist URL is required');
}
playlistRequestError = function(xhr, url, startingState) {
loader.setBandwidth(request || xhr);
// any in-flight request is now finished
request = null;
if (startingState) {
loader.state = startingState;
}
loader.error = {
playlist: loader.master.playlists[url],
status: xhr.status,
message: 'HLS playlist request error at URL: ' + url,
responseText: xhr.responseText,
code: (xhr.status >= 500) ? 4 : 2
};
loader.trigger('error');
};
// update the playlist loader's state in response to a new or
// updated playlist.
haveMetadata = function(error, xhr, url) {
haveMetadata = function(xhr, url) {
var parser, refreshDelay, update;
loader.setBandwidth(request || xhr);
// any in-flight request is now finished
request = null;
if (error) {
loader.error = {
playlist: loader.master.playlists[url],
status: xhr.status,
message: 'HLS playlist request error at URL: ' + url,
responseText: xhr.responseText,
code: (xhr.status >= 500) ? 4 : 2
};
return loader.trigger('error');
}
loader.state = 'HAVE_METADATA';
parser = new videojs.m3u8.Parser();
......@@ -252,12 +262,12 @@
uri: resolveUrl(loader.master.uri, playlist.uri),
withCredentials: withCredentials
}, function(error, request) {
haveMetadata(error, request, playlist.uri);
if (error) {
return;
return playlistRequestError(request, playlist.uri, startingState);
}
haveMetadata(request, playlist.uri);
// fire loadedmetadata the first time a media playlist is loaded
if (startingState === 'HAVE_MASTER') {
loader.trigger('loadedmetadata');
......@@ -289,7 +299,10 @@
uri: resolveUrl(loader.master.uri, loader.media().uri),
withCredentials: withCredentials
}, function(error, request) {
haveMetadata(error, request, loader.media().uri);
if (error) {
return playlistRequestError(request, loader.media().uri);
}
haveMetadata(request, loader.media().uri);
});
});
......@@ -349,7 +362,7 @@
}]
};
loader.master.playlists[srcUrl] = loader.master.playlists[0];
haveMetadata(null, req, srcUrl);
haveMetadata(req, srcUrl);
return loader.trigger('loadedmetadata');
});
};
......
{
"curly": true,
"eqeqeq": true,
"immed": true,
"latedef": true,
"newcap": true,
"noarg": true,
"sub": true,
"undef": true,
"unused": true,
"boss": true,
"eqnull": true,
"browser": true,
"node": true,
"predef": [
"QUnit",
"module",
"test",
"asyncTest",
"expect",
"start",
"stop",
"ok",
"equal",
"notEqual",
"deepEqual",
"notDeepEqual",
"strictEqual",
"notStrictEqual",
"throws",
"sinon",
"process"
]
}
......@@ -32,7 +32,7 @@ var stringFromBytes = function(bytes) {
return result;
};
module('Decryption');
QUnit.module('Decryption');
test('decrypts a single AES-128 with PKCS7 block', function() {
var
......@@ -74,7 +74,7 @@ test('decrypts multiple AES-128 blocks with CBC', function() {
var clock;
module('Incremental Processing', {
QUnit.module('Incremental Processing', {
setup: function() {
clock = sinon.useFakeTimers();
},
......@@ -114,7 +114,7 @@ test('executes callback in series', function() {
var decrypter;
module('Incremental Decryption', {
QUnit.module('Incremental Decryption', {
setup: function() {
clock = sinon.useFakeTimers();
},
......
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>video.js HLS Plugin Test Suite</title>
<link rel="stylesheet" href="/node_modules/qunitjs/qunit/qunit.css" media="screen">
<link rel="stylesheet" href="/node_modules/video.js/dist/video-js.css" media="screen">
</head>
<body>
<div id="qunit"></div>
<div id="qunit-fixture"></div>
<!-- NOTE in order for test to pass we require sinon 1.10.2 exactly -->
<script src="/node_modules/sinon/pkg/sinon.js"></script>
<script src="/node_modules/qunitjs/qunit/qunit.js"></script>
<script src="/node_modules/pkcs7/dist/pkcs7.unpad.js"></script>
<script src="/node_modules/video.js/dist/video.js"></script>
<script src="/node_modules/videojs-contrib-media-sources/src/videojs-media-sources.js"></script>
<script src="/src/videojs-hls.js"></script>
<script src="/src/xhr.js"></script>
<script src="/src/stream.js"></script>
<script src="/src/m3u8/m3u8-parser.js"></script>
<script src="/src/playlist.js"></script>
<script src="/src/playlist-loader.js"></script>
<script src="/src/decrypter.js"></script>
<script src="/src/bin-utils.js"></script>
<script src="/test/data/manifests.js"></script>
<script src="/test/data/expected.js"></script>
<script src="/test/data/ts-segment-bc.js"></script>
<script src="/test/videojs-hls.test.js"></script>
<script src="/test/m3u8.test.js"></script>
<script src="/test/playlist.test.js"></script>
<script src="/test/playlist-loader.test.js"></script>
<script src="/test/decrypter.test.js"></script>
</body>
</html>
var fixture = document.createElement('div');
fixture.id = 'qunit-fixture';
document.body.appendChild(fixture);
// Karma example configuration file
// NOTE: To configure Karma tests, do the following:
// 1. Copy this file and rename the copy with a .conf.js extension, for example: karma.conf.js
// 2. Configure the properties below in your conf.js copy
// 3. Run your tests
module.exports = function(config) {
var customLaunchers = {
chrome_sl: {
singleRun: true,
base: 'SauceLabs',
browserName: 'chrome',
platform: 'Windows 7'
},
firefox_sl: {
singleRun: true,
base: 'SauceLabs',
browserName: 'firefox',
platform: 'Windows 8'
},
safari_sl: {
singleRun: true,
base: 'SauceLabs',
browserName: 'safari',
platform: 'OS X 10.8'
},
ipad_sl: {
singleRun: true,
base: 'SauceLabs',
browserName: 'ipad',
platform:'OS X 10.9',
version: '7.1'
},
android_sl: {
singleRun: true,
base: 'SauceLabs',
browserName: 'android',
platform:'Linux'
}
};
config.set({
// base path, that will be used to resolve files and exclude
basePath: '',
frameworks: ['qunit'],
// Set autoWatch to true if you plan to run `grunt karma` continuously, to automatically test changes as you make them.
autoWatch: false,
// 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.
singleRun: true,
// custom launchers for sauce labs
//define SL browsers
customLaunchers: customLaunchers,
// Start these browsers
browsers: ['chrome_sl'], //Object.keys(customLaunchers),
// List of files / patterns to load in the browser
// Add any new src files to this list.
// If you add new unit tests, they will be picked up automatically by Karma,
// unless you've added them to a nested directory, in which case you should
// add their paths to this list.
files: [
'../node_modules/sinon/pkg/sinon.js',
'../node_modules/video.js/dist/video-js.css',
'../node_modules/video.js/dist/video.js',
'../node_modules/videojs-contrib-media-sources/src/videojs-media-sources.js',
'../node_modules/pkcs7/dist/pkcs7.unpad.js',
'../test/karma-qunit-shim.js',
'../src/videojs-hls.js',
'../src/stream.js',
'../src/m3u8/m3u8-parser.js',
'../src/xhr.js',
'../src/playlist.js',
'../src/playlist-loader.js',
'../src/decrypter.js',
'../tmp/manifests.js',
'../tmp/expected.js',
'tsSegment-bc.js',
'../src/bin-utils.js',
'../test/*.js',
],
plugins: [
'karma-qunit',
'karma-chrome-launcher',
'karma-firefox-launcher',
'karma-ie-launcher',
'karma-opera-launcher',
'karma-phantomjs-launcher',
'karma-safari-launcher',
'karma-sauce-launcher'
],
// test results reporter to use
// possible values: 'dots', 'progress', 'junit'
reporters: ['dots', 'progress'],
// web server port
port: 9876,
// cli runner port
runnerPort: 9100,
// enable / disable colors in the output (reporters and logs)
colors: true,
// level of logging
// possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
//logLevel: config.LOG_INFO,
// If browser does not capture in given timeout [ms], kill it
captureTimeout: 60000,
// global config for SauceLabs
sauceLabs: {
startConnect: false,
tunnelIdentifier: process.env.TRAVIS_JOB_NUMBER,
build: process.env.TRAVIS_BUILD_NUMBER,
testName: process.env.TRAVIS_BUILD_NUMBER + process.env.TRAVIS_BRANCH,
recordScreenshots: false
}
});
};
var common = require('./common');
module.exports = function(config) {
config.set(common({
plugins: ['karma-chrome-launcher'],
browsers: ['Chrome']
}));
};
var merge = require('lodash-compat/object/merge');
var DEFAULTS = {
basePath: '../..',
//frameworks: ['browserify', 'qunit'],
frameworks: ['qunit'],
files: [
'node_modules/sinon/pkg/sinon.js',
'node_modules/sinon/pkg/sinon-ie.js',
'node_modules/video.js/dist/video.js',
'node_modules/video.js/dist/video-js.css',
// REMOVE ME WHEN BROWSERIFIED
'node_modules/pkcs7/dist/pkcs7.unpad.js',
'node_modules/videojs-contrib-media-sources/src/videojs-media-sources.js',
'src/videojs-hls.js',
'src/xhr.js',
'src/stream.js',
'src/m3u8/m3u8-parser.js',
'src/playlist.js',
'src/playlist-loader.js',
'src/decrypter.js',
'src/bin-utils.js',
'test/data/manifests.js',
'test/data/expected.js',
'test/data/ts-segment-bc.js',
'test/videojs-hls.test.js',
'test/m3u8.test.js',
'test/playlist.test.js',
'test/playlist-loader.test.js',
'test/decrypter.test.js',
// END REMOVE ME
// 'test/**/*.js'
],
exclude: [
'test/bundle.js',
// 'test/data/**'
],
plugins: [
// 'karma-browserify',
'karma-qunit'
],
preprocessors: {
// 'test/**/*.js': ['browserify']
},
reporters: ['dots'],
port: 9876,
colors: true,
autoWatch: false,
singleRun: true,
concurrency: Infinity,
/*
browserify: {
debug: true,
transform: [
'babelify',
'browserify-shim'
],
noparse: [
'test/data/**',
]
}
*/
};
/**
* Customizes target/source merging with lodash merge.
*
* @param {Mixed} target
* @param {Mixed} source
* @return {Mixed}
*/
var customizer = function(target, source) {
if (Array.isArray(target)) {
return target.concat(source);
}
};
/**
* Generates a new Karma config with a common set of base configuration.
*
* @param {Object} custom
* Configuration that will be deep-merged. Arrays will be
* concatenated.
* @return {Object}
*/
module.exports = function(custom) {
return merge({}, custom, DEFAULTS, customizer);
};
var common = require('./common');
// Runs default testing configuration in multiple environments.
module.exports = function(config) {
// Travis CI should run in its available Firefox headless browser.
if (process.env.TRAVIS) {
config.set(common({
browsers: ['Firefox'],
plugins: ['karma-firefox-launcher']
}))
} else {
config.set(common({
frameworks: ['detectBrowsers'],
plugins: [
'karma-chrome-launcher',
'karma-detect-browsers',
'karma-firefox-launcher',
'karma-ie-launcher',
'karma-safari-launcher'
],
detectBrowsers: {
// disable safari as it was not previously supported and causes test failures
postDetection: function(availableBrowsers) {
var safariIndex = availableBrowsers.indexOf('Safari');
if(safariIndex !== -1) {
availableBrowsers.splice(safariIndex, 1);
}
return availableBrowsers;
},
usePhantomJS: false
}
}));
}
};
var common = require('./common');
module.exports = function(config) {
config.set(common({
plugins: ['karma-firefox-launcher'],
browsers: ['Firefox']
}));
};
var common = require('./common');
module.exports = function(config) {
config.set(common({
plugins: ['karma-ie-launcher'],
browsers: ['IE']
}));
};
var common = require('./common');
module.exports = function(config) {
config.set(common({
plugins: ['karma-safari-launcher'],
browsers: ['Safari']
}));
};
// Karma example configuration file
// NOTE: To configure Karma tests, do the following:
// 1. Copy this file and rename the copy with a .conf.js extension, for example: karma.conf.js
// 2. Configure the properties below in your conf.js copy
// 3. Run your tests
module.exports = function(config) {
config.set({
// base path, that will be used to resolve files and exclude
basePath: '',
frameworks: ['qunit'],
// Set autoWatch to true if you plan to run `grunt karma` continuously, to automatically test changes as you make them.
autoWatch: false,
// 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.
singleRun: true,
// Start these browsers, currently available:
// - Chrome
// - ChromeCanary
// - Firefox
// - Opera
// - Safari (only Mac)
// - PhantomJS
// - IE (only Windows)
// Example usage:
// browsers: [],
// List of files / patterns to load in the browser
// Add any new src files to this list.
// If you add new unit tests, they will be picked up automatically by Karma,
// unless you've added them to a nested directory, in which case you should
// add their paths to this list.
files: [
'../node_modules/sinon/pkg/sinon.js',
'../node_modules/video.js/dist/video-js.css',
'../node_modules/video.js/dist/video.js',
'../node_modules/videojs-contrib-media-sources/src/videojs-media-sources.js',
'../node_modules/pkcs7/dist/pkcs7.unpad.js',
'../test/karma-qunit-shim.js',
'../src/videojs-hls.js',
'../src/stream.js',
'../src/m3u8/m3u8-parser.js',
'../src/xhr.js',
'../src/playlist.js',
'../src/playlist-loader.js',
'../src/decrypter.js',
'../tmp/manifests.js',
'../tmp/expected.js',
'tsSegment-bc.js',
'../src/bin-utils.js',
'../test/*.js',
],
plugins: [
'karma-qunit',
'karma-chrome-launcher',
'karma-firefox-launcher',
'karma-ie-launcher',
'karma-opera-launcher',
'karma-phantomjs-launcher',
'karma-safari-launcher'
],
// list of files to exclude
exclude: [
],
// test results reporter to use
// possible values: 'dots', 'progress', 'junit'
reporters: ['progress'],
// web server port
port: 9876,
// cli runner port
runnerPort: 9100,
// enable / disable colors in the output (reporters and logs)
colors: true,
// level of logging
// possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
logLevel: config.LOG_DISABLE,
// If browser does not capture in given timeout [ms], kill it
captureTimeout: 60000
});
};
......@@ -13,7 +13,7 @@
M3U8 Test Suite
*/
module('LineStream', {
QUnit.module('LineStream', {
setup: function() {
lineStream = new LineStream();
}
......@@ -83,7 +83,7 @@
strictEqual(2, permanentLines.length, 'new events are still received');
});
module('ParseStream', {
QUnit.module('ParseStream', {
setup: function() {
lineStream = new LineStream();
parseStream = new ParseStream();
......@@ -622,13 +622,13 @@
ok(!event, 'no event is triggered');
});
module('m3u8 parser');
QUnit.module('m3u8 parser');
test('can be constructed', function() {
notStrictEqual(new Parser(), undefined, 'parser is defined');
});
module('m3u8s');
QUnit.module('m3u8s');
test('parses static manifests as expected', function() {
var key;
......
<!doctype html>
<html>
<head>
<title>MPEG-TS Parser Performance Workbench</title>
<!-- video.js -->
<script src="../node_modules/video.js/video.dev.js"></script>
<!-- HLS plugin -->
<script src="../src/video-js-hls.js"></script>
<script src="../src/flv-tag.js"></script>
<script src="../src/exp-golomb.js"></script>
<script src="../src/h264-stream.js"></script>
<script src="../src/aac-stream.js"></script>
<script src="../src/segment-parser.js"></script>
<!-- MPEG-TS segment -->
<script src="tsSegment-bc.js"></script>
<style>
.desc {
background-color: #ddd;
border: thin solid #333;
padding: 8px;
}
</style>
</head>
<body>
<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>
<form>
<input name="iterations" min="1" type="number" value="1">
<button type="sumbit">Run</button>
</form>
<table>
<thead>
<th>Iterations</th><th>Time</th><th>MB/second</th>
</thead>
<tbody class="results"></tbody>
</table>
<script>
var
button = document.querySelector('button'),
input = document.querySelector('input'),
results = document.querySelector('.results'),
reportResults = function(count, elapsed) {
var
row = document.createElement('tr'),
countCell = document.createElement('td'),
elapsedCell = document.createElement('td'),
throughputCell = document.createElement('td');
countCell.innerText = count;
elapsedCell.innerText = elapsed;
throughputCell.innerText = (((bcSegment.byteLength * count * 1000) / elapsed) / (Math.pow(2, 20))).toFixed(3);
row.appendChild(countCell);
row.appendChild(elapsedCell);
row.appendChild(throughputCell);
results.insertBefore(row, results.firstChild);
};
button.addEventListener('click', function(event) {
var
iterations = input.value,
parser = new window.videojs.hls.SegmentParser(),
start;
// setup
start = +new Date();
while (iterations--) {
// parse the segment
parser.parseSegmentBinaryData(window.bcSegment);
// finalize all the FLV tags
while (parser.tagsAvailable()) {
parser.getNextTag();
}
}
// report
reportResults(input.value, (+new Date()) - start);
// don't actually submit the form
event.preventDefault();
}, false);
</script>
</body>
</html>
......@@ -16,7 +16,7 @@
.join('/');
};
module('Playlist Loader', {
QUnit.module('Playlist Loader', {
setup: function() {
// fake XHRs
sinonXhr = sinon.useFakeXMLHttpRequest();
......
......@@ -3,7 +3,7 @@
'use strict';
var Playlist = videojs.Hls.Playlist;
module('Playlist Duration');
QUnit.module('Playlist Duration');
test('total duration for live playlists is Infinity', function() {
var duration = Playlist.duration({
......@@ -16,7 +16,7 @@
equal(duration, Infinity, 'duration is infinity');
});
module('Playlist Interval Duration');
QUnit.module('Playlist Interval Duration');
test('accounts for non-zero starting VOD media sequences', function() {
var duration = Playlist.duration({
......@@ -266,7 +266,7 @@
equal(Playlist.duration(playlist, -1), 0, 'negative length duration is zero');
});
module('Playlist Seekable');
QUnit.module('Playlist Seekable');
test('calculates seekable time ranges from the available segments', function() {
var playlist = {
......
import document from 'global/document';
import QUnit from 'qunit';
import sinon from 'sinon';
import videojs from 'video.js';
QUnit.module('videojs-contrib-hls - sanity', {
beforeEach() {
this.fixture = document.getElementById('qunit-fixture');
this.video = document.createElement('video');
this.fixture.appendChild(this.video);
this.player = videojs(this.video);
// Mock the environment's timers because certain things - particularly
// player readiness - are asynchronous in video.js 5.
this.clock = sinon.useFakeTimers();
},
afterEach() {
// The clock _must_ be restored before disposing the player; otherwise,
// certain timeout listeners that happen inside video.js may throw errors.
this.clock.restore();
this.player.dispose();
}
});
QUnit.test('the environment is sane', function(assert) {
assert.strictEqual(typeof Array.isArray, 'function', 'es5 exists');
assert.strictEqual(typeof sinon, 'object', 'sinon exists');
assert.strictEqual(typeof videojs, 'function', 'videojs exists');
assert.strictEqual(typeof videojs.MediaSource, 'object', 'MediaSource is an object');
assert.strictEqual(typeof videojs.URL, 'object', 'URL is an object');
assert.strictEqual(typeof videojs.Hls, 'object', 'Hls is an object');
assert.strictEqual(typeof videojs.HlsSourceHandler,'function', 'HlsSourceHandler is a function');
assert.strictEqual(typeof videojs.HlsHandler, 'function', 'HlsHandler is a function');
});
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>video.js HLS Plugin Test Suite</title>
<!-- Load sinon server for fakeXHR -->
<script src="../node_modules/sinon/pkg/sinon.js"></script>
<!-- Load local QUnit. -->
<link rel="stylesheet" href="../node_modules/qunitjs/qunit/qunit.css" media="screen">
<script src="../node_modules/qunitjs/qunit/qunit.js"></script>
<!-- video.js -->
<script src="../node_modules/video.js/dist/video.js"></script>
<link rel="stylesheet" href="../node_modules/video.js/dist/video-js.css" media="screen">
<script src="../node_modules/videojs-contrib-media-sources/src/videojs-media-sources.js"></script>
<!-- HLS plugin -->
<script src="../src/videojs-hls.js"></script>
<script src="../src/xhr.js"></script>
<script src="../src/stream.js"></script>
<!-- M3U8 -->
<script src="../src/m3u8/m3u8-parser.js"></script>
<script src="../src/playlist.js"></script>
<script src="../src/playlist-loader.js"></script>
<script src="../node_modules/pkcs7/dist/pkcs7.unpad.js"></script>
<script src="../src/decrypter.js"></script>
<!-- M3U8 TEST DATA -->
<script src="../tmp/manifests.js"></script>
<script src="../tmp/expected.js"></script>
<!-- M3U8 -->
<!-- SEGMENT -->
<script src="tsSegment-bc.js"></script>
<script src="../src/bin-utils.js"></script>
<!-- Test cases -->
<script>
module('environment');
test('is sane', function() {
expect(1);
ok(true);
});
</script>
<script src="videojs-hls_test.js"></script>
<script src="m3u8_test.js"></script>
<script src="playlist_test.js"></script>
<script src="playlist-loader_test.js"></script>
<script src="decrypter_test.js"></script>
</head>
<body>
<div id="qunit"></div>
<div id="qunit-fixture">
<span>test markup</span>
</div>
</body>
</html>
......@@ -206,7 +206,7 @@ var
MockMediaSource.open = function() {};
module('HLS', {
QUnit.module('HLS', {
beforeEach: function() {
oldMediaSource = videojs.MediaSource;
videojs.MediaSource = MockMediaSource;
......@@ -1296,6 +1296,28 @@ test('blacklists switching from video-only playlists to video+audio', function()
equal(videoAudioPlaylist.excludeUntil, Infinity, 'excluded incompatible playlist');
});
test('After an initial media playlist 404s, we fire loadedmetadata once we successfully load a playlist', function() {
var count = 0;
player.src({
src: 'manifest/master.m3u8',
type: 'application/vnd.apple.mpegurl'
});
openMediaSource(player);
player.tech_.hls.bandwidth = 20000;
player.on('loadedmetadata', function() {
count += 1;
});
standardXHRResponse(requests.shift()); //master
equal(count, 0,
'loadedMedia not triggered before requesting playlist');
requests.shift().respond(404); //media
equal(count, 0,
'loadedMedia not triggered after playlist 404');
standardXHRResponse(requests.shift()); //media
equal(count, 1,
'loadedMedia triggered after successful recovery from 404');
});
test('does not blacklist compatible H.264 codec strings', function() {
var master;
player.src({
......@@ -2884,7 +2906,7 @@ test('does not download segments if preload option set to none', function() {
equal(requests.length, 0, 'did not download any segments');
});
module('Buffer Inspection');
QUnit.module('Buffer Inspection');
test('detects time range end-point changed by updates', function() {
var edge;
......
......@@ -20,7 +20,7 @@ if (process.env.SAUCE_USERNAME) {
config.maxDuration = 300;
}
config.baseUrl = 'http://127.0.0.1:9999/example.html';
config.baseUrl = 'http://127.0.0.1:9999/';
config.specs = ['spec.js'];
config.framework = 'jasmine2';
......