├── .babelrc
├── .eslintignore
├── .eslintrc
├── .flowconfig
├── .gitignore
├── .npmignore
├── .travis.yml
├── build
├── rollup.config.base.js
├── rollup.config.common.js
├── rollup.config.dev.js
├── rollup.config.es.js
├── rollup.config.min.js
└── rollup.config.umd.js
├── demo
├── .DS_Store
├── base.js
├── get-live-url.js
├── hls-live
│ ├── index.css
│ └── index.html
├── hls
│ ├── index.css
│ └── index.html
└── index.html
├── flow
├── base.js
└── modules.js
├── karma.conf.js
├── lib
├── index.browser.js
├── index.js
├── index.min.js
└── index.mjs
├── package.json
├── readme.md
├── rollup
├── src
├── .DS_Store
├── custom-config.js
└── index.js
└── tests
└── index.js
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [
3 | "flow",
4 | [
5 | "env",
6 | {
7 | "targets": {
8 | "browsers": [
9 | "last 2 versions",
10 | "not ie <= 8"
11 | ]
12 | }
13 | }
14 | ],
15 | "stage-0"
16 | ],
17 | "plugins": [
18 | "transform-decorators-legacy"
19 | ]
20 | }
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | lib
3 | flow
4 | coverage
5 | bundle-size
6 | demo
7 |
--------------------------------------------------------------------------------
/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "globals": {
3 | "process": true
4 | },
5 | "env": {
6 | "browser": true,
7 | "commonjs": true,
8 | "es6": true
9 | },
10 | "extends": [
11 | "eslint-config-egg",
12 | "plugin:flowtype/recommended"
13 | ],
14 | "plugins": [
15 | "flowtype"
16 | ],
17 | "parser": "babel-eslint",
18 | "parserOptions": {
19 | "sourceType": "module"
20 | },
21 | "rules": {
22 | "valid-jsdoc": "off"
23 | }
24 | }
--------------------------------------------------------------------------------
/.flowconfig:
--------------------------------------------------------------------------------
1 | [ignore]
2 | .*/node_modules/.*
3 | .*/demos/.*
4 | .*/dist/.*
5 | [include]
6 | .*/src/.*
7 | [libs]
8 | flow
9 | node_modules/chimee-helper/lib/index.flow.js
10 | node_modules/chimee-kernel/lib/index.flow.js
11 | node_modules/toxic-decorators/lib/index.flow.js
12 | [lints]
13 | all=warn
14 | untyped-type-import=error
15 | sketchy-null-bool=off
16 | [options]
17 | esproposal.decorators=ignore
18 | [strict]
19 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 |
8 | # Runtime data
9 | pids
10 | *.pid
11 | *.seed
12 | *.pid.lock
13 |
14 | # Directory for instrumented libs generated by jscoverage/JSCover
15 | lib-cov
16 |
17 | # Coverage directory used by tools like istanbul
18 | coverage
19 |
20 | # nyc test coverage
21 | .nyc_output
22 |
23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
24 | .grunt
25 |
26 | # Bower dependency directory (https://bower.io/)
27 | bower_components
28 |
29 | # node-waf configuration
30 | .lock-wscript
31 |
32 | # Compiled binary addons (http://nodejs.org/api/addons.html)
33 | build/Release
34 |
35 | # Dependency directories
36 | node_modules/
37 | jspm_packages/
38 |
39 | # Typescript v1 declaration files
40 | typings/
41 |
42 | # Optional npm cache directory
43 | .npm
44 |
45 | # Optional eslint cache
46 | .eslintcache
47 |
48 | # Optional REPL history
49 | .node_repl_history
50 |
51 | # Output of 'npm pack'
52 | *.tgz
53 |
54 | # Yarn Integrity file
55 | .yarn-integrity
56 |
57 | # dotenv environment variables file
58 | .env
59 |
60 | package-lock.json
61 | .DS_Store
62 | lib/index.dev.js
63 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | tests/
2 | build/
3 | lib/index.dev.js
4 | coverage/
5 | demo/
6 | doc/
7 | flow/
8 | node_modules/
9 | tool/
10 | bundle-size/
11 | .babelrc
12 | .flowconfig
13 | .eslintignore
14 | .eslintrc
15 | karma.config.js
16 | src
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js:
3 | - '8'
4 | script:
5 | - 'npm test'
6 | after_success:
7 | - 'npm install coveralls && npm install nyc && ./node_modules/.bin/nyc report --temp-directory=coverage --reporter=text-lcov | ./node_modules/.bin/coveralls'
8 | notifications:
9 | webhooks:
10 | urls:
11 | - 'https://www.travisbuddy.com/'
12 | on_success: never
13 | on_failure: always
14 | on_start: never
15 | on_cancel: never
16 | on_error: never
17 |
--------------------------------------------------------------------------------
/build/rollup.config.base.js:
--------------------------------------------------------------------------------
1 | const { version, name, author, license, dependencies } = require('../package.json');
2 | export const banner = `
3 | /**
4 | * ${name} v${version}
5 | * (c) 2017-${(new Date()).getFullYear()} ${author}
6 | * Released under ${license}
7 | */
8 | `;
9 | import babel from 'rollup-plugin-babel';
10 | import resolve from 'rollup-plugin-node-resolve';
11 | import commonjs from 'rollup-plugin-commonjs';
12 | import replace from 'rollup-plugin-replace';
13 | const babelConfig = {
14 | common: {
15 | presets: [
16 | 'flow',
17 | [ 'env', {
18 | modules: false,
19 | targets: {
20 | browsers: [ 'last 2 versions', 'not ie <= 8' ],
21 | },
22 | }],
23 | 'stage-0',
24 | ],
25 | exclude: 'node_modules/**',
26 | plugins: [
27 | 'external-helpers',
28 | 'transform-decorators-legacy',
29 | 'transform-runtime',
30 | ],
31 | externalHelpers: true,
32 | runtimeHelpers: true,
33 | babelrc: false,
34 | },
35 | es: {
36 | presets: [
37 | 'flow',
38 | [ 'env', {
39 | modules: false,
40 | targets: {
41 | browsers: [ 'last 2 versions', 'not ie <= 8' ],
42 | },
43 | }],
44 | 'stage-0',
45 | ],
46 | exclude: 'node_modules/**',
47 | plugins: [
48 | 'external-helpers',
49 | 'transform-decorators-legacy',
50 | 'transform-runtime',
51 | ],
52 | externalHelpers: true,
53 | runtimeHelpers: true,
54 | babelrc: false,
55 | },
56 | umd: {
57 | presets: [
58 | 'flow',
59 | [ 'env', {
60 | modules: false,
61 | targets: {
62 | browsers: [ 'last 2 versions', 'not ie <= 8' ],
63 | },
64 | }],
65 | 'stage-0',
66 | ],
67 | exclude: 'node_modules/**',
68 | plugins: [
69 | 'external-helpers',
70 | 'transform-decorators-legacy',
71 | 'transform-runtime',
72 | ],
73 | externalHelpers: true,
74 | runtimeHelpers: true,
75 | babelrc: false,
76 | },
77 | iife: {
78 | presets: [
79 | 'flow',
80 | [ 'env', {
81 | modules: false,
82 | targets: {
83 | browsers: [ 'last 2 versions', 'not ie <= 8' ],
84 | },
85 | }],
86 | 'stage-0',
87 | ],
88 | exclude: 'node_modules/**',
89 | plugins: [
90 | 'external-helpers',
91 | 'transform-decorators-legacy',
92 | 'transform-runtime',
93 | ],
94 | externalHelpers: true,
95 | runtimeHelpers: true,
96 | babelrc: false,
97 | },
98 | min: {
99 | presets: [
100 | 'flow',
101 | [ 'env', {
102 | modules: false,
103 | targets: {
104 | browsers: [ 'last 2 versions', 'not ie <= 8' ],
105 | },
106 | }],
107 | 'stage-0',
108 | ],
109 | exclude: 'node_modules/**',
110 | plugins: [
111 | 'external-helpers',
112 | 'transform-decorators-legacy',
113 | ],
114 | runtimeHelpers: true,
115 | babelrc: false,
116 | },
117 | };
118 | // const externalRegExp = new RegExp(Object.keys(dependencies).concat(Object.keys(helperDependencies)).join('|'));
119 | const externalRegExp = new RegExp(Object.keys(dependencies).join('|'));
120 | export default function(mode) {
121 | return {
122 | input: 'src/index.js',
123 | external(id) {
124 | return !/min|umd|iife/.test(mode) && externalRegExp.test(id);
125 | },
126 | plugins: [
127 | babel(babelConfig[mode]),
128 | resolve({
129 | customResolveOptions: {
130 | moduleDirectory: [ 'src', 'node_modules' ],
131 | },
132 | preferBuiltins: true,
133 | }),
134 | commonjs(),
135 | replace({
136 | 'process.env.VERSION': `'${version}'`,
137 | }),
138 | ].concat(/min|umd|iife/.test(mode)
139 | ? [
140 | resolve({
141 | customResolveOptions: {
142 | moduleDirectory: [ 'src', 'node_modules' ],
143 | },
144 | preferBuiltins: true,
145 | }),
146 | ]
147 | : []
148 | ),
149 | };
150 | }
151 |
--------------------------------------------------------------------------------
/build/rollup.config.common.js:
--------------------------------------------------------------------------------
1 | import base, { banner } from './rollup.config.base';
2 | export default Object.assign(base('common'), {
3 | output: {
4 | banner,
5 | format: 'cjs',
6 | file: 'lib/index.js',
7 | },
8 | });
9 |
--------------------------------------------------------------------------------
/build/rollup.config.dev.js:
--------------------------------------------------------------------------------
1 | import base, { banner } from './rollup.config.base';
2 | import serve from 'rollup-plugin-serve';
3 | import livereload from 'rollup-plugin-livereload';
4 | import replace from 'rollup-plugin-replace';
5 | import { camelize } from 'toxic-utils';
6 | const { name } = require('../package.json');
7 | const config = base('iife');
8 | config.plugins.push(
9 | serve(),
10 | livereload()
11 | );
12 | config.plugins.unshift(replace({
13 | 'process.env.NODE_ENV': '"development"',
14 | }));
15 | export default Object.assign(config, {
16 | output: {
17 | banner,
18 | format: 'umd',
19 | file: 'lib/index.dev.js',
20 | name: camelize(name, true),
21 | },
22 | });
23 |
--------------------------------------------------------------------------------
/build/rollup.config.es.js:
--------------------------------------------------------------------------------
1 | import base, { banner } from './rollup.config.base';
2 | export default Object.assign(base('es'), {
3 | output: {
4 | banner,
5 | format: 'es',
6 | file: 'lib/index.mjs',
7 | },
8 | });
9 |
--------------------------------------------------------------------------------
/build/rollup.config.min.js:
--------------------------------------------------------------------------------
1 | import base, { banner } from './rollup.config.base';
2 | import { uglify } from 'rollup-plugin-uglify';
3 | import replace from 'rollup-plugin-replace';
4 | const { name } = require('../package.json');
5 | import { camelize } from 'toxic-utils';
6 | const config = base('min');
7 | config.plugins.unshift(replace({
8 | 'process.env.NODE_ENV': '"production"',
9 | }));
10 | config.plugins.push(uglify({}));
11 | export default Object.assign(config, {
12 | output: {
13 | banner,
14 | format: 'umd',
15 | file: 'lib/index.min.js',
16 | name: camelize(name, true),
17 | },
18 | });
19 |
--------------------------------------------------------------------------------
/build/rollup.config.umd.js:
--------------------------------------------------------------------------------
1 | import base, { banner } from './rollup.config.base';
2 | const { name } = require('../package.json');
3 | import { camelize } from 'toxic-utils';
4 | import replace from 'rollup-plugin-replace';
5 | const config = base('umd');
6 | config.plugins.unshift(replace({
7 | 'process.env.NODE_ENV': '"development"',
8 | }));
9 | export default Object.assign(config, {
10 | output: {
11 | banner,
12 | format: 'umd',
13 | file: 'lib/index.browser.js',
14 | name: camelize(name, true),
15 | },
16 | });
17 |
--------------------------------------------------------------------------------
/demo/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Chimeejs/chimee-kernel-hls/e09bed717bf7bc62086642120e48b5975d3c89be/demo/.DS_Store
--------------------------------------------------------------------------------
/demo/base.js:
--------------------------------------------------------------------------------
1 | // mp4 http://cdn.toxicjohann.com/lostStar.mp4
2 | // hls http://yunxianchang.live.ujne7.com/vod-system-bj/44_176_20170224113626af3a75cd-3508-4bc3-b51f-366fca3c7e39.m3u8
3 | // flv直播 http://pf.live.360vcloud.net/live_customers3/6818c55761856069a0ce
4 | // flv直播 http://flv.jia.360.cn/live_jia_public/_LC_RE_non_3605375765815007736131516144_BX.flv
5 | // flv点播 http://yunxianchang.live.ujne7.com/vod-system-bj/TL1ce1196bce348070bfeef2116efbdea6.flv
6 | // flv点播 http://yunxianchang.live.ujne7.com/vod-system-bj/TL2791e64b69ea0bea234c284c694986aa.flv
7 | window.start = function() {
8 | const kernelConfig = window.kernelConfig || {};
9 | const player = document.querySelector('#player');
10 | const kernel = new window.ChimeeKernel(player, kernelConfig);
11 | window.kernel = kernel;
12 |
13 | const seekController = document.createElement('div');
14 | seekController.innerText = 'seek: ';
15 |
16 | const seekInput = document.createElement('input');
17 | seekInput.value = 0;
18 | seekInput.type = 'number';
19 |
20 | seekController.appendChild(seekInput);
21 |
22 | document.body.appendChild(seekController);
23 |
24 | const srcController = document.createElement('div');
25 | srcController.innerText = 'src: ';
26 |
27 | const srcInput = document.createElement('input');
28 | srcInput.value = '';
29 | srcInput.type = 'text';
30 |
31 | srcController.appendChild(srcInput);
32 |
33 | document.body.appendChild(srcController);
34 |
35 | const keys = [ 'play', 'pause', 'load', 'startLoad', 'stopLoad', 'attachMedia', 'seek', 'refresh', 'destroy' ];
36 | const controller = document.createElement('div');
37 | keys.forEach(function(key) {
38 | const button = document.createElement('button');
39 | button.innerText = key;
40 | button.addEventListener('click', function() {
41 | if (key === 'seek') {
42 | kernel.seek(parseFloat(seekInput.value));
43 | return;
44 | }
45 | if (key === 'load') {
46 | kernel.load(srcInput.value);
47 | return;
48 | }
49 | kernel[key]();
50 | });
51 | controller.appendChild(button);
52 | });
53 |
54 | document.body.appendChild(controller);
55 |
56 | kernel.load();
57 | };
58 |
--------------------------------------------------------------------------------
/demo/get-live-url.js:
--------------------------------------------------------------------------------
1 | const $ = window.$;
2 |
3 | window.getLiveSource = function(type) {
4 | const sources = {};
5 |
6 | // 取个SD的直播流来用用
7 | function getSDLiveUrl(sn) {
8 | const a = 've3.ji';
9 | const b = '60.c';
10 | return $.ajax({
11 | url: 'https://li' + a + 'a.3' + b + 'n/public/getInfoAndPlayV2?from=mpc_ipcam_web&sn=36' + sn + '&taskid=' + +new Date(),
12 | type: 'get',
13 | dataType: 'jsonp',
14 | }).then(function(data) {
15 | let liveHLS = data && data.playInfo && data.playInfo.hls;
16 | const ret = {};
17 | if (liveHLS) {
18 | if (type === 'flv') liveHLS = liveHLS.replace('hls-live', 'flv-live').replace('/index.m3u8', '.flv');
19 | ret.url = liveHLS;
20 | ret.poster = data.publicInfo.thumbnail;
21 | }
22 | return ret;
23 | });
24 | }
25 |
26 | return Promise.all([
27 | getSDLiveUrl('072754052'),
28 | getSDLiveUrl('0K0905701'),
29 | getSDLiveUrl('0K0904122'),
30 | ]).then(function(re) {
31 | if (!re[0].url || !re[1].url || !re[2].url) {
32 | console.error('流地址异常');
33 | }
34 | sources.snow = re[0].url;
35 | sources.river = re[1].url;
36 | sources.city = re[2].url;
37 | return sources;
38 | });
39 | };
40 |
--------------------------------------------------------------------------------
/demo/hls-live/index.css:
--------------------------------------------------------------------------------
1 | html, body {
2 | width: 100%;
3 | margin: 0;
4 | padding: 0;
5 | }
6 | html {
7 | background-color: #FFFBE6;
8 | font-family: "Oswald", "HelveticaNeue-CondensedBold", "Arial Narrow", "Hiragino Sans GB", "Microsoft YaHei", "WenQuanYi Micro Hei", sans-serif;
9 | background-repeat: no-repeat;
10 | min-height: 100%;
11 | }
12 | body {
13 | padding: 10px;
14 | box-sizing: border-box;
15 | color: #36384A;
16 | max-width: 800px;
17 | margin: auto;
18 | }
19 | #wrapper {
20 | position: relative;
21 | width: 100%;
22 | height: 100%;
23 | }
24 | container {
25 | position: relative;
26 | display: block;
27 | /* width: 100%;
28 | height: 100%; */
29 | }
30 | video {
31 | /* width: 100%;
32 | height: 100%; */
33 | display: block;
34 | background-color: #000;
35 | }
36 | video:focus,
37 | video:active {
38 | outline: none;
39 | }
40 | button {
41 | color: #fff;
42 | background-color: #3F4F68;
43 | padding: 6px 12px;
44 | text-decoration: none;
45 | -webkit-user-select: none;
46 | -moz-user-select: none;
47 | -ms-user-select: none;
48 | user-select: none;
49 | border-radius: 4px;
50 | text-transform: none;
51 | outline: none;
52 | border: none;
53 | margin-bottom: 2px;
54 | }
55 | h1 {
56 | color: #9D295A;
57 | }
58 | button:active {
59 | background-color: #36384A;
60 | }
61 |
62 |
--------------------------------------------------------------------------------
/demo/hls-live/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | hls test demo
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
32 |
33 |
--------------------------------------------------------------------------------
/demo/hls/index.css:
--------------------------------------------------------------------------------
1 | html, body {
2 | width: 100%;
3 | margin: 0;
4 | padding: 0;
5 | }
6 | html {
7 | background-color: #FFFBE6;
8 | font-family: "Oswald", "HelveticaNeue-CondensedBold", "Arial Narrow", "Hiragino Sans GB", "Microsoft YaHei", "WenQuanYi Micro Hei", sans-serif;
9 | background-repeat: no-repeat;
10 | min-height: 100%;
11 | }
12 | body {
13 | padding: 10px;
14 | box-sizing: border-box;
15 | color: #36384A;
16 | max-width: 800px;
17 | margin: auto;
18 | }
19 | #wrapper {
20 | position: relative;
21 | width: 100%;
22 | height: 100%;
23 | }
24 | container {
25 | position: relative;
26 | display: block;
27 | /* width: 100%;
28 | height: 100%; */
29 | }
30 | video {
31 | /* width: 100%;
32 | height: 100%; */
33 | display: block;
34 | background-color: #000;
35 | }
36 | video:focus,
37 | video:active {
38 | outline: none;
39 | }
40 | button {
41 | color: #fff;
42 | background-color: #3F4F68;
43 | padding: 6px 12px;
44 | text-decoration: none;
45 | -webkit-user-select: none;
46 | -moz-user-select: none;
47 | -ms-user-select: none;
48 | user-select: none;
49 | border-radius: 4px;
50 | text-transform: none;
51 | outline: none;
52 | border: none;
53 | margin-bottom: 2px;
54 | }
55 | h1 {
56 | color: #9D295A;
57 | }
58 | button:active {
59 | background-color: #36384A;
60 | }
61 |
62 |
--------------------------------------------------------------------------------
/demo/hls/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | hls test demo
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
15 |
16 |
17 |
18 |
19 |
20 |
38 |
39 |
--------------------------------------------------------------------------------
/demo/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
38 |
39 |
--------------------------------------------------------------------------------
/flow/base.js:
--------------------------------------------------------------------------------
1 | import type CustomConfig from '../src/custom-config.js';
2 |
3 |
--------------------------------------------------------------------------------
/flow/modules.js:
--------------------------------------------------------------------------------
1 | declare module 'hls.js' {
2 | declare module.exports: any;
3 | }
4 |
5 | declare module 'toxic-decorators' {
6 | declare module.exports: any;
7 | }
--------------------------------------------------------------------------------
/karma.conf.js:
--------------------------------------------------------------------------------
1 | // process.env.CHROME_BIN = require('puppeteer').executablePath();
2 | const { version, name } = require('./package.json');
3 | const { camelize } = require('toxic-utils');
4 |
5 | module.exports = function(config) {
6 | config.set({
7 | // base path that will be used to resolve all patterns (eg. files, exclude)
8 | basePath: '',
9 |
10 | // frameworks to use
11 | // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
12 | frameworks: [ 'mocha' ],
13 |
14 | // list of files / patterns to load in the browser
15 | files: [
16 | 'tests/**/*.js',
17 | ],
18 |
19 | // list of files to exclude
20 | exclude: [],
21 |
22 | // preprocess matching files before serving them to the browser
23 | // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
24 | preprocessors: {
25 | 'tests/**/*.js': [ 'rollup' ],
26 | 'src/**/*.js': [ 'coverage' ],
27 | },
28 |
29 | // test results reporter to use
30 | // possible values: 'dots', 'progress'
31 | // available reporters: https://npmjs.org/browse/keyword/karma-reporter
32 | reporters: [ 'mocha', 'coverage-istanbul', 'progress', 'coverage', 'coveralls' ],
33 |
34 | coverageIstanbulReporter: {
35 | reports: [ 'lcov', 'text-summary' ],
36 | },
37 |
38 | coverageReporter: {
39 | type: 'lcov',
40 | dir: 'coverage/',
41 | },
42 |
43 | rollupPreprocessor: {
44 | plugins: [
45 | require('rollup-plugin-babel')({
46 | presets: [
47 | 'flow',
48 | [ 'env', {
49 | modules: false,
50 | targets: {
51 | browsers: [ 'last 2 versions', 'not ie <= 8' ],
52 | },
53 | }],
54 | 'stage-0',
55 | ],
56 | exclude: 'node_modules/**',
57 | plugins: [
58 | 'istanbul',
59 | 'external-helpers',
60 | 'transform-decorators-legacy',
61 | 'transform-runtime',
62 | ],
63 | externalHelpers: true,
64 | runtimeHelpers: true,
65 | babelrc: false,
66 | }),
67 | require('rollup-plugin-flow-no-whitespace')(),
68 | require('rollup-plugin-node-resolve')({
69 | customResolveOptions: {
70 | moduleDirectory: [ 'src', 'node_modules' ],
71 | },
72 | }),
73 | require('rollup-plugin-commonjs')(),
74 | require('rollup-plugin-replace')({
75 | 'process.env.VERSION': `'${version}'`,
76 | 'process.env.TRAVIS': `${process.env.TRAVIS}`,
77 | }),
78 | ],
79 | output: {
80 | format: 'iife', // Helps prevent naming collisions.
81 | name: camelize(name), // Required for 'iife' format.
82 | },
83 | sourcemap: 'inline', // Sensible for testing.
84 | },
85 |
86 | // web server port
87 | port: 9876,
88 |
89 | // enable / disable colors in the output (reporters and logs)
90 | // colors: true,
91 |
92 | // level of logging
93 | // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
94 | logLevel: config.LOG_DEBUG,
95 |
96 | // enable / disable watching file and executing tests whenever any file changes
97 | autoWatch: false,
98 |
99 | // start these browsers
100 | // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
101 | browsers: [ 'FirefoxHeadless' ],
102 |
103 | customLaunchers: {
104 | FirefoxHeadless: {
105 | base: 'Firefox',
106 | flags: [ '-headless' ],
107 | },
108 | },
109 |
110 | // Continuous Integration mode
111 | // if true, Karma captures browsers, runs the tests and exits
112 | singleRun: true,
113 |
114 | // Concurrency level
115 | // how many browser should be started simultaneous
116 | concurrency: Infinity,
117 | });
118 | };
119 |
--------------------------------------------------------------------------------
/lib/index.js:
--------------------------------------------------------------------------------
1 |
2 | /**
3 | * chimee-kernel-hls v1.3.2
4 | * (c) 2017-2018 songguangyu
5 | * Released under MIT
6 | */
7 |
8 | 'use strict';
9 |
10 | function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
11 |
12 | var _Object$getOwnPropertyDescriptor = _interopDefault(require('babel-runtime/core-js/object/get-own-property-descriptor'));
13 | var _typeof = _interopDefault(require('babel-runtime/helpers/typeof'));
14 | var _Object$getPrototypeOf = _interopDefault(require('babel-runtime/core-js/object/get-prototype-of'));
15 | var _classCallCheck = _interopDefault(require('babel-runtime/helpers/classCallCheck'));
16 | var _possibleConstructorReturn = _interopDefault(require('babel-runtime/helpers/possibleConstructorReturn'));
17 | var _createClass = _interopDefault(require('babel-runtime/helpers/createClass'));
18 | var _inherits = _interopDefault(require('babel-runtime/helpers/inherits'));
19 | var HlsCore = _interopDefault(require('hls.js'));
20 | var chimeeHelper = require('chimee-helper');
21 | var toxicDecorators = require('toxic-decorators');
22 |
23 | var defaultCustomConfig = {
24 | debug: false,
25 | enableWorker: true
26 | };
27 |
28 | var _class;
29 |
30 | function _applyDecoratedDescriptor(target, property, decorators, descriptor, context) {
31 | var desc = {};
32 | Object['ke' + 'ys'](descriptor).forEach(function (key) {
33 | desc[key] = descriptor[key];
34 | });
35 | desc.enumerable = !!desc.enumerable;
36 | desc.configurable = !!desc.configurable;
37 |
38 | if ('value' in desc || desc.initializer) {
39 | desc.writable = true;
40 | }
41 |
42 | desc = decorators.slice().reverse().reduce(function (desc, decorator) {
43 | return decorator(target, property, desc) || desc;
44 | }, desc);
45 |
46 | if (context && desc.initializer !== void 0) {
47 | desc.value = desc.initializer ? desc.initializer.call(context) : void 0;
48 | desc.initializer = undefined;
49 | }
50 |
51 | if (desc.initializer === void 0) {
52 | Object['define' + 'Property'](target, property, desc);
53 | desc = null;
54 | }
55 |
56 | return desc;
57 | }
58 |
59 | var LOG_TAG = 'chimee-kernel-hls';
60 |
61 | var Hls = (_class = function (_CustEvent) {
62 | _inherits(Hls, _CustEvent);
63 |
64 | _createClass(Hls, null, [{
65 | key: 'isSupport',
66 | value: function isSupport() {
67 | return HlsCore.isSupported();
68 | }
69 | }]);
70 |
71 | function Hls(videoElement, config) {
72 | var customConfig = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
73 |
74 | _classCallCheck(this, Hls);
75 |
76 | var _this = _possibleConstructorReturn(this, (Hls.__proto__ || _Object$getPrototypeOf(Hls)).call(this));
77 |
78 | _this.version = '1.3.2';
79 |
80 | if (!chimeeHelper.isElement(videoElement)) throw new Error('video element passed in ' + LOG_TAG + ' must be a HTMLVideoElement, but not ' + (typeof videoElement === 'undefined' ? 'undefined' : _typeof(videoElement)));
81 | if (!chimeeHelper.isObject(config)) throw new Error('config of ' + LOG_TAG + ' must be an Object but not ' + (typeof config === 'undefined' ? 'undefined' : _typeof(config)));
82 | _this.video = videoElement;
83 | _this.config = config;
84 | _this.customConfig = chimeeHelper.deepAssign({}, defaultCustomConfig, customConfig);
85 | _this.hlsKernel = new HlsCore(_this.customConfig);
86 | _this.bindEvents();
87 | _this.attachMedia();
88 | return _this;
89 | }
90 |
91 | _createClass(Hls, [{
92 | key: 'bindEvents',
93 | value: function bindEvents() {
94 | var remove = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
95 |
96 | var hlsKernel = this.hlsKernel;
97 | /* istanbul ignore else */
98 | if (hlsKernel) {
99 | hlsKernel[remove ? 'off' : 'on'](HlsCore.Events.ERROR, this.hlsErrorHandler);
100 | }
101 | }
102 | }, {
103 | key: 'load',
104 | value: function load() {
105 | return this.hlsKernel.loadSource(this.config.src);
106 | }
107 | }, {
108 | key: 'startLoad',
109 | value: function startLoad() {
110 | return this.hlsKernel.startLoad();
111 | }
112 | }, {
113 | key: 'stopLoad',
114 | value: function stopLoad() {
115 | return this.hlsKernel.stopLoad();
116 | }
117 | }, {
118 | key: 'attachMedia',
119 | value: function attachMedia() {
120 | return this.hlsKernel.attachMedia(this.video);
121 | }
122 | }, {
123 | key: 'play',
124 | value: function play() {
125 | return this.video.play();
126 | }
127 | }, {
128 | key: 'destroy',
129 | value: function destroy() {
130 | this.bindEvents(true);
131 | return this.hlsKernel.destroy();
132 | }
133 | }, {
134 | key: 'seek',
135 | value: function seek(seconds) {
136 | this.video.currentTime = seconds;
137 | }
138 | }, {
139 | key: 'pause',
140 | value: function pause() {
141 | return this.video.pause();
142 | }
143 | }, {
144 | key: 'refresh',
145 | value: function refresh() {
146 | this.hlsKernel.stopLoad();
147 | return this.hlsKernel.loadSource(this.config.src);
148 | }
149 | }, {
150 | key: 'hlsErrorHandler',
151 | value: function hlsErrorHandler(event, data) {
152 | this.emit('error', data);
153 | this.emit(event, data);
154 | /* istanbul ignore next */
155 | chimeeHelper.Log.error(LOG_TAG + (event ? ' ' + event : ''), data.details);
156 | }
157 | }]);
158 |
159 | return Hls;
160 | }(chimeeHelper.CustEvent), (_applyDecoratedDescriptor(_class.prototype, 'hlsErrorHandler', [toxicDecorators.autobind], _Object$getOwnPropertyDescriptor(_class.prototype, 'hlsErrorHandler'), _class.prototype)), _class);
161 |
162 | module.exports = Hls;
163 |
--------------------------------------------------------------------------------
/lib/index.mjs:
--------------------------------------------------------------------------------
1 |
2 | /**
3 | * chimee-kernel-hls v1.3.2
4 | * (c) 2017-2018 songguangyu
5 | * Released under MIT
6 | */
7 |
8 | import _Object$getOwnPropertyDescriptor from 'babel-runtime/core-js/object/get-own-property-descriptor';
9 | import _typeof from 'babel-runtime/helpers/typeof';
10 | import _Object$getPrototypeOf from 'babel-runtime/core-js/object/get-prototype-of';
11 | import _classCallCheck from 'babel-runtime/helpers/classCallCheck';
12 | import _possibleConstructorReturn from 'babel-runtime/helpers/possibleConstructorReturn';
13 | import _createClass from 'babel-runtime/helpers/createClass';
14 | import _inherits from 'babel-runtime/helpers/inherits';
15 | import HlsCore from 'hls.js';
16 | import { CustEvent, deepAssign, Log, isElement, isObject } from 'chimee-helper';
17 | import { autobind } from 'toxic-decorators';
18 |
19 | var defaultCustomConfig = {
20 | debug: false,
21 | enableWorker: true
22 | };
23 |
24 | var _class;
25 |
26 | function _applyDecoratedDescriptor(target, property, decorators, descriptor, context) {
27 | var desc = {};
28 | Object['ke' + 'ys'](descriptor).forEach(function (key) {
29 | desc[key] = descriptor[key];
30 | });
31 | desc.enumerable = !!desc.enumerable;
32 | desc.configurable = !!desc.configurable;
33 |
34 | if ('value' in desc || desc.initializer) {
35 | desc.writable = true;
36 | }
37 |
38 | desc = decorators.slice().reverse().reduce(function (desc, decorator) {
39 | return decorator(target, property, desc) || desc;
40 | }, desc);
41 |
42 | if (context && desc.initializer !== void 0) {
43 | desc.value = desc.initializer ? desc.initializer.call(context) : void 0;
44 | desc.initializer = undefined;
45 | }
46 |
47 | if (desc.initializer === void 0) {
48 | Object['define' + 'Property'](target, property, desc);
49 | desc = null;
50 | }
51 |
52 | return desc;
53 | }
54 |
55 | var LOG_TAG = 'chimee-kernel-hls';
56 |
57 | var Hls = (_class = function (_CustEvent) {
58 | _inherits(Hls, _CustEvent);
59 |
60 | _createClass(Hls, null, [{
61 | key: 'isSupport',
62 | value: function isSupport() {
63 | return HlsCore.isSupported();
64 | }
65 | }]);
66 |
67 | function Hls(videoElement, config) {
68 | var customConfig = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
69 |
70 | _classCallCheck(this, Hls);
71 |
72 | var _this = _possibleConstructorReturn(this, (Hls.__proto__ || _Object$getPrototypeOf(Hls)).call(this));
73 |
74 | _this.version = '1.3.2';
75 |
76 | if (!isElement(videoElement)) throw new Error('video element passed in ' + LOG_TAG + ' must be a HTMLVideoElement, but not ' + (typeof videoElement === 'undefined' ? 'undefined' : _typeof(videoElement)));
77 | if (!isObject(config)) throw new Error('config of ' + LOG_TAG + ' must be an Object but not ' + (typeof config === 'undefined' ? 'undefined' : _typeof(config)));
78 | _this.video = videoElement;
79 | _this.config = config;
80 | _this.customConfig = deepAssign({}, defaultCustomConfig, customConfig);
81 | _this.hlsKernel = new HlsCore(_this.customConfig);
82 | _this.bindEvents();
83 | _this.attachMedia();
84 | return _this;
85 | }
86 |
87 | _createClass(Hls, [{
88 | key: 'bindEvents',
89 | value: function bindEvents() {
90 | var remove = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
91 |
92 | var hlsKernel = this.hlsKernel;
93 | /* istanbul ignore else */
94 | if (hlsKernel) {
95 | hlsKernel[remove ? 'off' : 'on'](HlsCore.Events.ERROR, this.hlsErrorHandler);
96 | }
97 | }
98 | }, {
99 | key: 'load',
100 | value: function load() {
101 | return this.hlsKernel.loadSource(this.config.src);
102 | }
103 | }, {
104 | key: 'startLoad',
105 | value: function startLoad() {
106 | return this.hlsKernel.startLoad();
107 | }
108 | }, {
109 | key: 'stopLoad',
110 | value: function stopLoad() {
111 | return this.hlsKernel.stopLoad();
112 | }
113 | }, {
114 | key: 'attachMedia',
115 | value: function attachMedia() {
116 | return this.hlsKernel.attachMedia(this.video);
117 | }
118 | }, {
119 | key: 'play',
120 | value: function play() {
121 | return this.video.play();
122 | }
123 | }, {
124 | key: 'destroy',
125 | value: function destroy() {
126 | this.bindEvents(true);
127 | return this.hlsKernel.destroy();
128 | }
129 | }, {
130 | key: 'seek',
131 | value: function seek(seconds) {
132 | this.video.currentTime = seconds;
133 | }
134 | }, {
135 | key: 'pause',
136 | value: function pause() {
137 | return this.video.pause();
138 | }
139 | }, {
140 | key: 'refresh',
141 | value: function refresh() {
142 | this.hlsKernel.stopLoad();
143 | return this.hlsKernel.loadSource(this.config.src);
144 | }
145 | }, {
146 | key: 'hlsErrorHandler',
147 | value: function hlsErrorHandler(event, data) {
148 | this.emit('error', data);
149 | this.emit(event, data);
150 | /* istanbul ignore next */
151 | Log.error(LOG_TAG + (event ? ' ' + event : ''), data.details);
152 | }
153 | }]);
154 |
155 | return Hls;
156 | }(CustEvent), (_applyDecoratedDescriptor(_class.prototype, 'hlsErrorHandler', [autobind], _Object$getOwnPropertyDescriptor(_class.prototype, 'hlsErrorHandler'), _class.prototype)), _class);
157 |
158 | export default Hls;
159 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "chimee-kernel-hls",
3 | "version": "1.3.2",
4 | "description": "kernel-hls of chimee",
5 | "main": "lib/index.js",
6 | "module": "lib/index.mjs",
7 | "jsnext:main": "lib/index.mjs",
8 | "browser": "lib/index.browser.js",
9 | "scripts": {
10 | "precommit": "npm run lint",
11 | "prepush": "npm run test",
12 | "prepublishOnly": "npm run lint && npm t && pkg-ok",
13 | "build": "npm run b-common && npm run b-es && npm run b-umd && npm run b-min",
14 | "b-common": "rollup -c build/rollup.config.common.js",
15 | "b-es": "rollup -c build/rollup.config.es.js",
16 | "b-umd": "rollup -c build/rollup.config.umd.js",
17 | "b-min": "rollup -c build/rollup.config.min.js",
18 | "start": "rollup -c build/rollup.config.dev.js -w",
19 | "lint": "eslint . --fix && flow check",
20 | "flow": "flow check",
21 | "test": "karma start karma.conf.js",
22 | "unit": "karma start karma.conf.js --auto-watch"
23 | },
24 | "repository": {
25 | "type": "git",
26 | "url": "git+https://github.com/Chimeejs/chimee-kernel-hls.git"
27 | },
28 | "keywords": [
29 | "kernel",
30 | "chimee",
31 | "video",
32 | "hls"
33 | ],
34 | "author": "songguangyu",
35 | "license": "MIT",
36 | "bugs": {
37 | "url": "https://github.com/Chimeejs/chimee-kernel-hls/issues"
38 | },
39 | "homepage": "https://github.com/Chimeejs/chimee-kernel-hls#readme",
40 | "dependencies": {
41 | "babel-runtime": "^6.26.0",
42 | "chimee-helper": "^0.2.11",
43 | "hls.js": "^0.9.1",
44 | "toxic-decorators": "^0.3.8"
45 | },
46 | "devDependencies": {
47 | "babel-core": "^6.26.3",
48 | "babel-eslint": "^8.2.3",
49 | "babel-plugin-istanbul": "^4.1.6",
50 | "babel-plugin-transform-decorators-legacy": "^1.3.5",
51 | "babel-plugin-transform-runtime": "^6.23.0",
52 | "babel-preset-env": "^1.7.0",
53 | "babel-preset-es2015-rollup": "^3.0.0",
54 | "babel-preset-flow": "^6.23.0",
55 | "babel-preset-latest": "^6.24.1",
56 | "babel-preset-stage-0": "^6.24.1",
57 | "chai": "^4.1.2",
58 | "chimee-kernel": "^1.4.0",
59 | "eslint": "^4.19.1",
60 | "eslint-config-egg": "^7.0.0",
61 | "eslint-plugin-flowtype": "^2.49.3",
62 | "flow-bin": "^0.73.0",
63 | "husky": "^0.14.3",
64 | "karma": "^2.0.2",
65 | "karma-coverage": "^1.1.2",
66 | "karma-coverage-istanbul-reporter": "^2.0.1",
67 | "karma-coveralls": "^1.2.1",
68 | "karma-firefox-launcher": "^1.1.0",
69 | "karma-mocha": "^1.3.0",
70 | "karma-mocha-reporter": "^2.2.5",
71 | "karma-rollup-preprocessor": "^6.0.0",
72 | "karma-sourcemap-loader": "^0.3.7",
73 | "mocha": "^5.2.0",
74 | "pkg-ok": "^2.2.0",
75 | "puppeteer": "^1.4.0",
76 | "rollup": "^0.59.4",
77 | "rollup-plugin-babel": "^3.0.4",
78 | "rollup-plugin-commonjs": "^9.1.3",
79 | "rollup-plugin-flow-no-whitespace": "^1.0.0",
80 | "rollup-plugin-includepaths": "^0.2.2",
81 | "rollup-plugin-livereload": "^0.6.0",
82 | "rollup-plugin-node-resolve": "^3.3.0",
83 | "rollup-plugin-replace": "^2.0.0",
84 | "rollup-plugin-serve": "^0.4.2",
85 | "rollup-plugin-uglify": "^4.0.0",
86 | "rollup-watch": "^4.3.1"
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
1 | # chimee-kernel-hls
2 |
3 | [](https://travis-ci.org/Chimeejs/chimee-kernel-hls.svg?branch=master)
4 | [](https://coveralls.io/github/Chimeejs/chimee-kernel-hls?branch=master)
5 | [](https://www.npmjs.com/package/chimee-kernel-hls)
6 | [](https://david-dm.org/Chimeejs/chimee-kernel-hls)
7 | [](https://david-dm.org/Chimeejs/chimee-kernel-hls?type=dev)
8 |
9 | chimee-kernel-hls is the decoder for [chimee](https://github.com/Chimeejs/chimee). It can decode m3u8 on browser.
10 |
11 | It's based on [hls.js](https://github.com/video-dev/hls.js).
12 |
13 | It totally fit the requirement of [chimee-kernel](https://github.com/Chimeejs/chimee-kernel).
14 |
15 | It should only be used in the PC, as most of mobile browser support m3u8.
16 |
17 | ## Installation
18 | ```
19 | npm install --save chimee-kernel-hls
20 | ```
21 | ## Usage
22 |
23 | You can use chimee-kernel-hls in chimee or chimee-player like this.
24 |
25 | ```javascript
26 | import Chimee from 'chimee';
27 | import ChimeeKernelHls from 'chimee-kernel-hls';
28 | const chimee = new Chimee({
29 | wrapper: '#wrapper',
30 | src: 'http://cdn.toxicjohann.com/lostStar.mp4',
31 | controls: true,
32 | autoplay: true,
33 | kernels: {
34 | hls: ChimeeKernelHls,
35 | }
36 | });
37 | chimee.play();
38 | ```
39 |
40 | We also support custom config on hls.js, such as config describe in the [document](https://github.com/video-dev/hls.js/blob/master/doc/API.md#fine-tuning).
41 |
42 | ```Javascript
43 | import Chimee from 'chimee';
44 | import ChimeeKernelHls from 'chimee-kernel-hls';
45 | const chimee = new Chimee({
46 | wrapper: '#wrapper',
47 | src: 'http://cdn.toxicjohann.com/lostStar.mp4',
48 | controls: true,
49 | autoplay: true,
50 | kernels: {
51 | hls: {
52 | handler: ChimeeKernelHls,
53 | debug: true,
54 | }
55 | }
56 | });
57 | chimee.play();
58 | ```
--------------------------------------------------------------------------------
/rollup:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Chimeejs/chimee-kernel-hls/e09bed717bf7bc62086642120e48b5975d3c89be/rollup
--------------------------------------------------------------------------------
/src/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Chimeejs/chimee-kernel-hls/e09bed717bf7bc62086642120e48b5975d3c89be/src/.DS_Store
--------------------------------------------------------------------------------
/src/custom-config.js:
--------------------------------------------------------------------------------
1 | export default {
2 | debug: false,
3 | enableWorker: true,
4 | };
5 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | // @flow
2 | import HlsCore from 'hls.js';
3 | import { CustEvent, deepAssign, Log, isElement, isObject } from 'chimee-helper';
4 | import defaultCustomConfig from './custom-config.js';
5 | import { autobind } from 'toxic-decorators';
6 |
7 | const LOG_TAG = 'chimee-kernel-hls';
8 |
9 | export default class Hls extends CustEvent {
10 | version: string;
11 | video: HTMLVideoElement;
12 | config: KernelConfig;
13 | customConfig: CustomConfig;
14 | version = process.env.VERSION;
15 | hlsKernel: any
16 |
17 | static isSupport() {
18 | return HlsCore.isSupported();
19 | }
20 |
21 | constructor(videoElement: HTMLVideoElement, config: KernelConfig, customConfig: CustomConfig = {}) {
22 | super();
23 | if (!isElement(videoElement)) throw new Error(`video element passed in ${LOG_TAG} must be a HTMLVideoElement, but not ${typeof videoElement}`);
24 | if (!isObject(config)) throw new Error(`config of ${LOG_TAG} must be an Object but not ${typeof config}`);
25 | this.video = videoElement;
26 | this.config = config;
27 | this.customConfig = deepAssign({}, defaultCustomConfig, customConfig);
28 | this.hlsKernel = new HlsCore(this.customConfig);
29 | this.bindEvents();
30 | this.attachMedia();
31 | }
32 |
33 | bindEvents(remove: boolean = false) {
34 | const hlsKernel = this.hlsKernel;
35 | /* istanbul ignore else */
36 | if (hlsKernel) {
37 | hlsKernel[remove ? 'off' : 'on'](HlsCore.Events.ERROR, this.hlsErrorHandler);
38 | }
39 | }
40 |
41 | load() {
42 | return this.hlsKernel.loadSource(this.config.src);
43 | }
44 |
45 | startLoad() {
46 | return this.hlsKernel.startLoad();
47 | }
48 |
49 | stopLoad() {
50 | return this.hlsKernel.stopLoad();
51 | }
52 |
53 | attachMedia() {
54 | return this.hlsKernel.attachMedia(this.video);
55 | }
56 |
57 | play() {
58 | return this.video.play();
59 | }
60 |
61 | destroy() {
62 | this.bindEvents(true);
63 | return this.hlsKernel.destroy();
64 | }
65 |
66 | seek(seconds: number) {
67 | this.video.currentTime = seconds;
68 | }
69 |
70 | pause() {
71 | return this.video.pause();
72 | }
73 |
74 | refresh() {
75 | this.hlsKernel.stopLoad();
76 | return this.hlsKernel.loadSource(this.config.src);
77 | }
78 |
79 | @autobind
80 | hlsErrorHandler(event: string, data: Object) {
81 | this.emit('error', data);
82 | this.emit(event, data);
83 | /* istanbul ignore next */
84 | Log.error(LOG_TAG + (event ? ' ' + event : ''), data.details);
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/tests/index.js:
--------------------------------------------------------------------------------
1 | import ChimeeKernelHls from '../src/index';
2 | import chai from 'chai';
3 | import { isFunction } from 'chimee-helper';
4 | const { expect } = chai;
5 | describe('chimee-kernel base requirement', () => {
6 | let videoElement;
7 | beforeEach(() => {
8 | videoElement = document.createElement('video');
9 | });
10 | afterEach(() => {
11 | videoElement = null;
12 | });
13 | it('isSupport', () => {
14 | expect(ChimeeKernelHls.isSupport()).to.equal(!process.env.TRAVIS);
15 | });
16 | it('base method', () => {
17 | const config = {
18 | src: 'https://video-dev.github.io/streams/x36xhzz/x36xhzz.m3u8',
19 | box: 'hls',
20 | isLive: false,
21 | };
22 | const kernel = new ChimeeKernelHls(videoElement, config, {
23 | debug: true,
24 | });
25 | expect(kernel.config).to.deep.equal(config);
26 | expect(kernel.video).to.equal(videoElement);
27 | expect(isFunction(kernel.load)).to.equal(true);
28 | expect(isFunction(kernel.play)).to.equal(true);
29 | expect(isFunction(kernel.pause)).to.equal(true);
30 | expect(isFunction(kernel.refresh)).to.equal(true);
31 | expect(isFunction(kernel.attachMedia)).to.equal(true);
32 | expect(isFunction(kernel.seek)).to.equal(true);
33 | expect(isFunction(kernel.destroy)).to.equal(true);
34 | expect(isFunction(kernel.on)).to.equal(true);
35 | expect(isFunction(kernel.off)).to.equal(true);
36 | expect(isFunction(kernel.once)).to.equal(true);
37 | expect(isFunction(kernel.emit)).to.equal(true);
38 | kernel.destroy();
39 | });
40 | });
41 |
42 | describe('method it', () => {
43 | let kernel;
44 | let config;
45 | let videoElement;
46 | beforeEach(() => {
47 | videoElement = document.createElement('video');
48 | config = {
49 | src: 'https://video-dev.github.io/streams/x36xhzz/x36xhzz.m3u8',
50 | box: 'hls',
51 | isLive: false,
52 | };
53 | kernel = new ChimeeKernelHls(videoElement, config, {});
54 | });
55 | afterEach(() => {
56 | kernel.destroy();
57 | videoElement = null;
58 | config = undefined;
59 | });
60 | it('refresh', async () => {
61 | expect(kernel.config.src).to.equal(config.src);
62 | const videoSrc = kernel.video.src;
63 | await kernel.refresh();
64 | expect(kernel.config.src).to.equal(config.src);
65 | expect(kernel.video.src).to.equal(videoSrc);
66 | });
67 | it('load', () => {
68 | expect(kernel.config.src).to.equal(config.src);
69 | const videoSrc = kernel.video.src;
70 | kernel.load();
71 | expect(kernel.config.src).to.equal(config.src);
72 | expect(kernel.video.src).to.equal(videoSrc);
73 | });
74 | it('seek', () => {
75 | expect(kernel.video.currentTime).to.equal(0);
76 | kernel.load();
77 | expect(kernel.video.currentTime).to.equal(0);
78 | kernel.seek(10);
79 | expect(kernel.video.currentTime).to.equal(10);
80 | });
81 | it('play & pause', () => {
82 | expect(() => {
83 | kernel.attachMedia();
84 | kernel.load();
85 | kernel.play();
86 | kernel.pause();
87 | }).not.to.throw();
88 | });
89 | it('startload & stopLoad', () => {
90 | expect(() => {
91 | kernel.attachMedia();
92 | kernel.load();
93 | kernel.stopLoad();
94 | kernel.startLoad();
95 | }).not.to.throw();
96 | });
97 | });
98 |
99 | describe('error branch', () => {
100 | let videoElement;
101 | beforeEach(() => {
102 | videoElement = document.createElement('video');
103 | });
104 | afterEach(() => {
105 | videoElement = null;
106 | });
107 | it('no video element', () => {
108 | expect(() => new ChimeeKernelHls()).to.throw('video element passed in chimee-kernel-hls must be a HTMLVideoElement, but not undefined');
109 | });
110 | it('no config', () => {
111 | expect(() => new ChimeeKernelHls(videoElement)).to.throw('config of chimee-kernel-hls must be an Object but not undefined');
112 | });
113 | it('error handler', done => {
114 | const config = {
115 | src: 'http://cdn.toxicjohann.com',
116 | box: 'hls',
117 | isLive: false,
118 | };
119 | const kernel = new ChimeeKernelHls(videoElement, config, {
120 | debug: true,
121 | });
122 | kernel.on('error', () => {
123 | done();
124 | });
125 | expect(() => kernel.hlsKernel.trigger('hlsError', { type: 'test', details: 'something wrong', fatal: false })).not.to.throw();
126 | });
127 | });
128 |
--------------------------------------------------------------------------------