mirror of
https://github.com/zhw2590582/ArtPlayer.git
synced 2026-10-26 08:51:20 -08:00
添加字幕插件
This commit is contained in:
1 parent
5f384fb04d
commit
1667457188
24 files changed
+492
-247
No files matched your search
@@ -1,3 +0,0 @@
|
||||
export default function contextmenuMix(art) {
|
||||
//
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
export default function controlMix(art) {
|
||||
//
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
export default function i18n(art) {
|
||||
//
|
||||
}
|
||||
@@ -1,27 +1,8 @@
|
||||
import './index.scss';
|
||||
|
||||
function i18nMix() {
|
||||
//
|
||||
}
|
||||
|
||||
function contextmenuMix(art) {
|
||||
//
|
||||
}
|
||||
|
||||
function settingMix(art) {
|
||||
//
|
||||
}
|
||||
|
||||
function controlMix(art) {
|
||||
//
|
||||
}
|
||||
|
||||
function artplayerPluginDanmu(Artplayer) {
|
||||
const art = Artplayer.prototype;
|
||||
i18nMix(art);
|
||||
contextmenuMix(art);
|
||||
settingMix(art);
|
||||
controlMix(art);
|
||||
console.log(art);
|
||||
}
|
||||
|
||||
window.artplayerPluginDanmu = artplayerPluginDanmu;
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
export default function setting(art) {
|
||||
//
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"presets": [
|
||||
[
|
||||
"@babel/env",
|
||||
{
|
||||
"modules": false
|
||||
}
|
||||
]
|
||||
],
|
||||
"plugins": ["@babel/plugin-external-helpers", "@babel/plugin-transform-runtime"]
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
node_modules
|
||||
.DS_Store
|
||||
yarn.lock
|
||||
package-lock.json
|
||||
test
|
||||
coverage
|
||||
.nyc_output
|
||||
.cache
|
||||
docs
|
||||
@@ -0,0 +1 @@
|
||||
package-lock=false
|
||||
@@ -0,0 +1,51 @@
|
||||
# artplayer-plugin-subtitle
|
||||
|
||||
Subtitle plugin for ArtPlayer
|
||||
|
||||
## Install
|
||||
|
||||
Install with `npm`
|
||||
|
||||
```
|
||||
$ npm install artplayer-plugin-subtitle
|
||||
```
|
||||
|
||||
Or install with `yarn`
|
||||
|
||||
```
|
||||
$ yarn add artplayer-plugin-subtitle
|
||||
```
|
||||
|
||||
```js
|
||||
import artplayerPluginSubtitle from 'artplayer-plugin-subtitle';
|
||||
```
|
||||
|
||||
Or umd builds are also available
|
||||
|
||||
```html
|
||||
<script src="path/to/artplayer-plugin-subtitle.js"></script>
|
||||
```
|
||||
|
||||
Will expose the global variable to `window.artplayerPluginSubtitle`.
|
||||
|
||||
## Usage
|
||||
|
||||
```html
|
||||
<div class="artplayer-app"></div>
|
||||
```
|
||||
|
||||
```js
|
||||
var art = new Artplayer({
|
||||
container: '.artplayer-app',
|
||||
url: 'path/to/video.mp4',
|
||||
plugins: [
|
||||
artplayerPluginSubtitle({
|
||||
time: -1, // Subtitle delay time, ranging from -10 to 10
|
||||
}),
|
||||
],
|
||||
});
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
MIT © [Harvey Zack](https://www.zhw-island.com/)
|
||||
@@ -0,0 +1,50 @@
|
||||
{
|
||||
"name": "artplayer-plugin-subtitle",
|
||||
"version": "1.0.3",
|
||||
"description": "Danmu plugin for ArtPlayer",
|
||||
"main": "dist/artplayer-plugin-subtitle.js",
|
||||
"style": "dist/artplayer-plugin-subtitle.css",
|
||||
"scripts": {
|
||||
"dev": "cross-env NODE_ENV=development rollup -c -m -w",
|
||||
"build": "cross-env NODE_ENV=production rollup -c",
|
||||
"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",
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.1.2",
|
||||
"@babel/plugin-external-helpers": "^7.0.0",
|
||||
"@babel/plugin-transform-runtime": "^7.1.0",
|
||||
"@babel/preset-env": "^7.1.0",
|
||||
"@babel/runtime": "^7.1.2",
|
||||
"autoprefixer": "^9.3.1",
|
||||
"browser-env": "^3.2.5",
|
||||
"cross-env": "^5.2.0",
|
||||
"cssnano": "^4.1.7",
|
||||
"node-sass": "^4.9.4",
|
||||
"rollup": "^0.67.0",
|
||||
"rollup-plugin-babel": "^4.0.3",
|
||||
"rollup-plugin-commonjs": "^9.2.0",
|
||||
"rollup-plugin-eslint": "^5.0.0",
|
||||
"rollup-plugin-node-resolve": "^3.4.0",
|
||||
"rollup-plugin-postcss": "^1.6.2",
|
||||
"rollup-plugin-replace": "^2.1.0",
|
||||
"rollup-plugin-svgo": "^1.0.1",
|
||||
"rollup-plugin-uglify": "^6.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"vtt-adjust": "^1.0.2"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
const path = require('path');
|
||||
const babel = require('rollup-plugin-babel');
|
||||
const commonjs = require('rollup-plugin-commonjs');
|
||||
const nodeResolve = require('rollup-plugin-node-resolve');
|
||||
const postcss = require('rollup-plugin-postcss');
|
||||
const { eslint } = require('rollup-plugin-eslint');
|
||||
const autoprefixer = require('autoprefixer');
|
||||
const cssnano = require('cssnano');
|
||||
const replace = require('rollup-plugin-replace');
|
||||
const svgo = require('rollup-plugin-svgo');
|
||||
const { uglify } = require('rollup-plugin-uglify');
|
||||
const { version, homepage, name } = require('./package.json');
|
||||
|
||||
const isProd = process.env.NODE_ENV === 'production';
|
||||
|
||||
const banner =
|
||||
'/*!\n' +
|
||||
` * ${name}.js v${version}\n` +
|
||||
` * Github: ${homepage}\n` +
|
||||
` * (c) 2017-${new Date().getFullYear()} Harvey Zack\n` +
|
||||
' * Released under the MIT License.\n' +
|
||||
' */\n';
|
||||
|
||||
export default {
|
||||
input: 'src/index.js',
|
||||
output: {
|
||||
name,
|
||||
file: isProd ? `dist/${name}.js` : path.join(process.cwd(), '../../', `docs/lab/js/${name}.js`),
|
||||
format: 'umd',
|
||||
exports: 'named',
|
||||
},
|
||||
plugins: [
|
||||
eslint({
|
||||
exclude: ['node_modules/**', 'src/**/*.scss', 'src/**/*.svg'],
|
||||
}),
|
||||
postcss({
|
||||
plugins: [autoprefixer, cssnano],
|
||||
extract: isProd ? `dist/${name}.css` : path.join(process.cwd(), '../../', `docs/lab/css/${name}.css`),
|
||||
}),
|
||||
nodeResolve(),
|
||||
commonjs(),
|
||||
babel({
|
||||
runtimeHelpers: true,
|
||||
exclude: 'node_modules/**',
|
||||
presets: [['@babel/env', { modules: false }]],
|
||||
plugins: ['@babel/plugin-external-helpers', '@babel/plugin-transform-runtime'],
|
||||
}),
|
||||
svgo({
|
||||
raw: true,
|
||||
}),
|
||||
replace({
|
||||
exclude: 'node_modules/**',
|
||||
__ENV__: JSON.stringify(process.env.NODE_ENV || 'development'),
|
||||
__VERSION__: version,
|
||||
}),
|
||||
isProd &&
|
||||
uglify({
|
||||
output: {
|
||||
preamble: banner,
|
||||
},
|
||||
}),
|
||||
],
|
||||
};
|
||||
@@ -0,0 +1,33 @@
|
||||
function artplayerPluginSubtitle(option) {
|
||||
return art => {
|
||||
const { errorHandle, clamp, sleep } = art.constructor.utils;
|
||||
|
||||
errorHandle(
|
||||
option && typeof option.time === 'number',
|
||||
`The plugin 'artplayerPluginSubtitle': 'option.time' require 'number' type, but got '${typeof option.time}'`,
|
||||
);
|
||||
|
||||
let retry = 0;
|
||||
const maxRetry = 10;
|
||||
const time = clamp(option.time, -10, 10);
|
||||
|
||||
function adjust() {
|
||||
errorHandle(retry < maxRetry, 'It seems that something wrong for reading subtitle');
|
||||
retry += 1;
|
||||
const cues = Array.from(art.refs.$track.track.cues);
|
||||
if (cues.length === 0) {
|
||||
sleep(100).then(adjust);
|
||||
} else {
|
||||
cues.forEach(cue => {
|
||||
cue.startTime += time;
|
||||
cue.endTime += time;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
art.on('subtitle:load', adjust);
|
||||
};
|
||||
}
|
||||
|
||||
window.artplayerPluginSubtitle = artplayerPluginSubtitle;
|
||||
export default artplayerPluginSubtitle;
|
||||
@@ -71,6 +71,7 @@ class Artplayer extends Emitter {
|
||||
quality: [],
|
||||
controls: [],
|
||||
highlight: [],
|
||||
plugins: [],
|
||||
thumbnails: {
|
||||
url: '',
|
||||
number: 60,
|
||||
@@ -90,18 +91,6 @@ class Artplayer extends Emitter {
|
||||
};
|
||||
}
|
||||
|
||||
static use(...args) {
|
||||
const plugin = args[0];
|
||||
const installedPlugins = this.plugins || (this.plugins = []);
|
||||
if (installedPlugins.indexOf === -1) {
|
||||
installedPlugins.push(plugin);
|
||||
args.unshift(this);
|
||||
plugin(...args.slice(1));
|
||||
this.prototype.emit('use', plugin);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
init() {
|
||||
this.isFocus = false;
|
||||
this.isPlaying = false;
|
||||
@@ -136,6 +125,20 @@ class Artplayer extends Emitter {
|
||||
id += 1;
|
||||
this.id = id;
|
||||
Artplayer.instances.push(this);
|
||||
|
||||
this.plugins = [];
|
||||
this.option.plugins.forEach((plugin, index) => {
|
||||
const resule = plugin(this);
|
||||
let pluginName = '';
|
||||
if (resule && resule.name) {
|
||||
pluginName = resule.name;
|
||||
} else if (plugin.name) {
|
||||
pluginName = plugin.name;
|
||||
} else {
|
||||
pluginName = `plugin${index}`;
|
||||
}
|
||||
this.plugins[pluginName] = resule;
|
||||
});
|
||||
}
|
||||
|
||||
destroy(removeHtml = false) {
|
||||
|
||||
@@ -32,6 +32,12 @@ export default {
|
||||
mutex: 'boolean',
|
||||
fullscreen: 'boolean',
|
||||
fullscreenWeb: 'boolean',
|
||||
plugins: {
|
||||
type: 'array',
|
||||
child: {
|
||||
type: 'function',
|
||||
},
|
||||
},
|
||||
layers: {
|
||||
type: 'array',
|
||||
child: {
|
||||
|
||||
@@ -26,8 +26,4 @@
|
||||
fill: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
.art-hide {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,6 @@ export default class Subtitle {
|
||||
constructor(art) {
|
||||
this.art = art;
|
||||
this.state = true;
|
||||
this.vttText = '';
|
||||
const { url } = this.art.option.subtitle;
|
||||
if (url) {
|
||||
this.init();
|
||||
@@ -22,10 +21,11 @@ export default class Subtitle {
|
||||
const $track = document.createElement('track');
|
||||
$track.default = true;
|
||||
$track.kind = 'metadata';
|
||||
this.load(subtitle.url).then(data => {
|
||||
$track.src = data;
|
||||
$video.appendChild($track);
|
||||
this.art.refs.$track = $track;
|
||||
$video.appendChild($track);
|
||||
this.art.refs.$track = $track;
|
||||
this.load(subtitle.url).then(vttText => {
|
||||
$track.src = vttToBlob(vttText);
|
||||
this.art.emit('subtitle:load', vttText);
|
||||
if ($video.textTracks && $video.textTracks[0]) {
|
||||
const [track] = $video.textTracks;
|
||||
proxy(track, 'cuechange', () => {
|
||||
@@ -54,12 +54,13 @@ export default class Subtitle {
|
||||
return response.text();
|
||||
})
|
||||
.then(text => {
|
||||
let vttText = '';
|
||||
if (/x-subrip/gi.test(type)) {
|
||||
this.vttText = srtToVtt(text);
|
||||
vttText = srtToVtt(text);
|
||||
} else {
|
||||
this.vttText = text;
|
||||
vttText = text;
|
||||
}
|
||||
return vttToBlob(this.vttText);
|
||||
return vttText;
|
||||
})
|
||||
.catch(err => {
|
||||
notice.show(err);
|
||||
@@ -103,8 +104,9 @@ export default class Subtitle {
|
||||
switch(url) {
|
||||
const { $track } = this.art.refs;
|
||||
errorHandle($track, 'You need to initialize the subtitle option first.');
|
||||
this.load(url).then(data => {
|
||||
$track.src = data;
|
||||
this.load(url).then(vttText => {
|
||||
$track.src = vttToBlob(vttText);
|
||||
this.art.emit('subtitle:load', vttText);
|
||||
this.art.emit('subtitle:switch', url);
|
||||
});
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user