移除flv插件

This commit is contained in:
Harvey Zack committed 2019-04-25 09:17:53 +08:00
1 parent 43f8e9d935
commit d626ee601e
18 files changed
-652

No files matched your search

-1
View File
@@ -32,7 +32,6 @@
| Project | Description | Demo |
| --------------------------------------------------------------------------------------------------------------------- | ------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------- |
| [artplayer-plugin-danmu](https://github.com/zhw2590582/ArtPlayer/tree/master/packages/artplayer-plugin-danmu) | Danmu plugin for ArtPlayer | `WIP` |
| [artplayer-plugin-flv](https://github.com/zhw2590582/ArtPlayer/tree/master/packages/artplayer-plugin-flv) | Flv plugin for ArtPlayer | `WIP` |
| [artplayer-plugin-gif](https://github.com/zhw2590582/ArtPlayer/tree/master/packages/artplayer-plugin-gif) | Gif plugin for ArtPlayer | [demo](https://artplayer.org/?libs=.%2Funcompiled%2Fartplayer-plugin-gif.js&example=gif) |
| [artplayer-plugin-backlight](https://github.com/zhw2590582/ArtPlayer/tree/master/packages/artplayer-plugin-backlight) | Backlight plugin for ArtPlayer | [demo](https://artplayer.org/?libs=.%2Funcompiled%2Fartplayer-plugin-backlight.js&example=backlight) |
| [artplayer-plugin-playlist](https://github.com/zhw2590582/ArtPlayer/tree/master/packages/artplayer-plugin-playlist) | Playlist plugin for ArtPlayer | [demo](https://artplayer.org/?libs=.%2Funcompiled%2Fartplayer-plugin-playlist.js%0A.%2Funcompiled%2Fartplayer-plugin-playlist.css&example=playlist) |
-9
View File
@@ -1,9 +0,0 @@
node_modules
.DS_Store
yarn.lock
package-lock.json
test
coverage
.nyc_output
.cache
docs
-1
View File
@@ -1 +0,0 @@
package-lock=false
-3
View File
@@ -1,3 +0,0 @@
# artplayer-plugin-flv
Flv plugin for ArtPlayer
@@ -1,8 +0,0 @@
/*!
* artplayer-plugin-flv.js v3.1.7
* Github: https://github.com/zhw2590582/ArtPlayer#readme
* (c) 2017-2019 Harvey Zack
* Released under the MIT License.
*/
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e=e||self)["artplayer-plugin-flv"]=t()}(this,function(){"use strict";var a=function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")};function r(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}var c=function(e,t,n){return t&&r(e.prototype,t),n&&r(e,n),e};function e(e,t){return e(t={exports:{}},t.exports),t.exports}var n=e(function(t){function n(e){return(n="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function r(e){return"function"==typeof Symbol&&"symbol"===n(Symbol.iterator)?t.exports=r=function(e){return n(e)}:t.exports=r=function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":n(e)},r(e)}t.exports=r});var o=function(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e};var i=function(e,t){return!t||"object"!==n(t)&&"function"!=typeof t?o(e):t},u=e(function(t){function n(e){return t.exports=n=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)},n(e)}t.exports=n}),s=e(function(n){function r(e,t){return n.exports=r=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},r(e,t)}n.exports=r});var t=function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&s(e,t)};function f(){}f.prototype={on:function(e,t,n){var r=this.e||(this.e={});return(r[e]||(r[e]=[])).push({fn:t,ctx:n}),this},once:function(e,t,n){var r=this;function o(){r.off(e,o),t.apply(n,arguments)}return o._=t,this.on(e,o,n)},emit:function(e){for(var t=[].slice.call(arguments,1),n=((this.e||(this.e={}))[e]||[]).slice(),r=0,o=n.length;r<o;r++)n[r].fn.apply(n[r].ctx,t);return this},off:function(e,t){var n=this.e||(this.e={}),r=n[e],o=[];if(r&&t)for(var i=0,a=r.length;i<a;i++)r[i].fn!==t&&r[i].fn._!==t&&o.push(r[i]);return o.length?n[e]=o:delete n[e],this}};var l=f,p=f;l.TinyEmitter=p;var d=function(e){if(Array.isArray(e)){for(var t=0,n=new Array(e.length);t<e.length;t++)n[t]=e[t];return n}};var h=function(e){if(Symbol.iterator in Object(e)||"[object Arguments]"===Object.prototype.toString.call(e))return Array.from(e)};var v=function(){throw new TypeError("Invalid attempt to spread non-iterable instance")};var y=function(e){return d(e)||h(e)||v()};var m=function(e){return-1!==Function.toString.call(e).indexOf("[native code]")},g=e(function(r){function o(e,t,n){return!function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],function(){})),!0}catch(e){return!1}}()?r.exports=o=function(e,t,n){var r=[null];r.push.apply(r,t);var o=new(Function.bind.apply(e,r));return n&&s(o,n.prototype),o}:r.exports=o=Reflect.construct,o.apply(null,arguments)}r.exports=o}),b=function(e){function r(e,t){var n;return a(this,r),n=i(this,u(r).call(this,e)),"function"==typeof Error.captureStackTrace&&Error.captureStackTrace(o(n),t||n.constructor),n.name="FlvError",n}return t(r,e),r}(e(function(t){function r(e){var n="function"==typeof Map?new Map:void 0;return t.exports=r=function(e){if(null===e||!m(e))return e;if("function"!=typeof e)throw new TypeError("Super expression must either be null or a function");if(void 0!==n){if(n.has(e))return n.get(e);n.set(e,t)}function t(){return g(e,arguments,u(this).constructor)}return t.prototype=Object.create(e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),s(t,e)},r(e)}t.exports=r})(Error));function w(e,t){if(!e)throw new b(t)}function S(e,t){var n=new e.constructor(e.length+t.length);return n.set(e),n.set(t,e.length),n}function k(r){return r.reduce(function(e,t,n){return e+t*Math.pow(256,r.length-n-1)},0)}function x(e){var t;return(t=String.fromCharCode).call.apply(t,[String].concat(y(e)))}function E(e){var n=new DataView(new ArrayBuffer(e.length));return e.forEach(function(e,t){n.setUint8(t,e)}),n.getFloat64(0)}function O(e){return 1===e}function T(o){var i=0;return function e(t){for(var n=new Uint8Array(t),r=0;r<t;r+=1)n[r]=o[i],i+=1;return e.index=i,n}}var j=Object.freeze({errorHandle:w,mergeTypedArrays:S,sleep:function(){var t=0<arguments.length&&void 0!==arguments[0]?arguments[0]:0;return new Promise(function(e){return setTimeout(e,t)})},getUint8Sum:k,string2Bin:function(e){for(var t=[],n=0;n<e.length;n+=1)t.push(Number(e.charCodeAt(n).toString(10)));return t},bin2String:x,bin2Float:E,bin2Boolean:O,log:function(Line truncated
@@ -1,26 +0,0 @@
{
"name": "artplayer-plugin-flv",
"version": "3.1.7",
"description": "Flv plugin for ArtPlayer",
"main": "dist/artplayer-plugin-flv.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "git+https://github.com/zhw2590582/ArtPlayer.git"
},
"keywords": [
"video",
"player"
],
"author": "Harvey Zack <laozhaochaguan@gmail.com>",
"license": "MIT",
"bugs": {
"url": "https://github.com/zhw2590582/ArtPlayer/issues"
},
"homepage": "https://github.com/zhw2590582/ArtPlayer#readme",
"dependencies": {
"tiny-emitter": "^2.0.2"
}
}
@@ -1,58 +0,0 @@
export default {
mediaSource: {
propertys: [
'activeSourceBuffers',
'duration',
'readyState',
'sourceBuffers',
],
methods: [
'addSourceBuffer',
'endOfStream',
'removeSourceBuffer',
'clearLiveSeekableRange',
'setLiveSeekableRange',
],
events: [
'sourceclose',
'sourceended',
'sourceopen',
],
},
sourceBuffer: {
propertys: [
'mode',
'updating',
'buffered',
'timestampOffset',
'audioTracks',
'videoTracks',
'textTracks',
'appendWindowStart',
'appendWindowEnd',
'trackDefaults',
],
methods: [
'appendBuffer',
'appendStream',
'abort',
'remove',
],
events: [
'abort',
'error',
'update',
'updateend',
'updatestart',
],
},
sourceBufferList: {
propertys: [
'length',
],
events: [
'addsourcebuffer',
'removesourcebuffer',
],
},
};
@@ -1,43 +0,0 @@
import config from './config';
export default class CreatMediaSource {
constructor(flv) {
this.flv = flv;
this.creatUrl();
this.eventBind();
}
creatUrl() {
const {
options: { mediaElement },
events: { destroyEvents },
} = this.flv;
this.mediaSource = new MediaSource();
const url = URL.createObjectURL(this.mediaSource);
destroyEvents.push(() => {
URL.revokeObjectURL(url);
});
mediaElement.src = url;
}
eventBind() {
const {
events: { proxy },
} = this.flv;
config.mediaSource.events.forEach(eventName => {
proxy(this.mediaSource, eventName, event => {
this.flv.emit(`mediaSource:${event.type}`, event);
});
});
config.sourceBufferList.events.forEach(eventName => {
proxy(this.mediaSource.sourceBuffers, eventName, event => {
this.flv.emit(`sourceBuffers:${event.type}`, event);
});
proxy(this.mediaSource.activeSourceBuffers, eventName, event => {
this.flv.emit(`activeSourceBuffers:${event.type}`, event);
});
});
}
}
@@ -1,58 +0,0 @@
export default class CreatWorker {
constructor() {
this.workers = new Map();
}
static fnToStr(fn) {
return `
self.onmessage = event => {
return self.postMessage((${fn}).apply(null, event.data));
}
`;
}
static create(fn) {
const blob = new Blob([CreatWorker.fnToStr(fn)], {
type: 'application/javascript',
});
const objectURL = window.URL.createObjectURL(blob);
const worker = new Worker(objectURL);
worker.kill = () => {
URL.revokeObjectURL(objectURL);
worker.terminate();
};
worker.post = args =>
new Promise((resolve, reject) => {
worker.onmessage = event => {
resolve(event.data);
};
worker.onerror = error => {
reject(error);
};
worker.postMessage(args);
});
return worker;
}
add(name, fn) {
if (!this.workers.has(name)) {
this.workers.set(name, CreatWorker.create(fn));
}
}
run(name, ...args) {
const worker = this.workers.get(name);
return worker.post(args);
}
kill(name) {
const worker = this.workers.get(name);
worker.kill();
}
killAll() {
this.workers.forEach(worker => {
worker.kill();
});
}
}
@@ -1,17 +0,0 @@
export default class EventProxy {
constructor() {
this.destroyEvents = [];
this.proxy = this.proxy.bind(this);
}
proxy(target, name, callback, option = {}) {
target.addEventListener(name, callback, option);
this.destroyEvents.push(() => {
target.removeEventListener(name, callback, option);
});
}
destroy() {
this.destroyEvents.forEach(event => event());
}
}
@@ -1,49 +0,0 @@
import { errorHandle } from '../utils';
export default function fetchStream(flv, url) {
flv.emit('flvFetchStart');
fetch(url).then(response => {
errorHandle(
response.ok && response.status >= 200 && response.status <= 299,
`${response.status} ${response.statusText}`,
);
const contentType = response.headers.get('content-type');
errorHandle(contentType.includes('x-flv'), 'The resource does not seem to be a flv file');
return new Response(
new ReadableStream({
start(controller) {
const reader = response.body.getReader();
flv.on('destroy', () => {
reader.cancel();
});
flv.on('readerCancel', () => {
reader.cancel();
});
(function read() {
reader
.read()
.then(({ done, value }) => {
if (done) {
flv.emit('flvFetchEnd');
controller.close();
return;
}
flv.emit('flvFetching', new Uint8Array(value));
controller.enqueue(value);
read();
})
.catch(error => {
throw error;
});
})();
},
cancel() {
flv.emit('flvFetchCancel');
},
}),
);
});
}
@@ -1,110 +0,0 @@
import fetchStream from './fetchStream';
import readFile from './readFile';
import parseScripTag from './parseScripTag';
import { mergeTypedArrays, getUint8Sum, bin2String } from '../utils';
export default class FlvParse {
constructor(flv) {
this.flv = flv;
const { url, debug } = flv.options;
this.uint8 = new Uint8Array(0);
this.index = 0;
this.header = null;
this.scripTag = null;
this.tags = [];
this.done = false;
flv.on('flvFetchStart', () => {
if (debug) {
console.log('[flv-fetch-start]', url);
}
});
flv.on('flvFetchCancel', () => {
if (debug) {
console.log('[flv-fetch-cancel]');
}
});
flv.on('flvFetching', uint8 => {
this.uint8 = mergeTypedArrays(this.uint8, uint8);
this.parse();
});
flv.on('flvFetchEnd', uint8 => {
if (debug) {
console.log('[flv-fetch-end]');
}
this.done = true;
if (uint8) {
this.uint8 = uint8;
this.index = 0;
this.header = null;
this.scripTag = null;
this.tags = [];
this.parse();
}
flv.emit('flvParseDone');
if (debug) {
console.log('[flv-parse-done]');
}
});
if (typeof url === 'string') {
fetchStream(flv, url);
} else {
readFile(flv, url);
}
}
parse() {
const { debug } = this.flv.options;
if (this.uint8.length >= 13 && !this.header) {
const header = Object.create(null);
header.signature = bin2String(this.read(3));
[header.version] = this.read(1);
[header.flags] = this.read(1);
header.headersize = getUint8Sum(this.read(4));
this.header = header;
this.read(4);
this.flv.emit('flvParseHeader', this.header);
if (debug) {
console.log('[flv-parse-header]', this.header);
}
}
while (this.index < this.uint8.length) {
const tag = Object.create(null);
[tag.tagType] = this.read(1);
tag.dataSize = getUint8Sum(this.read(3));
tag.timestamp = this.read(4);
tag.streamID = this.read(3);
tag.body = this.read(tag.dataSize);
this.tags.push(tag);
this.read(4);
switch (tag.tagType) {
case 18:
this.scripTag = parseScripTag(tag.body);
this.flv.emit('parseScripTag', this.scripTag);
if (debug) {
console.log('[flv-parse-scrip-tag]', this.scripTag);
}
break;
default:
break;
}
this.flv.emit('flvParseTag', tag);
}
}
read(length) {
const tempUint8 = new Uint8Array(length);
for (let i = 0; i < length; i += 1) {
tempUint8[i] = this.uint8[this.index];
this.index += 1;
}
return tempUint8;
}
}
@@ -1,104 +0,0 @@
import { getUint8Sum, readUint8, bin2String, bin2Boolean, bin2Float, errorHandle } from '../utils';
export default function parseScripTag(scripTagBody) {
const readScripTag = readUint8(scripTagBody);
const metadata = Object.create(null);
const amf1 = Object.create(null);
const amf2 = Object.create(null);
[amf1.type] = readScripTag(1);
errorHandle(amf1.type === 2, `AMF: [amf1] type expect 2, but got ${amf1.type}`);
amf1.size = getUint8Sum(readScripTag(2));
amf1.string = bin2String(readScripTag(amf1.size));
[amf2.type] = readScripTag(1);
errorHandle(amf2.type === 8, `AMF: [amf1] type expect 8, but got ${amf2.type}`);
amf2.size = getUint8Sum(readScripTag(4));
amf2.metaData = Object.create(null);
function getValue(type) {
let value = null;
if (type !== undefined) {
switch (type) {
case 0:
value = bin2Float(readScripTag(8));
break;
case 1:
value = bin2Boolean(readScripTag(1)[0]);
break;
case 2: {
const valueLength = getUint8Sum(readScripTag(2));
value = bin2String(readScripTag(valueLength));
break;
}
case 3: {
value = Object.create(null);
let endObject = false;
while (!endObject && readScripTag.index < scripTagBody.length) {
const nameLength = getUint8Sum(readScripTag(2));
const name = bin2String(readScripTag(nameLength));
const type = readScripTag(1)[0];
if (name) {
value[name] = getValue(type);
}
if (type === 9) {
endObject = true;
}
}
break;
}
case 8: {
value = Object.create(null);
let endArray = false;
while (!endArray && readScripTag.index < scripTagBody.length) {
const nameLength = getUint8Sum(readScripTag(2));
const name = bin2String(readScripTag(nameLength));
const type = readScripTag(1)[0];
if (name) {
value[name] = getValue(type);
}
if (type === 9) {
endArray = true;
}
}
break;
}
case 10: {
const valueLength = getUint8Sum(readScripTag(4));
value = [];
for (let index = 0; index < valueLength; index += 1) {
const itemType = readScripTag(1)[0];
value.push(getValue(itemType));
}
break;
}
case 12: {
const valueLength = getUint8Sum(readScripTag(4));
value = bin2String(readScripTag(valueLength));
break;
}
default:
console.log(readScripTag(scripTagBody.length - readScripTag.index - 1));
errorHandle(false, `AMF: Unknown metaData type: ${type}`);
break;
}
}
return value;
}
while (readScripTag.index < scripTagBody.length) {
const nameLength = getUint8Sum(readScripTag(2));
const name = bin2String(readScripTag(nameLength));
const type = readScripTag(1)[0];
if (name) {
amf2.metaData[name] = getValue(type);
}
}
errorHandle(readScripTag.index === scripTagBody.length, 'AMF: Seems to be incompletely parsed');
errorHandle(amf2.size === Object.keys(amf2.metaData).length, 'AMF: [amf2] length does not match');
metadata.amf1 = amf1;
metadata.amf2 = amf2;
return metadata;
}
@@ -1,11 +0,0 @@
export default function readFile(flv, file) {
flv.emit('flvFetchStart');
const { proxy } = flv.events;
const reader = new FileReader();
proxy(reader, 'load', e => {
const buffer = e.target.result;
const uint8 = new Uint8Array(buffer);
flv.emit('flvFetchEnd', uint8);
});
reader.readAsArrayBuffer(file);
}
@@ -1,58 +0,0 @@
import Emitter from 'tiny-emitter';
import checkSupport from './utils/checkSupport';
import EventProxy from './eventProxy';
import CreatWorker from './creatWorker';
import CreatMediaSource from './creatMediaSource';
import FlvParse from './flvParse';
import * as utils from './utils';
import config from './config';
let id = 0;
class Flv extends Emitter {
constructor(options) {
super();
this.options = Object.assign({}, Flv.DEFAULTS, options);
checkSupport(this.options);
this.events = new EventProxy(this);
this.workers = new CreatWorker(this);
this.mediaSource = new CreatMediaSource(this);
this.flvData = new FlvParse(this);
id += 1;
this.id = id;
Flv.instances.push(this);
}
static get DEFAULTS() {
return {
mediaElement: '',
url: '',
debug: false,
};
}
static get version() {
return '__VERSION__';
}
static get config() {
return config;
}
static get utils() {
return utils;
}
destroy() {
this.events.destroy();
this.workers.killAll();
Flv.instances.splice(Flv.instances.indexOf(this), 1);
this.emit('destroy');
}
}
Object.defineProperty(Flv, 'instances', {
value: [],
});
window.Flv = Flv;
export default Flv;
@@ -1,24 +0,0 @@
import { errorHandle } from '.';
export default function checkSupport(options) {
const { mediaElement, url } = options;
errorHandle(mediaElement instanceof HTMLVideoElement, 'The first parameter is not a video tag element');
errorHandle(
typeof url === 'string' || (url instanceof File && url.type === 'video/x-flv'),
'The second parameter is not a string type or flv file',
);
const MP4H264MimeCodec = 'video/mp4; codecs="avc1.42001E, mp4a.40.2"';
const canPlay = mediaElement.canPlayType(MP4H264MimeCodec);
errorHandle(
window.MediaSource &&
window.MediaSource.isTypeSupported(MP4H264MimeCodec) &&
(canPlay === 'probably' || canPlay === 'maybe'),
`Unsupported MIME type or codec: ${MP4H264MimeCodec}`,
);
errorHandle(typeof window.Promise === 'function', "Unsupported 'Promise' method");
errorHandle(typeof window.fetch === 'function', "Unsupported 'fetch' method");
errorHandle(typeof window.Worker === 'function', "Unsupported 'Worker' method");
errorHandle(typeof window.ReadableStream === 'function', "Unsupported 'ReadableStream' method");
}
@@ -1,9 +0,0 @@
export default class FlvError extends Error {
constructor(message, context) {
super(message);
if (typeof Error.captureStackTrace === 'function') {
Error.captureStackTrace(this, context || this.constructor);
}
this.name = 'FlvError';
}
}
@@ -1,63 +0,0 @@
import FlvError from './flvError';
export function errorHandle(condition, msg) {
if (!condition) {
throw new FlvError(msg);
}
}
export function mergeTypedArrays(a, b) {
const c = new a.constructor(a.length + b.length);
c.set(a);
c.set(b, a.length);
return c;
}
export function sleep(ms = 0) {
return new Promise(resolve => setTimeout(resolve, ms));
}
export function getUint8Sum(arr) {
return arr.reduce((totle, num, index) => totle + num * 256 ** (arr.length - index - 1), 0);
}
export function string2Bin(str) {
const result = [];
for (let i = 0; i < str.length; i += 1) {
result.push(Number(str.charCodeAt(i).toString(10)));
}
return result;
}
export function bin2String(array) {
return String.fromCharCode.call(String, ...array);
}
export function bin2Float(array) {
const view = new DataView(new ArrayBuffer(array.length));
array.forEach((b, i) => {
view.setUint8(i, b);
});
return view.getFloat64(0);
}
export function bin2Boolean(bin) {
return bin === 1;
}
export function log(name, msg = '') {
console.log(`[${name}] ${msg}`);
}
export function readUint8(uint8) {
let index = 0;
return function read(length) {
const tempUint8 = new Uint8Array(length);
for (let i = 0; i < length; i += 1) {
tempUint8[i] = uint8[index];
index += 1;
}
read.index = index;
return tempUint8;
};
}