This commit is contained in:
Harvey Zack committed 2018-10-22 10:54:19 +08:00
1 parent 1d1bf15f0d
commit 8b6258c4e5
11 files changed
+331 -169

No files matched your search

+72 -34
View File
@@ -3,13 +3,8 @@ import { errorHandle, getExt, setStyle } from './utils';
export default class Subtitle {
constructor(art) {
this.art = art;
if (this.art.option.subtitle) {
errorHandle(
getExt(this.art.option.subtitle.url) === 'vtt',
`'url' option require 'vtt' format, but got '${getExt(this.art.option.subtitle.url)}'.`
);
this.init();
}
this.checkExt(this.art.option.subtitle.url);
this.init();
}
init() {
@@ -23,26 +18,71 @@ export default class Subtitle {
const $track = document.createElement('track');
$track.default = true;
$track.kind = 'metadata';
$track.src = subtitle.url;
$video.appendChild($track);
this.art.refs.$track = $track;
if ($video.textTracks && $video.textTracks[0]) {
const [track] = $video.textTracks;
proxy(track, 'cuechange', () => {
const [cue] = track.activeCues;
$subtitle.innerHTML = '';
if (cue) {
const template = document.createElement('div');
template.appendChild(cue.getCueAsHTML());
$subtitle.innerHTML = template.innerHTML
.split(/\r?\n/)
.map(item => `<p>${item}</p>`)
.join('');
this.load(subtitle.url).then(data => {
$track.src = data;
$video.appendChild($track);
this.art.refs.$track = $track;
if ($video.textTracks && $video.textTracks[0]) {
const [track] = $video.textTracks;
proxy(track, 'cuechange', () => {
const [cue] = track.activeCues;
$subtitle.innerHTML = '';
if (cue) {
const template = document.createElement('div');
template.appendChild(cue.getCueAsHTML());
$subtitle.innerHTML = template.innerHTML
.split(/\r?\n/)
.map(item => `<p>${item}</p>`)
.join('');
}
this.art.emit('subtitle:update', $subtitle);
});
}
});
}
load(url) {
let type;
return fetch(url)
.then(response => {
type = response.headers.get('Content-Type');
return response.text();
})
.then(text => {
if ((/x-subrip/gi).test(type)) {
return this.srtToVtt(text);
}
this.art.emit('subtitle:update', $subtitle);
return url;
})
.catch(err => {
throw err;
});
}
}
srtToVtt(text) {
const vttText = 'WEBVTT \r\n\r\n'.concat(
text
.replace(/\{\\([ibu])\}/g, '</$1>')
.replace(/\{\\([ibu])1\}/g, '<$1>')
.replace(/\{([ibu])\}/g, '<$1>')
.replace(/\{\/([ibu])\}/g, '</$1>')
.replace(/(\d\d:\d\d:\d\d),(\d\d\d)/g, '$1.$2')
.concat('\r\n\r\n')
);
return URL.createObjectURL(
new Blob([vttText], {
type: 'text/vtt'
})
);
}
checkExt(url) {
const ext = getExt(url);
errorHandle(
ext === 'vtt' || ext === 'srt',
`'url' option require 'vtt' or 'srt' format, but got '${ext}'.`
);
}
show() {
@@ -59,15 +99,13 @@ export default class Subtitle {
switch(url) {
const { $track } = this.art.refs;
errorHandle(
getExt(url) === 'vtt',
`'url' option require 'vtt' format, but got '${getExt(url)}'.`
);
errorHandle(
$track,
'You need to initialize the subtitle option first.'
);
$track.src = url;
this.art.emit('subtitle:switch', url);
this.checkExt(url);
errorHandle($track, 'You need to initialize the subtitle option first.');
this.load(url).then(data => {
if (url !== data) {
$track.src = data;
this.art.emit('subtitle:switch', url);
}
});
}
}