mirror of
https://github.com/zhw2590582/ArtPlayer.git
synced 2026-10-27 17:51:20 -08:00
Add unescape utility function and
artplayerPluginMultipleSubtitles plugin
This commit is contained in:
1 parent
3db53c425e
commit
89b8525f2f
47 files changed
+2982
-75
No files matched your search
@@ -0,0 +1,10 @@
|
||||
node_modules
|
||||
.DS_Store
|
||||
yarn.lock
|
||||
package-lock.json
|
||||
test
|
||||
coverage
|
||||
.nyc_output
|
||||
.parcel-cache
|
||||
.cache
|
||||
docs
|
||||
@@ -0,0 +1 @@
|
||||
package-lock=false
|
||||
@@ -0,0 +1,11 @@
|
||||
# artplayer-plugin-multiple-subtitles
|
||||
|
||||
multiple subtitles plugin for ArtPlayer
|
||||
|
||||
## Demo
|
||||
|
||||
[https://artplayer.org](https://artplayer.org/?libs=./uncompiled/artplayer-plugin-multiple-subtitles/index.js&example=multiple.subtitles)
|
||||
|
||||
## License
|
||||
|
||||
MIT © Harvey Zack
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
/*!
|
||||
* artplayer-plugin-multiple-subtitles.js v1.0.0
|
||||
* Github: https://github.com/zhw2590582/ArtPlayer
|
||||
* (c) 2017-2023 Harvey Zack
|
||||
* Released under the MIT License.
|
||||
*/
|
||||
!// modules are defined as an array
|
||||
// [ module function, map of requires ]
|
||||
//
|
||||
// map of requires is short require name -> numeric require
|
||||
//
|
||||
// anything defined in a previous bundle is accessed via the
|
||||
// orig method which is the require for previous bundles
|
||||
function(e,t,n,i,r){/* eslint-disable no-undef */var a="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:"undefined"!=typeof window?window:"undefined"!=typeof global?global:{},o="function"==typeof a[i]&&a[i],s=o.cache||{},l="undefined"!=typeof module&&"function"==typeof module.require&&module.require.bind(module);function u(t,n){if(!s[t]){if(!e[t]){// if we cannot find the module within our internal map or
|
||||
// cache jump to the current global require ie. the last bundle
|
||||
// that was added to the page.
|
||||
var r="function"==typeof a[i]&&a[i];if(!n&&r)return r(t,!0);// If there are other bundles on this page the require from the
|
||||
// previous one is saved to 'previousRequire'. Repeat this as
|
||||
// many times as there are bundles until the module is found or
|
||||
// we exhaust the require chain.
|
||||
if(o)return o(t,!0);// Try the node require function if it exists.
|
||||
if(l&&"string"==typeof t)return l(t);var f=Error("Cannot find module '"+t+"'");throw f.code="MODULE_NOT_FOUND",f}d.resolve=function(n){var i=e[t][1][n];return null!=i?i:n},d.cache={};var c=s[t]=new u.Module(t);e[t][0].call(c.exports,d,c,c.exports,this)}return s[t].exports;function d(e){var t=d.resolve(e);return!1===t?{}:u(t)}}u.isParcelRequire=!0,u.Module=function(e){this.id=e,this.bundle=u,this.exports={}},u.modules=e,u.cache=s,u.parent=o,u.register=function(t,n){e[t]=[function(e,t){t.exports=n},{}]},Object.defineProperty(u,"root",{get:function(){return a[i]}}),a[i]=u;for(var f=0;f<t.length;f++)u(t[f]);if(n){// Expose entry point to Node, AMD or browser globals
|
||||
// Based on https://github.com/ForbesLindesay/umd/blob/master/template.js
|
||||
var c=u(n);// CommonJS
|
||||
"object"==typeof exports&&"undefined"!=typeof module?module.exports=c:"function"==typeof define&&define.amd?define(function(){return c}):r&&(this[r]=c)}}({"4Kbf6":[function(e,t,n){var i=e("@parcel/transformer-js/src/esmodule-helpers.js");i.defineInteropFlag(n),i.export(n,"default",()=>s);var r=e("./parser");function a(e){let t={"&":"&","<":"<",">":">","'":"'",""":'"'},n=RegExp(`(${Object.keys(t).join("|")})`,"g");return e.replace(n,e=>t[e]||e)}async function o(e){let{getExt:t,srtToVtt:n,assToVtt:i}=Artplayer.utils,r=await fetch(e.url),a=await r.arrayBuffer(),o=new TextDecoder(e.encoding||"utf-8"),s=o.decode(a);switch(e.type||t(e.url)){case"srt":return n(s);case"ass":return i(s);case"vtt":return s;default:return""}}function s({subtitles:e}){return async t=>{let n=await Promise.all(e.map(o)),i=function(e,t){let n=new r.WebVTTParser,i=new r.WebVTTSerializer,a=n.parse("","metadata");for(let i=0;i<e.length;i++){let r=t[i],o=n.parse(e[i],"metadata");for(let e=0;e<o.cues.length;e++){let t=o.cues[e];for(let e=0;e<t.tree.children.length;e++){let n=t.tree.children[e];n.value=`<div class="art-subtitle-${r.name}">${n.value}</div>`}}if(0===a.cues.length)a.cues=o.cues;else for(let e=0;e<a.cues.length;e++)a.cues[e].tree.children.push(...o.cues[e]?.tree?.children||[])}return i.serialize(a.cues)}(n,e),s=URL.createObjectURL(new Blob([i],{type:"text/vtt"}));t.option.subtitle.escape=!1,t.subtitle.init({...t.option.subtitle,url:s,type:"vtt",onVttLoad:a})}}s.env="production",s.version="1.0.0",s.build="2023-11-23 23:22:06","undefined"!=typeof window&&(window.artplayerPluginMultipleSubtitles=s)},{"./parser":"cU78l","@parcel/transformer-js/src/esmodule-helpers.js":"9pCYc"}],cU78l:[function(e,t,n){!// Any copyright is dedicated to the Public Domain.
|
||||
// http://creativecommons.org/publicdomain/zero/1.0/
|
||||
// Not intended to be fast, but if you can make it faster, please help out!
|
||||
function(){var e={direction:"horizontal",snapToLines:!0,linePosition:"auto",lineAlign:"start",textPosition:"auto",positionAlign:"auto",size:100,alignment:"center"},t=function(t){t||(t={"&":"&","<":"<",">":">","&lrm":"","&rlm":""," ":"\xa0"}),this.entities=t,this.parse=function(n,a){// global search and replace for \0
|
||||
n=n.replace(/\0/g,"�");var o=Date.now(),s=0,l=n.split(/\r\n|\r|\n/),u=!1,f=[],c=[],d=[];function p(e,t){d.push({message:e,line:s+1,col:t})}var m=l[s],g=m.length,h="WEBVTT",v=0,b=h.length;/* HEADER */for("\uFEFF"===m[0]&&(v=1,b+=1),(g<b||m.indexOf(h)!==0+v||g>b&&" "!==m[b]&&" "!==m[b])&&p('No valid signature. (File needs to start with "WEBVTT".)'),s++;""!=l[s]&&void 0!=l[s];){if(p("No blank line after the signature."),-1!=l[s].indexOf("-->")){u=!0;break}s++}/* CUE LOOP */for(;void 0!=l[s];){for(;!u&&""==l[s];)s++;if(!u&&void 0==l[s])break;/* CUE CREATION */T=Object.assign({},e,{id:"",startTime:0,endTime:0,pauseOnExit:!1,direction:"horizontal",snapToLines:!0,linePosition:"auto",lineAlign:"start",textPosition:"auto",positionAlign:"auto",size:100,alignment:"center",text:"",tree:null});var T,x=!0;if(-1==l[s].indexOf("-->")){/* COMMENTS
|
||||
Not part of the specification's parser as these would just be ignored. However,
|
||||
we want them to be conforming and not get "Cue identifier cannot be standalone".
|
||||
*/if(T.id=l[s],/^NOTE($|[ \t])/.test(T.id)){for(s++;""!=l[s]&&void 0!=l[s];)-1!=l[s].indexOf("-->")&&p("Cannot have timestamp in a comment."),s++;continue}/* STYLES */if(/^STYLE($|[ \t])/.test(T.id)){var y=[],w=!1;for(s++;""!=l[s]&&void 0!=l[s];)-1!=l[s].indexOf("-->")&&(p("Cannot have timestamp in a style block."),w=!0),y.push(l[s]),s++;if(c.length){p("Style blocks cannot appear after the first cue.");continue}w||f.push(y.join("\n"));continue}if(""==l[++s]||void 0==l[s]){p("Cue identifier cannot be standalone.");continue}if(-1==l[s].indexOf("-->")){x=!1,p("Cue identifier needs to be followed by timestamp.");continue}}/* TIMINGS */u=!1;var O=new i(l[s],p),P=0;if(c.length>0&&(P=c[c.length-1].startTime),x&&!O.parse(T,P)){/* BAD CUE LOOP */for(/* BAD CUE */T=null,s++;""!=l[s]&&void 0!=l[s];){if(-1!=l[s].indexOf("-->")){u=!0;break}s++}continue}/* CUE TEXT LOOP */for(s++;""!=l[s]&&void 0!=l[s];){if(-1!=l[s].indexOf("-->")){p("Blank line missing before cue."),u=!0;break}""!=T.text&&(T.text+="\n"),T.text+=l[s],s++}/* CUE TEXT PROCESSING */var j=new r(T.text,p,a,t);T.tree=j.parse(T.startTime,T.endTime),c.push(T)}/* END */return c.sort(function(e,t){return e.startTime<t.startTime?-1:e.startTime>t.startTime?1:e.endTime>t.endTime?-1:e.endTime<t.endTime?1:0}),{cues:c,errors:d,time:Date.now()-o,styles:f}}},i=function(e,t){var n=/[\u0020\t\f]/,i=/[^\u0020\t\f]/,e=e,r=0,a=function(e){t(e,r+1)};function o(t){for(;void 0!=e[r]&&t.test(e[r]);)r++}function s(t){for(var n="";void 0!=e[r]&&t.test(e[r]);)n+=e[r],r++;return n}/* http://dev.w3.org/html5/webvtt/#collect-a-webvtt-timestamp */function l(){var t,n,i,o,l="minutes";// 3
|
||||
if(void 0==e[r]){a("No timestamp found.");return}// 4
|
||||
if(!/\d/.test(e[r])){a("Timestamp must start with a character in the range 0-9.");return}// 8
|
||||
if((// 5-7
|
||||
(t=s(/\d/)).length>2||parseInt(t,10)>59)&&(l="hours"),":"!=e[r]){a("No time unit separator found.");return}if(r++,2!=// 9-11
|
||||
(n=s(/\d/)).length){a("Must be exactly two digits.");return}// 12
|
||||
if("hours"==l||":"==e[r]){if(":"!=e[r]){a("No seconds found or minutes is greater than 59.");return}if(r++,2!=(i=s(/\d/)).length){a("Must be exactly two digits.");return}}else{if(2!=t.length){a("Must be exactly two digits.");return}i=n,n=t,t="0"}// 13
|
||||
if("."!=e[r]){a('No decimal separator (".") found.');return}if(r++,3!=// 14-16
|
||||
(o=s(/\d/)).length){a("Milliseconds must be given in three digits.");return}// 17
|
||||
if(parseInt(n,10)>59){a("You cannot have more than 59 minutes.");return}if(parseInt(i,10)>59){a("You cannot have more than 59 seconds.");return}return 3600*parseInt(t,10)+60*parseInt(n,10)+parseInt(i,10)+parseInt(o,10)/1e3}this.parse=function(t,s){if(o(n),t.startTime=l(),void 0!=t.startTime){// 6-8
|
||||
if(t.startTime<s&&a("Start timestamp is not greater than or equal to start timestamp of previous cue."),i.test(e[r])&&a("Timestamp not separated from '-->' by whitespace."),o(n),"-"!=e[r]||"-"!=e[++r]||">"!=e[++r]){a("No valid timestamp separator found.");return}if(r++,i.test(e[r])&&a("'-->' not separated from timestamp by whitespace."),o(n),t.endTime=l(),void 0!=t.endTime)return t.endTime<=t.startTime&&a("End timestamp is not greater than start timestamp."),i.test(e[r]),o(n),/* http://dev.w3.org/html5/webvtt/#parse-the-webvtt-settings */function(e,t){for(var i=e.split(n),r=[],o=0;o<i.length;o++)if(""!=i[o]){var s=i[o].indexOf(":"),l=i[o].slice(0,s),u=i[o].slice(s+1);if(-1!=r.indexOf(l)&&a("Duplicate setting."),r.push(l),""==u){a("No value for setting defined.");return}if("vertical"==l){if("rl"!=u&&"lr"!=u){a("Writing direction can only be set to 'rl' or 'rl'.");continue}t.direction=u}else if("line"==l){if(/,/.test(u)){var f=u.split(",");u=f[0];var c=f[1]}if(!/^[-\d](\d*)(\.\d+)?%?$/.test(u)){a("Line position takes a number or percentage.");continue}if(-1!=u.indexOf("-",1)){a("Line position can only have '-' at the start.");continue}if(-1!=u.indexOf("%")&&u.indexOf("%")!=u.length-1){a("Line position can only have '%' at the end.");continue}if("-"==u[0]&&"%"==u[u.length-1]){a("Line position cannot be a negative percentage.");continue}var d=u,p=!1;if("%"==u[u.length-1]&&(p=!0,d=u.slice(0,u.length-1),parseInt(u,10)>100)){a("Line position cannot be >100%.");continue}if(""===d||isNaN(d)||!isFinite(d)){a("Line position needs to be a number");continue}if(void 0!==c){if(!["start","center","end"].includes(c)){a("Line alignment needs to be one of start, center or end");continue}t.lineAlign=c}t.snapToLines=!p,t.linePosition=parseFloat(d),parseFloat(d).toString()!==d&&(t.nonSerializable=!0)}else if("position"==l){if(/,/.test(u)){var f=u.split(",");u=f[0];var m=f[1]}if("%"!=u[u.length-1]){a("Text position must be a percentage.");continue}if(parseInt(u,10)>100||0>parseInt(u,10)){a("Text position needs to be between 0 and 100%.");continue}if(""===(d=u.slice(0,u.length-1))||isNaN(d)||!isFinite(d)){a("Line position needs to be a number");continue}if(void 0!==m){if(!["line-left","center","line-right"].includes(m)){a("Position alignment needs to be one of line-left, center or line-right");continue}t.positionAlign=m}t.textPosition=parseFloat(d)}else if("size"==l){if("%"!=u[u.length-1]){a("Size must be a percentage.");continue}if(parseInt(u,10)>100){a("Size cannot be >100%.");continue}var g=u.slice(0,u.length-1);if(void 0===g||""===g||isNaN(g)){a("Size needs to be a number"),g=100;continue}if((g=parseFloat(g))<0||g>100){a("Size needs to be between 0 and 100%.");continue}t.size=g}else if("align"==l){var h=["start","center","end","left","right"];if(-1==h.indexOf(u)){a("Alignment can only be set to one of "+h.join(", ")+".");continue}t.alignment=u}else a("Invalid setting.")}}(e.substring(r),t),!0}},this.parseTimestamp=function(){var t=l();if(void 0!=e[r]){a("Timestamp must not have trailing characters.");return}return t}},r=function(e,t,n,r){this.entities=r;var a=this,e=e,o=0,s=function(e){"metadata"!=n&&t(e,o+1)};this.parse=function(t,l){var u={children:[]},f=u,c=[];function d(e){f.children.push({type:"object",name:e[1],classes:e[2],children:[],parent:f}),f=f.children[f.children.length-1]}for(;void 0!=e[o];){var p=function(){for(var t="data",n="",i="",l=[];void 0!=e[o-1]||0==o;){var u=e[o];if("data"==t){if("&"==u)i=u,t="escape";else if("<"==u&&""==n)t="tag";else{if("<"==u||void 0==u)return["text",n];n+=u}}else if("escape"==t){if("<"==u||void 0==u){let e;return s("Incorrect escape."),(e=i.match(/^&#([0-9]+)$/))?n+=String.fromCharCode(e[1]):a.entities[i]?n+=a.entities[i]:n+=i,["text",n]}if("&"==u)s("Incorrect escape."),n+=i,i=u;else if(/[a-z#0-9]/i.test(u))i+=u;else if(";"==u){let e;(e=i.match(/^&#(x?[0-9]+)$/))?n+=String.fromCharCode("0"+e[1]):a.entities[i+u]?n+=a.entities[i+u]:(e=Object.keys(r).find(e=>i.startsWith(e)))?n+=a.entities[e]+i.slice(e.length)+u:(s("Incorrect escape."),n+=i+";"),t="data"}else s("Incorrect escape."),n+=i+u,t="data"}else if("tag"==t){if(" "==u||"\n"==u||"\f"==u||" "==u)t="start tag annotation";else if("."==u)t="start tag class";else if("/"==u)t="end tag";else if(/\d/.test(u))n=u,t="timestamp tag";else{if(">"==u||void 0==u)return">"==u&&o++,["start tag","",[],""];n=u,t="start tag"}}else if("start tag"==t){if(" "==u||"\f"==u||" "==u)t="start tag annotation";else if("\n"==u)i=u,t="start tag annotation";else if("."==u)t="start tag class";else{if(">"==u||void 0==u)return">"==u&&o++,["start tag",n,[],""];n+=u}}else if("start tag class"==t){if(" "==u||"\f"==u||" "==u)i&&l.push(i),i="",t="start tag annotation";else if("\n"==u)i&&l.push(i),i=u,t="start tag annotation";else if("."==u)i&&l.push(i),i="";else{if(">"==u||void 0==u)return">"==u&&o++,i&&l.push(i),["start tag",n,l,""];i+=u}}else if("start tag annotation"==t){if(">"==u||void 0==u)return">"==u&&o++,["start tag",n,l,i=i.split(/[\u0020\t\f\r\n]+/).filter(fuLine truncated
|
||||
;// 8
|
||||
o++}}();if("text"==p[0])f.children.push({type:"text",value:p[1],parent:f});else if("start tag"==p[0]){"chapters"==n&&s("Start tags not allowed in chapter title text.");var m=p[1];"v"!=m&&"lang"!=m&&""!=p[3]&&s("Only <v> and <lang> can have an annotation."),"c"==m||"i"==m||"b"==m||"u"==m||"ruby"==m?d(p):"rt"==m&&"ruby"==f.name?d(p):"v"==m?(function(e){for(var t=f;t;){if("v"==t.name)return!0;t=t.parent}}(0)&&s("<v> cannot be nested inside itself."),d(p),f.value=p[3]// annotation
|
||||
,p[3]||s("<v> requires an annotation.")):"lang"==m?(d(p),f.value=p[3]// language
|
||||
):s("Incorrect start tag.")}else if("end tag"==p[0])"chapters"==n&&s("End tags not allowed in chapter title text."),p[1]==f.name?f=f.parent:"ruby"==p[1]&&"rt"==f.name?f=f.parent.parent:s("Incorrect end tag.");else if("timestamp"==p[0]){"chapters"==n&&s("Timestamp not allowed in chapter title text.");var g=new i(p[1],s).parseTimestamp();void 0!=g&&((g<=t||g>=l)&&s("Timestamp must be between start timestamp and end timestamp."),c.length>0&&c[c.length-1]>=g&&s("Timestamp must be greater than any previous timestamp."),f.children.push({type:"timestamp",value:g,parent:f}),c.push(g))}}for(;f.parent;)"v"!=f.name&&s("Required end tag missing."),f=f.parent;return function e(t){let n={...t};return t.children&&(n.children=t.children.map(e)),n.parent&&delete n.parent,n}(u)}},a=function(){function t(e){let t=("00"+1e3*(e-Math.floor(e)).toFixed(3)).slice(-3),n=0,i=0,r=0;return e>=3600&&(n=Math.floor(e/3600)),i=Math.floor((e-3600*n)/60),r=Math.floor(e-3600*n-60*i),(n?n+":":"")+(""+i).padStart(2,"0")+":"+(""+r).padStart(2,"0")+"."+t}this.serialize=function(n,i){var r,a="WEBVTT\n\n";if(i)for(var o=0;o<i.length;o++)a+="STYLE\n"+i[o]+"\n\n";for(var o=0;o<n.length;o++)a+=(void 0!==(r=n[o]).id?r.id+"\n":"")+t(r.startTime)+" --> "+t(r.endTime)+function(t){var n="";let i=Object.keys(e).filter(n=>t[n]!==e[n]);return i.includes("direction")&&(n+=" vertical:"+t.direction),i.includes("alignment")&&(n+=" align:"+t.alignment),i.includes("size")&&(n+=" size:"+t.size+"%"),(i.includes("lineAlign")||i.includes("linePosition"))&&(n+=" line:"+t.linePosition+(t.snapToLines?"":"%")+(t.lineAlign&&t.lineAlign!=e.lineAlign?","+t.lineAlign:"")),(i.includes("textPosition")||i.includes("positionAlign"))&&(n+=" position:"+t.textPosition+"%"+(t.positionAlign&&t.positionAlign!==e.positionAlign?","+t.positionAlign:"")),n}(r)+"\n"+function e(n){for(var i="",r=0;r<n.length;r++){var a=n[r];if("text"==a.type)i+=a.value.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">");else if("object"==a.type){if(i+="<"+a.name,a.classes)for(var o=0;o<a.classes.length;o++)i+="."+a.classes[o];a.value&&(i+=" "+a.value),i+=">",a.children&&(i+=e(a.children)),i+="</"+a.name+">"}else"timestamp"==a.type?i+="<"+t(a.value)+">":i+="<"+a.value+">"}return i}(r.tree.children)+"\n\n";return a}};function o(e){e.WebVTTParser=t,e.WebVTTCueTimingsAndSettingsParser=i,e.WebVTTCueTextParser=r,e.WebVTTSerializer=a}"undefined"!=typeof window&&o(window),o(n)}()},{}],"9pCYc":[function(e,t,n){n.interopDefault=function(e){return e&&e.__esModule?e:{default:e}},n.defineInteropFlag=function(e){Object.defineProperty(e,"__esModule",{value:!0})},n.exportAll=function(e,t){return Object.keys(e).forEach(function(n){"default"===n||"__esModule"===n||t.hasOwnProperty(n)||Object.defineProperty(t,n,{enumerable:!0,get:function(){return e[n]}})}),t},n.export=function(e,t,n){Object.defineProperty(e,t,{enumerable:!0,get:n})}},{}]},["4Kbf6"],"4Kbf6","parcelRequire4dc0");
|
||||
Vendored
+59
@@ -0,0 +1,59 @@
|
||||
/*!
|
||||
* artplayer-plugin-multiple-subtitles.js v1.0.0
|
||||
* Github: https://github.com/zhw2590582/ArtPlayer
|
||||
* (c) 2017-2023 Harvey Zack
|
||||
* Released under the MIT License.
|
||||
*/
|
||||
!// modules are defined as an array
|
||||
// [ module function, map of requires ]
|
||||
//
|
||||
// map of requires is short require name -> numeric require
|
||||
//
|
||||
// anything defined in a previous bundle is accessed via the
|
||||
// orig method which is the require for previous bundles
|
||||
function(e,t,r,n,o){/* eslint-disable no-undef */var i="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:"undefined"!=typeof window?window:"undefined"!=typeof global?global:{},a="function"==typeof i[n]&&i[n],s=a.cache||{},u="undefined"!=typeof module&&"function"==typeof module.require&&module.require.bind(module);function c(t,r){if(!s[t]){if(!e[t]){// if we cannot find the module within our internal map or
|
||||
// cache jump to the current global require ie. the last bundle
|
||||
// that was added to the page.
|
||||
var o="function"==typeof i[n]&&i[n];if(!r&&o)return o(t,!0);// If there are other bundles on this page the require from the
|
||||
// previous one is saved to 'previousRequire'. Repeat this as
|
||||
// many times as there are bundles until the module is found or
|
||||
// we exhaust the require chain.
|
||||
if(a)return a(t,!0);// Try the node require function if it exists.
|
||||
if(u&&"string"==typeof t)return u(t);var l=Error("Cannot find module '"+t+"'");throw l.code="MODULE_NOT_FOUND",l}p.resolve=function(r){var n=e[t][1][r];return null!=n?n:r},p.cache={};var f=s[t]=new c.Module(t);e[t][0].call(f.exports,p,f,f.exports,this)}return s[t].exports;function p(e){var t=p.resolve(e);return!1===t?{}:c(t)}}c.isParcelRequire=!0,c.Module=function(e){this.id=e,this.bundle=c,this.exports={}},c.modules=e,c.cache=s,c.parent=a,c.register=function(t,r){e[t]=[function(e,t){t.exports=r},{}]},Object.defineProperty(c,"root",{get:function(){return i[n]}}),i[n]=c;for(var l=0;l<t.length;l++)c(t[l]);if(r){// Expose entry point to Node, AMD or browser globals
|
||||
// Based on https://github.com/ForbesLindesay/umd/blob/master/template.js
|
||||
var f=c(r);// CommonJS
|
||||
"object"==typeof exports&&"undefined"!=typeof module?module.exports=f:"function"==typeof define&&define.amd?define(function(){return f}):o&&(this[o]=f)}}({"2hz0c":[function(e,t,r){var n=e("@parcel/transformer-js/src/esmodule-helpers.js");n.defineInteropFlag(r),n.export(r,"default",function(){return d});var o=e("@swc/helpers/_/_async_to_generator"),i=e("@swc/helpers/_/_object_spread"),a=e("@swc/helpers/_/_object_spread_props"),s=e("@swc/helpers/_/_to_consumable_array"),u=e("@swc/helpers/_/_ts_generator"),c=e("./parser");function l(e){var t={"&":"&","<":"<",">":">","'":"'",""":'"'},r=RegExp("(".concat(Object.keys(t).join("|"),")"),"g");return e.replace(r,function(e){return t[e]||e})}function f(e){return p.apply(this,arguments)}function p(){return(p=(0,o._)(function(e){var t,r,n,o,i,a;return(0,u._)(this,function(s){switch(s.label){case 0:return r=(t=Artplayer.utils).getExt,n=t.srtToVtt,o=t.assToVtt,[4,fetch(e.url)];case 1:return[4,s.sent().arrayBuffer()];case 2:switch(i=s.sent(),a=new TextDecoder(e.encoding||"utf-8").decode(i),e.type||r(e.url)){case"srt":return[2,n(a)];case"ass":return[2,o(a)];case"vtt":return[2,a];default:return[2,""]}return[2]}})})).apply(this,arguments)}function d(e){var t,r=e.subtitles;return t=(0,o._)(function(e){var t,n;return(0,u._)(this,function(o){switch(o.label){case 0:return[4,Promise.all(r.map(f))];case 1:return t=function(e,t){for(var r=new c.WebVTTParser,n=new c.WebVTTSerializer,o=r.parse("","metadata"),i=0;i<e.length;i++){for(var a,u,l,f=t[i],p=r.parse(e[i],"metadata"),d=0;d<p.cues.length;d++)for(var _=p.cues[d],h=0;h<_.tree.children.length;h++){var m=_.tree.children[h];m.value='<div class="art-subtitle-'.concat(f.name,'">').concat(m.value,"</div>")}if(0===o.cues.length)o.cues=p.cues;else for(var y=0;y<o.cues.length;y++)(a=o.cues[y].tree.children).push.apply(a,(0,s._)((null===(l=p.cues[y])||void 0===l?void 0:null===(u=l.tree)||void 0===u?void 0:u.children)||[]))}return n.serialize(o.cues)}(o.sent(),r),n=URL.createObjectURL(new Blob([t],{type:"text/vtt"})),e.option.subtitle.escape=!1,e.subtitle.init((0,a._)((0,i._)({},e.option.subtitle),{url:n,type:"vtt",onVttLoad:l})),[2]}})}),function(e){return t.apply(this,arguments)}}d.env="production",d.version="1.0.0",d.build="2023-11-23 23:22:07","undefined"!=typeof window&&(window.artplayerPluginMultipleSubtitles=d)},{"@swc/helpers/_/_async_to_generator":"eONSn","@swc/helpers/_/_object_spread":"9agdF","@swc/helpers/_/_object_spread_props":"gJNH2","@swc/helpers/_/_to_consumable_array":"iwLF0","@swc/helpers/_/_ts_generator":"6Xyd0","./parser":"8YYw5","@parcel/transformer-js/src/esmodule-helpers.js":"iWrD0"}],eONSn:[function(e,t,r){var n=e("@parcel/transformer-js/src/esmodule-helpers.js");function o(e,t,r,n,o,i,a){try{var s=e[i](a),u=s.value}catch(e){r(e);return}s.done?t(u):Promise.resolve(u).then(n,o)}function i(e){return function(){var t=this,r=arguments;return new Promise(function(n,i){var a=e.apply(t,r);function s(e){o(a,n,i,s,u,"next",e)}function u(e){o(a,n,i,s,u,"throw",e)}s(void 0)})}}n.defineInteropFlag(r),n.export(r,"_async_to_generator",function(){return i}),n.export(r,"_",function(){return i})},{"@parcel/transformer-js/src/esmodule-helpers.js":"iWrD0"}],iWrD0:[function(e,t,r){r.interopDefault=function(e){return e&&e.__esModule?e:{default:e}},r.defineInteropFlag=function(e){Object.defineProperty(e,"__esModule",{value:!0})},r.exportAll=function(e,t){return Object.keys(e).forEach(function(r){"default"===r||"__esModule"===r||t.hasOwnProperty(r)||Object.defineProperty(t,r,{enumerable:!0,get:function(){return e[r]}})}),t},r.export=function(e,t,r){Object.defineProperty(e,t,{enumerable:!0,get:r})}},{}],"9agdF":[function(e,t,r){var n=e("@parcel/transformer-js/src/esmodule-helpers.js");n.defineInteropFlag(r),n.export(r,"_object_spread",function(){return i}),n.export(r,"_",function(){return i});var o=e("./_define_property.js");function i(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{},n=Object.keys(r);"function"==typeof Object.getOwnPropertySymbols&&(n=n.concat(Object.getOwnPropertySymbols(r).filter(function(e){return Object.getOwnPropertyDescriptor(r,e).enumerable}))),n.forEach(function(t){(0,o._define_property)(e,t,r[t])})}return e}},{"./_define_property.js":"3NGsL","@parcel/transformer-js/src/esmodule-helpers.js":"iWrD0"}],"3NGsL":[function(e,t,r){var n=e("@parcel/transformer-js/src/esmodule-helpers.js");function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}n.defineInteropFlag(r),n.export(r,"_define_property",function(){return o}),n.export(r,"_",function(){return o})},{"@parcel/transformer-js/src/esmodule-helpers.js":"iWrD0"}],gJNH2:[function(e,t,r){var n=e("@parcel/transformer-js/src/esmodule-helpers.js");function o(e,t){return t=null!=t?t:{},Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):(function(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOLine truncated
|
||||
Copyright (c) Microsoft Corporation.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
PERFORMANCE OF THIS SOFTWARE.
|
||||
***************************************************************************** *//* global Reflect, Promise, SuppressedError, Symbol */var n=e("@parcel/transformer-js/src/esmodule-helpers.js");n.defineInteropFlag(r),n.export(r,"__extends",function(){return a}),n.export(r,"__assign",function(){return s}),n.export(r,"__rest",function(){return u}),n.export(r,"__decorate",function(){return c}),n.export(r,"__param",function(){return l}),n.export(r,"__esDecorate",function(){return f}),n.export(r,"__runInitializers",function(){return p}),n.export(r,"__propKey",function(){return d}),n.export(r,"__setFunctionName",function(){return _}),n.export(r,"__metadata",function(){return h}),n.export(r,"__awaiter",function(){return m}),n.export(r,"__generator",function(){return y}),n.export(r,"__createBinding",function(){return v}),n.export(r,"__exportStar",function(){return g}),n.export(r,"__values",function(){return b}),n.export(r,"__read",function(){return j}),/** @deprecated */n.export(r,"__spread",function(){return w}),/** @deprecated */n.export(r,"__spreadArrays",function(){return x}),n.export(r,"__spreadArray",function(){return O}),n.export(r,"__await",function(){return T}),n.export(r,"__asyncGenerator",function(){return P}),n.export(r,"__asyncDelegator",function(){return S}),n.export(r,"__asyncValues",function(){return I}),n.export(r,"__makeTemplateObject",function(){return E}),n.export(r,"__importStar",function(){return F}),n.export(r,"__importDefault",function(){return A}),n.export(r,"__classPrivateFieldGet",function(){return k}),n.export(r,"__classPrivateFieldSet",function(){return W}),n.export(r,"__classPrivateFieldIn",function(){return z}),n.export(r,"__addDisposableResource",function(){return N}),n.export(r,"__disposeResources",function(){return R});var o=e("@swc/helpers/_/_type_of"),i=function(e,t){return(i=Object.setPrototypeOf||({__proto__:[]})instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(e[r]=t[r])})(e,t)};function a(e,t){if("function"!=typeof t&&null!==t)throw TypeError("Class extends value "+String(t)+" is not a constructor or null");function r(){this.constructor=e}i(e,t),e.prototype=null===t?Object.create(t):(r.prototype=t.prototype,new r)}var s=function(){return(s=Object.assign||function(e){for(var t,r=1,n=arguments.length;r<n;r++)for(var o in t=arguments[r])Object.prototype.hasOwnProperty.call(t,o)&&(e[o]=t[o]);return e}).apply(this,arguments)};function u(e,t){var r={};for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&0>t.indexOf(n)&&(r[n]=e[n]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var o=0,n=Object.getOwnPropertySymbols(e);o<n.length;o++)0>t.indexOf(n[o])&&Object.prototype.propertyIsEnumerable.call(e,n[o])&&(r[n[o]]=e[n[o]]);return r}function c(e,t,r,n){var o,i=arguments.length,a=i<3?t:null===n?n=Object.getOwnPropertyDescriptor(t,r):n;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)a=Reflect.decorate(e,t,r,n);else for(var s=e.length-1;s>=0;s--)(o=e[s])&&(a=(i<3?o(a):i>3?o(t,r,a):o(t,r))||a);return i>3&&a&&Object.defineProperty(t,r,a),a}function l(e,t){return function(r,n){t(r,n,e)}}function f(e,t,r,n,o,i){function a(e){if(void 0!==e&&"function"!=typeof e)throw TypeError("Function expected");return e}for(var s,u=n.kind,c="getter"===u?"get":"setter"===u?"set":"value",l=!t&&e?n.static?e:e.prototype:null,f=t||(l?Object.getOwnPropertyDescriptor(l,n.name):{}),p=!1,d=r.length-1;d>=0;d--){var _={};for(var h in n)_[h]="access"===h?{}:n[h];for(var h in n.access)_.access[h]=n.access[h];_.addInitializer=function(e){if(p)throw TypeError("Cannot add initializers after decoration has completed");i.push(a(e||null))};var m=(0,r[d])("accessor"===u?{get:f.get,set:f.set}:f[c],_);if("accessor"===u){if(void 0===m)continue;if(null===m||"object"!=typeof m)throw TypeError("Object expected");(s=a(m.get))&&(f.get=s),(s=a(m.set))&&(f.set=s),(s=a(m.init))&&o.unshift(s)}else(s=a(m))&&("field"===u?o.unshift(s):f[c]=s)}l&&Object.defineProperty(l,n.name,f),p=!0}function p(e,t,r){for(var n=arguments.length>2,o=0;o<t.length;o++)r=n?t[o].call(e,r):t[o].call(e);return n?r:void 0}function d(e){return(void 0===e?"undefined":(0,o._)(e))==="symbol"?e:"".concat(e)}function _(e,t,r){return(void 0===t?"undefined":(0,o._)(t))==="symbol"&&(t=t.description?"[".concat(t.description,"]"):""),Object.defineProperty(e,"name",{configurable:!0,value:r?"".concat(r," ",t):t})}function h(e,t){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(e,t)}function m(e,t,r,n){return new(r||(r=Promise))(function(o,i){function a(e){try{u(n.next(e))}catch(e){i(e)}}function s(e){try{u(n.throw(e))}catch(e){i(e)}}function u(e){var t;e.done?o(e.value):((t=e.value)instanceof r?t:new r(function(e){e(t)})).then(a,s)}u((n=n.apply(e,t||[])).next())})}function y(e,t){var r,n,o,i,a={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return i={next:s(0),throw:s(1),return:s(2)},"function"==typeof Sym
Line truncated
|
||||
// http://creativecommons.org/publicdomain/zero/1.0/
|
||||
// Not intended to be fast, but if you can make it faster, please help out!
|
||||
function(){var e={direction:"horizontal",snapToLines:!0,linePosition:"auto",lineAlign:"start",textPosition:"auto",positionAlign:"auto",size:100,alignment:"center"},t=function(t){t||(t={"&":"&","<":"<",">":">","&lrm":"","&rlm":""," ":"\xa0"}),this.entities=t,this.parse=function(r,n){// global search and replace for \0
|
||||
r=r.replace(/\0/g,"�");var a=Date.now(),s=0,u=r.split(/\r\n|\r|\n/),c=!1,l=[],f=[],p=[];function d(e,t){p.push({message:e,line:s+1,col:t})}var _=u[s],h=_.length,m="WEBVTT",y=0,v=m.length;/* HEADER */for("\uFEFF"===_[0]&&(y=1,v+=1),(h<v||_.indexOf(m)!==0+y||h>v&&" "!==_[v]&&" "!==_[v])&&d('No valid signature. (File needs to start with "WEBVTT".)'),s++;""!=u[s]&&void 0!=u[s];){if(d("No blank line after the signature."),-1!=u[s].indexOf("-->")){c=!0;break}s++}/* CUE LOOP */for(;void 0!=u[s];){for(;!c&&""==u[s];)s++;if(!c&&void 0==u[s])break;/* CUE CREATION */g=Object.assign({},e,{id:"",startTime:0,endTime:0,pauseOnExit:!1,direction:"horizontal",snapToLines:!0,linePosition:"auto",lineAlign:"start",textPosition:"auto",positionAlign:"auto",size:100,alignment:"center",text:"",tree:null});var g,b=!0;if(-1==u[s].indexOf("-->")){/* COMMENTS
|
||||
Not part of the specification's parser as these would just be ignored. However,
|
||||
we want them to be conforming and not get "Cue identifier cannot be standalone".
|
||||
*/if(g.id=u[s],/^NOTE($|[ \t])/.test(g.id)){for(s++;""!=u[s]&&void 0!=u[s];)-1!=u[s].indexOf("-->")&&d("Cannot have timestamp in a comment."),s++;continue}/* STYLES */if(/^STYLE($|[ \t])/.test(g.id)){var j=[],w=!1;for(s++;""!=u[s]&&void 0!=u[s];)-1!=u[s].indexOf("-->")&&(d("Cannot have timestamp in a style block."),w=!0),j.push(u[s]),s++;if(f.length){d("Style blocks cannot appear after the first cue.");continue}w||l.push(j.join("\n"));continue}if(""==u[++s]||void 0==u[s]){d("Cue identifier cannot be standalone.");continue}if(-1==u[s].indexOf("-->")){b=!1,d("Cue identifier needs to be followed by timestamp.");continue}}/* TIMINGS */c=!1;var x=new o(u[s],d),O=0;if(f.length>0&&(O=f[f.length-1].startTime),b&&!x.parse(g,O)){/* BAD CUE LOOP */for(/* BAD CUE */g=null,s++;""!=u[s]&&void 0!=u[s];){if(-1!=u[s].indexOf("-->")){c=!0;break}s++}continue}/* CUE TEXT LOOP */for(s++;""!=u[s]&&void 0!=u[s];){if(-1!=u[s].indexOf("-->")){d("Blank line missing before cue."),c=!0;break}""!=g.text&&(g.text+="\n"),g.text+=u[s],s++}/* CUE TEXT PROCESSING */var T=new i(g.text,d,n,t);g.tree=T.parse(g.startTime,g.endTime),f.push(g)}/* END */return f.sort(function(e,t){return e.startTime<t.startTime?-1:e.startTime>t.startTime?1:e.endTime>t.endTime?-1:e.endTime<t.endTime?1:0}),{cues:f,errors:p,time:Date.now()-a,styles:l}}},o=function(e,t){var r=/[\u0020\t\f]/,n=/[^\u0020\t\f]/,e=e,o=0,i=function(e){t(e,o+1)};function a(t){for(;void 0!=e[o]&&t.test(e[o]);)o++}function s(t){for(var r="";void 0!=e[o]&&t.test(e[o]);)r+=e[o],o++;return r}/* http://dev.w3.org/html5/webvtt/#collect-a-webvtt-timestamp */function u(){var t,r,n,a,u="minutes";// 3
|
||||
if(void 0==e[o]){i("No timestamp found.");return}// 4
|
||||
if(!/\d/.test(e[o])){i("Timestamp must start with a character in the range 0-9.");return}// 8
|
||||
if((// 5-7
|
||||
(t=s(/\d/)).length>2||parseInt(t,10)>59)&&(u="hours"),":"!=e[o]){i("No time unit separator found.");return}if(o++,2!=// 9-11
|
||||
(r=s(/\d/)).length){i("Must be exactly two digits.");return}// 12
|
||||
if("hours"==u||":"==e[o]){if(":"!=e[o]){i("No seconds found or minutes is greater than 59.");return}if(o++,2!=(n=s(/\d/)).length){i("Must be exactly two digits.");return}}else{if(2!=t.length){i("Must be exactly two digits.");return}n=r,r=t,t="0"}// 13
|
||||
if("."!=e[o]){i('No decimal separator (".") found.');return}if(o++,3!=// 14-16
|
||||
(a=s(/\d/)).length){i("Milliseconds must be given in three digits.");return}// 17
|
||||
if(parseInt(r,10)>59){i("You cannot have more than 59 minutes.");return}if(parseInt(n,10)>59){i("You cannot have more than 59 seconds.");return}return 3600*parseInt(t,10)+60*parseInt(r,10)+parseInt(n,10)+parseInt(a,10)/1e3}this.parse=function(t,s){if(a(r),t.startTime=u(),void 0!=t.startTime){// 6-8
|
||||
if(t.startTime<s&&i("Start timestamp is not greater than or equal to start timestamp of previous cue."),n.test(e[o])&&i("Timestamp not separated from '-->' by whitespace."),a(r),"-"!=e[o]||"-"!=e[++o]||">"!=e[++o]){i("No valid timestamp separator found.");return}if(o++,n.test(e[o])&&i("'-->' not separated from timestamp by whitespace."),a(r),t.endTime=u(),void 0!=t.endTime)return t.endTime<=t.startTime&&i("End timestamp is not greater than start timestamp."),n.test(e[o]),a(r),/* http://dev.w3.org/html5/webvtt/#parse-the-webvtt-settings */function(e,t){for(var n=e.split(r),o=[],a=0;a<n.length;a++)if(""!=n[a]){var s=n[a].indexOf(":"),u=n[a].slice(0,s),c=n[a].slice(s+1);if(-1!=o.indexOf(u)&&i("Duplicate setting."),o.push(u),""==c){i("No value for setting defined.");return}if("vertical"==u){if("rl"!=c&&"lr"!=c){i("Writing direction can only be set to 'rl' or 'rl'.");continue}t.direction=c}else if("line"==u){if(/,/.test(c)){var l=c.split(",");c=l[0];var f=l[1]}if(!/^[-\d](\d*)(\.\d+)?%?$/.test(c)){i("Line position takes a number or percentage.");continue}if(-1!=c.indexOf("-",1)){i("Line position can only have '-' at the start.");continue}if(-1!=c.indexOf("%")&&c.indexOf("%")!=c.length-1){i("Line position can only have '%' at the end.");continue}if("-"==c[0]&&"%"==c[c.length-1]){i("Line position cannot be a negative percentage.");continue}var p=c,d=!1;if("%"==c[c.length-1]&&(d=!0,p=c.slice(0,c.length-1),parseInt(c,10)>100)){i("Line position cannot be >100%.");continue}if(""===p||isNaN(p)||!isFinite(p)){i("Line position needs to be a number");continue}if(void 0!==f){if(!["start","center","end"].includes(f)){i("Line alignment needs to be one of start, center or end");continue}t.lineAlign=f}t.snapToLines=!d,t.linePosition=parseFloat(p),parseFloat(p).toString()!==p&&(t.nonSerializable=!0)}else if("position"==u){if(/,/.test(c)){var l=c.split(",");c=l[0];var _=l[1]}if("%"!=c[c.length-1]){i("Text position must be a percentage.");continue}if(parseInt(c,10)>100||0>parseInt(c,10)){i("Text position needs to be between 0 and 100%.");continue}if(""===(p=c.slice(0,c.length-1))||isNaN(p)||!isFinite(p)){i("Line position needs to be a number");continue}if(void 0!==_){if(!["line-left","center","line-right"].includes(_)){i("Position alignment needs to be one of line-left, center or line-right");continue}t.positionAlign=_}t.textPosition=parseFloat(p)}else if("size"==u){if("%"!=c[c.length-1]){i("Size must be a percentage.");continue}if(parseInt(c,10)>100){i("Size cannot be >100%.");continue}var h=c.slice(0,c.length-1);if(void 0===h||""===h||isNaN(h)){i("Size needs to be a number"),h=100;continue}if((h=parseFloat(h))<0||h>100){i("Size needs to be between 0 and 100%.");continue}t.size=h}else if("align"==u){var m=["start","center","end","left","right"];if(-1==m.indexOf(c)){i("Alignment can only be set to one of "+m.join(", ")+".");continue}t.alignment=c}else i("Invalid setting.")}}(e.substring(o),t),!0}},this.parseTimestamp=function(){var t=u();if(void 0!=e[o]){i("Timestamp must not have trailing characters.");return}return t}},i=function(e,t,r,i){this.entities=i;var a=this,e=e,s=0,u=function(e){"metadata"!=r&&t(e,s+1)};this.parse=function(t,c){var l={children:[]},f=l,p=[];function d(e){f.children.push({type:"object",name:e[1],classes:e[2],children:[],parent:f}),f=f.children[f.children.length-1]}for(;void 0!=e[s];){var _=function(){for(var t="data",r="",n="",o=[];void 0!=e[s-1]||0==s;){var c=e[s];if("data"==t){if("&"==c)n=c,t="escape";else if("<"==c&&""==r)t="tag";else{if("<"==c||void 0==c)return["text",r];r+=c}}else if("escape"==t){if("<"==c||void 0==c){u("Incorrect escape.");var l=void 0;return(l=n.match(/^&#([0-9]+)$/))?r+=String.fromCharCode(l[1]):a.entities[n]?r+=a.entities[n]:r+=n,["text",r]}if("&"==c)u("Incorrect escape."),r+=n,n=c;else if(/[a-z#0-9]/i.test(c))n+=c;else if(";"==c){var f=void 0;(f=n.match(/^&#(x?[0-9]+)$/))?r+=String.fromCharCode("0"+f[1]):a.entities[n+c]?r+=a.entities[n+c]:(f=Object.keys(i).find(function(e){return n.startsWith(e)}))?r+=a.entities[f]+n.slice(f.length)+c:(u("Incorrect escape."),r+=n+";"),t="data"}else u("Incorrect escape."),r+=n+c,t="data"}else if("tag"==t){if(" "==c||"\n"==c||"\f"==c||" "==c)t="start tag annotation";else if("."==c)t="start tag class";else if("/"==c)t="end tag";else if(/\d/.test(c))r=c,t="timestamp tag";else{if(">"==c||void 0==c)return">"==c&&s++,["start tag","",[],""];r=c,t="start tag"}}else if("start tag"==t){if(" "==c||"\f"==c||" "==c)t="start tag annotation";else if("\n"==c)n=c,t="start tag annotation";else if("."==c)t="start tag class";else{if(">"==c||void 0==c)return">"==c&&s++,["start tag",r,[],""];r+=c}}else if("start tag class"==t){if(" "==c||"\f"==c||" "==c)n&&o.push(n),n="",t="start tag annotation";else if("\n"==c)n&&o.push(n),n=c,t="start tag annotation";else if("."==c)n&&o.push(n),n="";else{if(">"==c||void 0==c)return">"==c&&s++,n&&o.push(n),["start tag",r,o,""];n+=c}}else if("start tag annotation"==t){if(">"==c||void 0==c)return">"==c&&s++,["start tag",r,o,n=n.split(Line truncated
|
||||
;// 8
|
||||
s++}}();if("text"==_[0])f.children.push({type:"text",value:_[1],parent:f});else if("start tag"==_[0]){"chapters"==r&&u("Start tags not allowed in chapter title text.");var h=_[1];"v"!=h&&"lang"!=h&&""!=_[3]&&u("Only <v> and <lang> can have an annotation."),"c"==h||"i"==h||"b"==h||"u"==h||"ruby"==h?d(_):"rt"==h&&"ruby"==f.name?d(_):"v"==h?(function(e){for(var t=f;t;){if("v"==t.name)return!0;t=t.parent}}(0)&&u("<v> cannot be nested inside itself."),d(_),f.value=_[3]// annotation
|
||||
,_[3]||u("<v> requires an annotation.")):"lang"==h?(d(_),f.value=_[3]// language
|
||||
):u("Incorrect start tag.")}else if("end tag"==_[0])"chapters"==r&&u("End tags not allowed in chapter title text."),_[1]==f.name?f=f.parent:"ruby"==_[1]&&"rt"==f.name?f=f.parent.parent:u("Incorrect end tag.");else if("timestamp"==_[0]){"chapters"==r&&u("Timestamp not allowed in chapter title text.");var m=new o(_[1],u).parseTimestamp();void 0!=m&&((m<=t||m>=c)&&u("Timestamp must be between start timestamp and end timestamp."),p.length>0&&p[p.length-1]>=m&&u("Timestamp must be greater than any previous timestamp."),f.children.push({type:"timestamp",value:m,parent:f}),p.push(m))}}for(;f.parent;)"v"!=f.name&&u("Required end tag missing."),f=f.parent;return function e(t){var r=(0,n._)({},t);return t.children&&(r.children=t.children.map(e)),r.parent&&delete r.parent,r}(l)}},a=function(){function t(e){var t=("00"+1e3*(e-Math.floor(e)).toFixed(3)).slice(-3),r=0,n=0,o=0;return e>=3600&&(r=Math.floor(e/3600)),n=Math.floor((e-3600*r)/60),o=Math.floor(e-3600*r-60*n),(r?r+":":"")+(""+n).padStart(2,"0")+":"+(""+o).padStart(2,"0")+"."+t}this.serialize=function(r,n){var o="WEBVTT\n\n";if(n)for(var i=0;i<n.length;i++)o+="STYLE\n"+n[i]+"\n\n";for(var i=0;i<r.length;i++)o+=function(r){var n,o;return(void 0!==r.id?r.id+"\n":"")+t(r.startTime)+" --> "+t(r.endTime)+(n="",(o=Object.keys(e).filter(function(t){return r[t]!==e[t]})).includes("direction")&&(n+=" vertical:"+r.direction),o.includes("alignment")&&(n+=" align:"+r.alignment),o.includes("size")&&(n+=" size:"+r.size+"%"),(o.includes("lineAlign")||o.includes("linePosition"))&&(n+=" line:"+r.linePosition+(r.snapToLines?"":"%")+(r.lineAlign&&r.lineAlign!=e.lineAlign?","+r.lineAlign:"")),(o.includes("textPosition")||o.includes("positionAlign"))&&(n+=" position:"+r.textPosition+"%"+(r.positionAlign&&r.positionAlign!==e.positionAlign?","+r.positionAlign:"")),n)+"\n"+function e(r){for(var n="",o=0;o<r.length;o++){var i=r[o];if("text"==i.type)n+=i.value.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">");else if("object"==i.type){if(n+="<"+i.name,i.classes)for(var a=0;a<i.classes.length;a++)n+="."+i.classes[a];i.value&&(n+=" "+i.value),n+=">",i.children&&(n+=e(i.children)),n+="</"+i.name+">"}else"timestamp"==i.type?n+="<"+t(i.value)+">":n+="<"+i.value+">"}return n}(r.tree.children)+"\n\n"}(r[i]);return o}};function s(e){e.WebVTTParser=t,e.WebVTTCueTimingsAndSettingsParser=o,e.WebVTTCueTextParser=i,e.WebVTTSerializer=a}"undefined"!=typeof window&&s(window),s(r)}()},{"@swc/helpers/_/_object_spread":"9agdF"}]},["2hz0c"],"2hz0c","parcelRequire4dc0");
|
||||
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"license": "MIT",
|
||||
"version": "1.0.0",
|
||||
"name": "artplayer-plugin-multiple-subtitles",
|
||||
"types": "types/artplayer-plugin-multiple-subtitles.d.ts",
|
||||
"description": "multiple subtitles plugin for ArtPlayer",
|
||||
"main": "dist/artplayer-plugin-multiple-subtitles.js",
|
||||
"legacy": "dist/artplayer-plugin-multiple-subtitles.legacy.js",
|
||||
"author": "Harvey Zack <laozhaochaguan@gmail.com>",
|
||||
"browserslist": "last 1 Chrome version",
|
||||
"homepage": "https://artplayer.org",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/zhw2590582/ArtPlayer.git"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/zhw2590582/ArtPlayer/issues"
|
||||
},
|
||||
"keywords": [
|
||||
"html5",
|
||||
"video",
|
||||
"player"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
import { WebVTTParser, WebVTTSerializer } from './parser';
|
||||
|
||||
function unescape(str) {
|
||||
const map = {
|
||||
'&': '&',
|
||||
'<': '<',
|
||||
'>': '>',
|
||||
''': "'",
|
||||
'"': '"',
|
||||
};
|
||||
const reg = new RegExp(`(${Object.keys(map).join('|')})`, 'g');
|
||||
return str.replace(reg, (tag) => map[tag] || tag);
|
||||
}
|
||||
|
||||
async function loadSubtitleAsVtt(option) {
|
||||
const { getExt, srtToVtt, assToVtt } = Artplayer.utils;
|
||||
const response = await fetch(option.url);
|
||||
const buffer = await response.arrayBuffer();
|
||||
const decoder = new TextDecoder(option.encoding || 'utf-8');
|
||||
const text = decoder.decode(buffer);
|
||||
switch (option.type || getExt(option.url)) {
|
||||
case 'srt': {
|
||||
return srtToVtt(text);
|
||||
}
|
||||
case 'ass': {
|
||||
return assToVtt(text);
|
||||
}
|
||||
case 'vtt': {
|
||||
return text;
|
||||
}
|
||||
default:
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
function mergeVtts(vtts, subtitles) {
|
||||
const parser = new WebVTTParser();
|
||||
const seri = new WebVTTSerializer();
|
||||
const result = parser.parse('', 'metadata');
|
||||
|
||||
for (let i = 0; i < vtts.length; i++) {
|
||||
const option = subtitles[i];
|
||||
const tree = parser.parse(vtts[i], 'metadata');
|
||||
|
||||
for (let j = 0; j < tree.cues.length; j++) {
|
||||
const cue = tree.cues[j];
|
||||
for (let k = 0; k < cue.tree.children.length; k++) {
|
||||
const children = cue.tree.children[k];
|
||||
children.value = `<div class="art-subtitle-${option.name}">${children.value}</div>`;
|
||||
}
|
||||
}
|
||||
|
||||
if (result.cues.length === 0) {
|
||||
result.cues = tree.cues;
|
||||
} else {
|
||||
for (let l = 0; l < result.cues.length; l++) {
|
||||
result.cues[l].tree.children.push(...(tree.cues[l]?.tree?.children || []));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return seri.serialize(result.cues);
|
||||
}
|
||||
|
||||
export default function artplayerPluginMultipleSubtitles({ subtitles }) {
|
||||
return async (art) => {
|
||||
const vtts = await Promise.all(subtitles.map(loadSubtitleAsVtt));
|
||||
const vtt = mergeVtts(vtts, subtitles);
|
||||
const url = URL.createObjectURL(new Blob([vtt], { type: 'text/vtt' }));
|
||||
|
||||
art.option.subtitle.escape = false;
|
||||
|
||||
art.subtitle.init({
|
||||
...art.option.subtitle,
|
||||
url,
|
||||
type: 'vtt',
|
||||
onVttLoad: unescape,
|
||||
});
|
||||
};
|
||||
}
|
||||
artplayerPluginMultipleSubtitles.env = process.env.NODE_ENV;
|
||||
artplayerPluginMultipleSubtitles.version = process.env.APP_VER;
|
||||
artplayerPluginMultipleSubtitles.build = process.env.BUILD_DATE;
|
||||
|
||||
if (typeof window !== 'undefined') {
|
||||
window['artplayerPluginMultipleSubtitles'] = artplayerPluginMultipleSubtitles;
|
||||
}
|
||||
@@ -0,0 +1,888 @@
|
||||
// Any copyright is dedicated to the Public Domain.
|
||||
// http://creativecommons.org/publicdomain/zero/1.0/
|
||||
|
||||
// Not intended to be fast, but if you can make it faster, please help out!
|
||||
|
||||
(function () {
|
||||
var defaultCueSettings = {
|
||||
direction:"horizontal",
|
||||
snapToLines:true,
|
||||
linePosition:"auto",
|
||||
lineAlign:"start",
|
||||
textPosition:"auto",
|
||||
positionAlign:"auto",
|
||||
size:100,
|
||||
alignment:"center",
|
||||
};
|
||||
|
||||
var WebVTTParser = function(entities) {
|
||||
if (!entities) {
|
||||
entities = {
|
||||
"&": "&",
|
||||
"<": "<",
|
||||
">": ">",
|
||||
"&lrm": "\u200e",
|
||||
"&rlm": "\u200f",
|
||||
" ": "\u00A0"
|
||||
}
|
||||
}
|
||||
this.entities = entities
|
||||
this.parse = function(input, mode) {
|
||||
// global search and replace for \0
|
||||
input = input.replace(/\0/g, '\uFFFD');
|
||||
var NEWLINE = /\r\n|\r|\n/,
|
||||
startTime = Date.now(),
|
||||
linePos = 0,
|
||||
lines = input.split(NEWLINE),
|
||||
alreadyCollected = false,
|
||||
styles = [],
|
||||
cues = [],
|
||||
errors = []
|
||||
function err(message, col) {
|
||||
errors.push({message:message, line:linePos+1, col:col})
|
||||
}
|
||||
|
||||
var line = lines[linePos],
|
||||
lineLength = line.length,
|
||||
signature = "WEBVTT",
|
||||
bom = 0,
|
||||
signature_length = signature.length
|
||||
|
||||
/* Byte order mark */
|
||||
if (line[0] === "\ufeff") {
|
||||
bom = 1
|
||||
signature_length += 1
|
||||
}
|
||||
/* SIGNATURE */
|
||||
if (
|
||||
lineLength < signature_length ||
|
||||
line.indexOf(signature) !== 0+bom ||
|
||||
lineLength > signature_length &&
|
||||
line[signature_length] !== " " &&
|
||||
line[signature_length] !== "\t"
|
||||
) {
|
||||
err("No valid signature. (File needs to start with \"WEBVTT\".)")
|
||||
}
|
||||
|
||||
linePos++
|
||||
|
||||
/* HEADER */
|
||||
while(lines[linePos] != "" && lines[linePos] != undefined) {
|
||||
err("No blank line after the signature.")
|
||||
if(lines[linePos].indexOf("-->") != -1) {
|
||||
alreadyCollected = true
|
||||
break
|
||||
}
|
||||
linePos++
|
||||
}
|
||||
|
||||
/* CUE LOOP */
|
||||
while(lines[linePos] != undefined) {
|
||||
var cue
|
||||
while(!alreadyCollected && lines[linePos] == "") {
|
||||
linePos++
|
||||
}
|
||||
if(!alreadyCollected && lines[linePos] == undefined)
|
||||
break
|
||||
|
||||
/* CUE CREATION */
|
||||
cue = Object.assign({}, defaultCueSettings, {
|
||||
id:"",
|
||||
startTime:0,
|
||||
endTime:0,
|
||||
pauseOnExit:false,
|
||||
direction:"horizontal",
|
||||
snapToLines:true,
|
||||
linePosition:"auto",
|
||||
lineAlign:"start",
|
||||
textPosition:"auto",
|
||||
positionAlign:"auto",
|
||||
size:100,
|
||||
alignment:"center",
|
||||
text:"",
|
||||
tree:null
|
||||
})
|
||||
|
||||
var parseTimings = true
|
||||
|
||||
if(lines[linePos].indexOf("-->") == -1) {
|
||||
cue.id = lines[linePos]
|
||||
|
||||
/* COMMENTS
|
||||
Not part of the specification's parser as these would just be ignored. However,
|
||||
we want them to be conforming and not get "Cue identifier cannot be standalone".
|
||||
*/
|
||||
if(/^NOTE($|[ \t])/.test(cue.id)) { // .startsWith fails in Chrome
|
||||
linePos++
|
||||
while(lines[linePos] != "" && lines[linePos] != undefined) {
|
||||
if(lines[linePos].indexOf("-->") != -1)
|
||||
err("Cannot have timestamp in a comment.")
|
||||
linePos++
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
/* STYLES */
|
||||
if(/^STYLE($|[ \t])/.test(cue.id)) {
|
||||
var style = []
|
||||
var invalid = false
|
||||
linePos++
|
||||
while(lines[linePos] != "" && lines[linePos] != undefined) {
|
||||
if(lines[linePos].indexOf("-->") != -1) {
|
||||
err("Cannot have timestamp in a style block.")
|
||||
invalid = true
|
||||
}
|
||||
style.push(lines[linePos])
|
||||
linePos++
|
||||
}
|
||||
if(cues.length) {
|
||||
err("Style blocks cannot appear after the first cue.")
|
||||
continue
|
||||
}
|
||||
if (!invalid) {
|
||||
styles.push(style.join('\n'))
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
linePos++
|
||||
|
||||
if(lines[linePos] == "" || lines[linePos] == undefined) {
|
||||
err("Cue identifier cannot be standalone.")
|
||||
continue
|
||||
}
|
||||
|
||||
if(lines[linePos].indexOf("-->") == -1) {
|
||||
parseTimings = false
|
||||
err("Cue identifier needs to be followed by timestamp.")
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
/* TIMINGS */
|
||||
alreadyCollected = false
|
||||
var timings = new WebVTTCueTimingsAndSettingsParser(lines[linePos], err)
|
||||
var previousCueStart = 0
|
||||
if(cues.length > 0) {
|
||||
previousCueStart = cues[cues.length-1].startTime
|
||||
}
|
||||
if(parseTimings && !timings.parse(cue, previousCueStart)) {
|
||||
/* BAD CUE */
|
||||
|
||||
cue = null
|
||||
linePos++
|
||||
|
||||
/* BAD CUE LOOP */
|
||||
while(lines[linePos] != "" && lines[linePos] != undefined) {
|
||||
if(lines[linePos].indexOf("-->") != -1) {
|
||||
alreadyCollected = true
|
||||
break
|
||||
}
|
||||
linePos++
|
||||
}
|
||||
continue
|
||||
}
|
||||
linePos++
|
||||
|
||||
/* CUE TEXT LOOP */
|
||||
while(lines[linePos] != "" && lines[linePos] != undefined) {
|
||||
if(lines[linePos].indexOf("-->") != -1) {
|
||||
err("Blank line missing before cue.")
|
||||
alreadyCollected = true
|
||||
break
|
||||
}
|
||||
if(cue.text != "")
|
||||
cue.text += "\n"
|
||||
cue.text += lines[linePos]
|
||||
linePos++
|
||||
}
|
||||
|
||||
/* CUE TEXT PROCESSING */
|
||||
var cuetextparser = new WebVTTCueTextParser(cue.text, err, mode, entities)
|
||||
cue.tree = cuetextparser.parse(cue.startTime, cue.endTime)
|
||||
cues.push(cue)
|
||||
}
|
||||
cues.sort(function(a, b) {
|
||||
if (a.startTime < b.startTime)
|
||||
return -1
|
||||
if (a.startTime > b.startTime)
|
||||
return 1
|
||||
if (a.endTime > b.endTime)
|
||||
return -1
|
||||
if (a.endTime < b.endTime)
|
||||
return 1
|
||||
return 0
|
||||
})
|
||||
/* END */
|
||||
return {cues:cues, errors:errors, time:Date.now()-startTime, styles: styles}
|
||||
}
|
||||
}
|
||||
|
||||
var WebVTTCueTimingsAndSettingsParser = function(line, errorHandler) {
|
||||
var SPACE = /[\u0020\t\f]/,
|
||||
NOSPACE = /[^\u0020\t\f]/,
|
||||
line = line,
|
||||
pos = 0,
|
||||
err = function(message) {
|
||||
errorHandler(message, pos+1)
|
||||
},
|
||||
spaceBeforeSetting = true
|
||||
function skip(pattern) {
|
||||
while(
|
||||
line[pos] != undefined &&
|
||||
pattern.test(line[pos])
|
||||
) {
|
||||
pos++
|
||||
}
|
||||
}
|
||||
function collect(pattern) {
|
||||
var str = ""
|
||||
while(
|
||||
line[pos] != undefined &&
|
||||
pattern.test(line[pos])
|
||||
) {
|
||||
str += line[pos]
|
||||
pos++
|
||||
}
|
||||
return str
|
||||
}
|
||||
/* http://dev.w3.org/html5/webvtt/#collect-a-webvtt-timestamp */
|
||||
function timestamp() {
|
||||
var units = "minutes",
|
||||
val1,
|
||||
val2,
|
||||
val3,
|
||||
val4
|
||||
// 3
|
||||
if(line[pos] == undefined) {
|
||||
err("No timestamp found.")
|
||||
return
|
||||
}
|
||||
// 4
|
||||
if(!/\d/.test(line[pos])) {
|
||||
err("Timestamp must start with a character in the range 0-9.")
|
||||
return
|
||||
}
|
||||
// 5-7
|
||||
val1 = collect(/\d/)
|
||||
if(val1.length > 2 || parseInt(val1, 10) > 59) {
|
||||
units = "hours"
|
||||
}
|
||||
// 8
|
||||
if(line[pos] != ":") {
|
||||
err("No time unit separator found.")
|
||||
return
|
||||
}
|
||||
pos++
|
||||
// 9-11
|
||||
val2 = collect(/\d/)
|
||||
if(val2.length != 2) {
|
||||
err("Must be exactly two digits.")
|
||||
return
|
||||
}
|
||||
// 12
|
||||
if(units == "hours" || line[pos] == ":") {
|
||||
if(line[pos] != ":") {
|
||||
err("No seconds found or minutes is greater than 59.")
|
||||
return
|
||||
}
|
||||
pos++
|
||||
val3 = collect(/\d/)
|
||||
if(val3.length != 2) {
|
||||
err("Must be exactly two digits.")
|
||||
return
|
||||
}
|
||||
} else {
|
||||
if (val1.length != 2) {
|
||||
err("Must be exactly two digits.")
|
||||
return
|
||||
}
|
||||
val3 = val2
|
||||
val2 = val1
|
||||
val1 = "0"
|
||||
}
|
||||
// 13
|
||||
if(line[pos] != ".") {
|
||||
err("No decimal separator (\".\") found.")
|
||||
return
|
||||
}
|
||||
pos++
|
||||
// 14-16
|
||||
val4 = collect(/\d/)
|
||||
if(val4.length != 3) {
|
||||
err("Milliseconds must be given in three digits.")
|
||||
return
|
||||
}
|
||||
// 17
|
||||
if(parseInt(val2, 10) > 59) {
|
||||
err("You cannot have more than 59 minutes.")
|
||||
return
|
||||
}
|
||||
if(parseInt(val3, 10) > 59) {
|
||||
err("You cannot have more than 59 seconds.")
|
||||
return
|
||||
}
|
||||
return parseInt(val1, 10) * 60 * 60 + parseInt(val2, 10) * 60 + parseInt(val3, 10) + parseInt(val4, 10) / 1000
|
||||
}
|
||||
|
||||
/* http://dev.w3.org/html5/webvtt/#parse-the-webvtt-settings */
|
||||
function parseSettings(input, cue) {
|
||||
var settings = input.split(SPACE),
|
||||
seen = []
|
||||
for(var i=0; i < settings.length; i++) {
|
||||
if(settings[i] == "")
|
||||
continue
|
||||
|
||||
var index = settings[i].indexOf(':'),
|
||||
setting = settings[i].slice(0, index),
|
||||
value = settings[i].slice(index + 1)
|
||||
|
||||
if(seen.indexOf(setting) != -1) {
|
||||
err("Duplicate setting.")
|
||||
}
|
||||
seen.push(setting)
|
||||
|
||||
if(value == "") {
|
||||
err("No value for setting defined.")
|
||||
return
|
||||
}
|
||||
|
||||
if(setting == "vertical") { // writing direction
|
||||
if(value != "rl" && value != "lr") {
|
||||
err("Writing direction can only be set to 'rl' or 'rl'.")
|
||||
continue
|
||||
}
|
||||
cue.direction = value
|
||||
} else if(setting == "line") { // line position and optionally line alignment
|
||||
if (/,/.test(value)) {
|
||||
var comp = value.split(',')
|
||||
value = comp[0]
|
||||
var lineAlign = comp[1]
|
||||
}
|
||||
if(!/^[-\d](\d*)(\.\d+)?%?$/.test(value)) {
|
||||
err("Line position takes a number or percentage.")
|
||||
continue
|
||||
}
|
||||
if(value.indexOf("-", 1) != -1) {
|
||||
err("Line position can only have '-' at the start.")
|
||||
continue
|
||||
}
|
||||
if(value.indexOf("%") != -1 && value.indexOf("%") != value.length-1) {
|
||||
err("Line position can only have '%' at the end.")
|
||||
continue
|
||||
}
|
||||
if(value[0] == "-" && value[value.length-1] == "%") {
|
||||
err("Line position cannot be a negative percentage.")
|
||||
continue
|
||||
}
|
||||
var numVal = value;
|
||||
var isPercent = false;
|
||||
if(value[value.length-1] == "%") {
|
||||
isPercent = true;
|
||||
numVal = value.slice(0, value.length-1)
|
||||
if(parseInt(value, 10) > 100) {
|
||||
err("Line position cannot be >100%.")
|
||||
continue
|
||||
}
|
||||
}
|
||||
if (numVal === '' || isNaN(numVal) || !isFinite(numVal)) {
|
||||
err("Line position needs to be a number")
|
||||
continue
|
||||
}
|
||||
if (lineAlign !== undefined) {
|
||||
if (!["start", "center", "end"].includes(lineAlign)) {
|
||||
err("Line alignment needs to be one of start, center or end")
|
||||
continue
|
||||
}
|
||||
cue.lineAlign = lineAlign
|
||||
}
|
||||
cue.snapToLines = !isPercent;
|
||||
cue.linePosition = parseFloat(numVal)
|
||||
if (parseFloat(numVal).toString() !== numVal) {
|
||||
cue.nonSerializable = true;
|
||||
}
|
||||
} else if(setting == "position") { // text position and optional positionAlign
|
||||
if (/,/.test(value)) {
|
||||
var comp = value.split(',')
|
||||
value = comp[0]
|
||||
var positionAlign = comp[1]
|
||||
}
|
||||
if(value[value.length-1] != "%") {
|
||||
err("Text position must be a percentage.")
|
||||
continue
|
||||
}
|
||||
if(parseInt(value, 10) > 100 || parseInt(value, 10) < 0) {
|
||||
err("Text position needs to be between 0 and 100%.")
|
||||
continue
|
||||
}
|
||||
numVal = value.slice(0, value.length-1)
|
||||
if (numVal === '' || isNaN(numVal) || !isFinite(numVal)) {
|
||||
err("Line position needs to be a number")
|
||||
continue
|
||||
}
|
||||
if (positionAlign !== undefined) {
|
||||
if (!["line-left", "center", "line-right"].includes(positionAlign)) {
|
||||
err("Position alignment needs to be one of line-left, center or line-right")
|
||||
continue
|
||||
}
|
||||
cue.positionAlign = positionAlign
|
||||
}
|
||||
cue.textPosition = parseFloat(numVal)
|
||||
} else if(setting == "size") { // size
|
||||
if(value[value.length-1] != "%") {
|
||||
err("Size must be a percentage.")
|
||||
continue
|
||||
}
|
||||
if(parseInt(value, 10) > 100) {
|
||||
err("Size cannot be >100%.")
|
||||
continue
|
||||
}
|
||||
var size = value.slice(0, value.length -1)
|
||||
if (size === undefined || size === "" || isNaN(size)) {
|
||||
err("Size needs to be a number")
|
||||
size = 100
|
||||
continue
|
||||
} else {
|
||||
size = parseFloat(size)
|
||||
if (size < 0 || size > 100) {
|
||||
err("Size needs to be between 0 and 100%.")
|
||||
continue;
|
||||
}
|
||||
}
|
||||
cue.size = size
|
||||
} else if(setting == "align") { // alignment
|
||||
var alignValues = ["start", "center", "end", "left", "right"]
|
||||
if(alignValues.indexOf(value) == -1) {
|
||||
err("Alignment can only be set to one of " + alignValues.join(", ") + ".")
|
||||
continue
|
||||
}
|
||||
cue.alignment = value
|
||||
} else {
|
||||
err("Invalid setting.")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.parse = function(cue, previousCueStart) {
|
||||
skip(SPACE)
|
||||
cue.startTime = timestamp()
|
||||
if(cue.startTime == undefined) {
|
||||
return
|
||||
}
|
||||
if(cue.startTime < previousCueStart) {
|
||||
err("Start timestamp is not greater than or equal to start timestamp of previous cue.")
|
||||
}
|
||||
if(NOSPACE.test(line[pos])) {
|
||||
err("Timestamp not separated from '-->' by whitespace.")
|
||||
}
|
||||
skip(SPACE)
|
||||
// 6-8
|
||||
if(line[pos] != "-") {
|
||||
err("No valid timestamp separator found.")
|
||||
return
|
||||
}
|
||||
pos++
|
||||
if(line[pos] != "-") {
|
||||
err("No valid timestamp separator found.")
|
||||
return
|
||||
}
|
||||
pos++
|
||||
if(line[pos] != ">") {
|
||||
err("No valid timestamp separator found.")
|
||||
return
|
||||
}
|
||||
pos++
|
||||
if(NOSPACE.test(line[pos])) {
|
||||
err("'-->' not separated from timestamp by whitespace.")
|
||||
}
|
||||
skip(SPACE)
|
||||
cue.endTime = timestamp()
|
||||
if(cue.endTime == undefined) {
|
||||
return
|
||||
}
|
||||
if(cue.endTime <= cue.startTime) {
|
||||
err("End timestamp is not greater than start timestamp.")
|
||||
}
|
||||
|
||||
if(NOSPACE.test(line[pos])) {
|
||||
spaceBeforeSetting = false
|
||||
}
|
||||
skip(SPACE)
|
||||
parseSettings(line.substring(pos), cue)
|
||||
return true
|
||||
}
|
||||
this.parseTimestamp = function() {
|
||||
var ts = timestamp()
|
||||
if(line[pos] != undefined) {
|
||||
err("Timestamp must not have trailing characters.")
|
||||
return
|
||||
}
|
||||
return ts
|
||||
}
|
||||
}
|
||||
|
||||
var WebVTTCueTextParser = function(line, errorHandler, mode, entities) {
|
||||
this.entities = entities
|
||||
var self = this
|
||||
var line = line,
|
||||
pos = 0,
|
||||
err = function(message) {
|
||||
if(mode == "metadata")
|
||||
return
|
||||
errorHandler(message, pos+1)
|
||||
}
|
||||
|
||||
this.parse = function(cueStart, cueEnd) {
|
||||
function removeCycles(tree) {
|
||||
const cyclelessTree = {...tree};
|
||||
if (tree.children) {
|
||||
cyclelessTree.children = tree.children.map(removeCycles);
|
||||
}
|
||||
if (cyclelessTree.parent) {
|
||||
delete cyclelessTree.parent;
|
||||
}
|
||||
return cyclelessTree;
|
||||
}
|
||||
|
||||
var result = {children:[]},
|
||||
current = result,
|
||||
timestamps = []
|
||||
|
||||
function attach(token) {
|
||||
current.children.push({type:"object", name:token[1], classes:token[2], children:[], parent:current})
|
||||
current = current.children[current.children.length-1]
|
||||
}
|
||||
function inScope(name) {
|
||||
var node = current
|
||||
while(node) {
|
||||
if(node.name == name)
|
||||
return true
|
||||
node = node.parent
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
while(line[pos] != undefined) {
|
||||
var token = nextToken()
|
||||
if(token[0] == "text") {
|
||||
current.children.push({type:"text", value:token[1], parent:current})
|
||||
} else if(token[0] == "start tag") {
|
||||
if(mode == "chapters")
|
||||
err("Start tags not allowed in chapter title text.")
|
||||
var name = token[1]
|
||||
if(name != "v" && name != "lang" && token[3] != "") {
|
||||
err("Only <v> and <lang> can have an annotation.")
|
||||
}
|
||||
if(
|
||||
name == "c" ||
|
||||
name == "i" ||
|
||||
name == "b" ||
|
||||
name == "u" ||
|
||||
name == "ruby"
|
||||
) {
|
||||
attach(token)
|
||||
} else if(name == "rt" && current.name == "ruby") {
|
||||
attach(token)
|
||||
} else if(name == "v") {
|
||||
if(inScope("v")) {
|
||||
err("<v> cannot be nested inside itself.")
|
||||
}
|
||||
attach(token)
|
||||
current.value = token[3] // annotation
|
||||
if(!token[3]) {
|
||||
err("<v> requires an annotation.")
|
||||
}
|
||||
} else if(name == "lang") {
|
||||
attach(token)
|
||||
current.value = token[3] // language
|
||||
} else {
|
||||
err("Incorrect start tag.")
|
||||
}
|
||||
} else if(token[0] == "end tag") {
|
||||
if(mode == "chapters")
|
||||
err("End tags not allowed in chapter title text.")
|
||||
// XXX check <ruby> content
|
||||
if(token[1] == current.name) {
|
||||
current = current.parent
|
||||
} else if(token[1] == "ruby" && current.name == "rt") {
|
||||
current = current.parent.parent
|
||||
} else {
|
||||
err("Incorrect end tag.")
|
||||
}
|
||||
} else if(token[0] == "timestamp") {
|
||||
if(mode == "chapters")
|
||||
err("Timestamp not allowed in chapter title text.")
|
||||
var timings = new WebVTTCueTimingsAndSettingsParser(token[1], err),
|
||||
timestamp = timings.parseTimestamp()
|
||||
if(timestamp != undefined) {
|
||||
if(timestamp <= cueStart || timestamp >= cueEnd) {
|
||||
err("Timestamp must be between start timestamp and end timestamp.")
|
||||
}
|
||||
if(timestamps.length > 0 && timestamps[timestamps.length-1] >= timestamp) {
|
||||
err("Timestamp must be greater than any previous timestamp.")
|
||||
}
|
||||
current.children.push({type:"timestamp", value:timestamp, parent:current})
|
||||
timestamps.push(timestamp)
|
||||
}
|
||||
}
|
||||
}
|
||||
while(current.parent) {
|
||||
if(current.name != "v") {
|
||||
err("Required end tag missing.")
|
||||
}
|
||||
current = current.parent
|
||||
}
|
||||
return removeCycles(result)
|
||||
}
|
||||
|
||||
function nextToken() {
|
||||
var state = "data",
|
||||
result = "",
|
||||
buffer = "",
|
||||
classes = []
|
||||
while(line[pos-1] != undefined || pos == 0) {
|
||||
var c = line[pos]
|
||||
if(state == "data") {
|
||||
if(c == "&") {
|
||||
buffer = c
|
||||
state = "escape"
|
||||
} else if(c == "<" && result == "") {
|
||||
state = "tag"
|
||||
} else if(c == "<" || c == undefined) {
|
||||
return ["text", result]
|
||||
} else {
|
||||
result += c
|
||||
}
|
||||
} else if(state == "escape") {
|
||||
if(c == "<" || c == undefined) {
|
||||
err("Incorrect escape.")
|
||||
let m;
|
||||
if (m = buffer.match(/^&#([0-9]+)$/)) {
|
||||
result += String.fromCharCode(m[1])
|
||||
} else {
|
||||
if(self.entities[buffer]) {
|
||||
result += self.entities[buffer]
|
||||
} else {
|
||||
result += buffer
|
||||
}
|
||||
}
|
||||
return ["text", result]
|
||||
} else if(c == "&") {
|
||||
err("Incorrect escape.")
|
||||
result += buffer
|
||||
buffer = c
|
||||
} else if(/[a-z#0-9]/i.test(c)) {
|
||||
buffer += c
|
||||
} else if(c == ";") {
|
||||
let m;
|
||||
if (m = buffer.match(/^&#(x?[0-9]+)$/)) {
|
||||
// we prepend "0" so that x20 be interpreted as hexadecim (0x20)
|
||||
result += String.fromCharCode("0" + m[1])
|
||||
} else if(self.entities[buffer + c]) {
|
||||
result += self.entities[buffer + c]
|
||||
} else if (m = Object.keys(entities).find(n => buffer.startsWith(n))) { // partial match
|
||||
result += self.entities[m] + buffer.slice(m.length) + c
|
||||
} else {
|
||||
err("Incorrect escape.")
|
||||
result += buffer + ";"
|
||||
}
|
||||
state = "data"
|
||||
} else {
|
||||
err("Incorrect escape.")
|
||||
result += buffer + c
|
||||
state = "data"
|
||||
}
|
||||
} else if(state == "tag") {
|
||||
if(c == "\t" || c == "\n" || c == "\f" || c == " ") {
|
||||
state = "start tag annotation"
|
||||
} else if(c == ".") {
|
||||
state = "start tag class"
|
||||
} else if(c == "/") {
|
||||
state = "end tag"
|
||||
} else if(/\d/.test(c)) {
|
||||
result = c
|
||||
state = "timestamp tag"
|
||||
} else if(c == ">" || c == undefined) {
|
||||
if(c == ">") {
|
||||
pos++
|
||||
}
|
||||
return ["start tag", "", [], ""]
|
||||
} else {
|
||||
result = c
|
||||
state = "start tag"
|
||||
}
|
||||
} else if(state == "start tag") {
|
||||
if(c == "\t" || c == "\f" || c == " ") {
|
||||
state = "start tag annotation"
|
||||
} else if(c == "\n") {
|
||||
buffer = c
|
||||
state = "start tag annotation"
|
||||
} else if(c == ".") {
|
||||
state = "start tag class"
|
||||
} else if(c == ">" || c == undefined) {
|
||||
if(c == ">") {
|
||||
pos++
|
||||
}
|
||||
return ["start tag", result, [], ""]
|
||||
} else {
|
||||
result += c
|
||||
}
|
||||
} else if(state == "start tag class") {
|
||||
if(c == "\t" || c == "\f" || c == " ") {
|
||||
if (buffer) {
|
||||
classes.push(buffer)
|
||||
}
|
||||
buffer = ""
|
||||
state = "start tag annotation"
|
||||
} else if(c == "\n") {
|
||||
if (buffer) {
|
||||
classes.push(buffer)
|
||||
}
|
||||
buffer = c
|
||||
state = "start tag annotation"
|
||||
} else if(c == ".") {
|
||||
if (buffer) {
|
||||
classes.push(buffer)
|
||||
}
|
||||
buffer = ""
|
||||
} else if(c == ">" || c == undefined) {
|
||||
if(c == ">") {
|
||||
pos++
|
||||
}
|
||||
if (buffer) {
|
||||
classes.push(buffer)
|
||||
}
|
||||
return ["start tag", result, classes, ""]
|
||||
} else {
|
||||
buffer += c
|
||||
}
|
||||
} else if(state == "start tag annotation") {
|
||||
if(c == ">" || c == undefined) {
|
||||
if(c == ">") {
|
||||
pos++
|
||||
}
|
||||
buffer = buffer.split(/[\u0020\t\f\r\n]+/).filter(function(item) { if(item) return true }).join(" ")
|
||||
return ["start tag", result, classes, buffer]
|
||||
} else {
|
||||
buffer +=c
|
||||
}
|
||||
} else if(state == "end tag") {
|
||||
if(c == ">" || c == undefined) {
|
||||
if(c == ">") {
|
||||
pos++
|
||||
}
|
||||
return ["end tag", result]
|
||||
} else {
|
||||
result += c
|
||||
}
|
||||
} else if(state == "timestamp tag") {
|
||||
if(c == ">" || c == undefined) {
|
||||
if(c == ">") {
|
||||
pos++
|
||||
}
|
||||
return ["timestamp", result]
|
||||
} else {
|
||||
result += c
|
||||
}
|
||||
} else {
|
||||
err("Never happens.") // The joke is it might.
|
||||
}
|
||||
// 8
|
||||
pos++
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var WebVTTSerializer = function() {
|
||||
function serializeTimestamp(seconds) {
|
||||
const ms = ("00" + (seconds - Math.floor(seconds)).toFixed(3)*1000).slice(-3);
|
||||
let h = 0, m = 0, s = 0;
|
||||
if (seconds >= 3600) {
|
||||
h = Math.floor(seconds/3600);
|
||||
}
|
||||
m = Math.floor((seconds - 3600*h) / 60);
|
||||
s = Math.floor(seconds - 3600*h - 60*m);
|
||||
return (h ? h + ":" : "") + ("" + m).padStart(2, "0") + ":" + ("" + s).padStart(2, "0") + "." + ms;
|
||||
}
|
||||
function serializeCueSettings(cue) {
|
||||
var result = ""
|
||||
const nonDefaultSettings = Object.keys(defaultCueSettings).filter(s => cue[s] !== defaultCueSettings[s]);
|
||||
if (nonDefaultSettings.includes("direction")) {
|
||||
result+= " vertical:" + cue.direction
|
||||
}
|
||||
if (nonDefaultSettings.includes("alignment")) {
|
||||
result+= " align:" + cue.alignment
|
||||
}
|
||||
if (nonDefaultSettings.includes("size")) {
|
||||
result+= " size:" + cue.size + "%"
|
||||
}
|
||||
if (nonDefaultSettings.includes("lineAlign") || nonDefaultSettings.includes("linePosition")) {
|
||||
result += " line:" + cue.linePosition + (cue.snapToLines ? "" : "%") + (cue.lineAlign && cue.lineAlign != defaultCueSettings.lineAlign ? "," + cue.lineAlign : "")
|
||||
}
|
||||
if (nonDefaultSettings.includes("textPosition") || nonDefaultSettings.includes("positionAlign")) {
|
||||
result += " position:" + cue.textPosition + "%" + (cue.positionAlign && cue.positionAlign !== defaultCueSettings.positionAlign ? "," + cue.positionAlign : "")
|
||||
}
|
||||
return result
|
||||
}
|
||||
function serializeTree(tree) {
|
||||
var result = ""
|
||||
for (var i = 0; i < tree.length; i++) {
|
||||
var node = tree[i]
|
||||
if(node.type == "text") {
|
||||
result += node.value.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
|
||||
} else if(node.type == "object") {
|
||||
result += "<" + node.name
|
||||
if(node.classes) {
|
||||
for(var y = 0; y < node.classes.length; y++) {
|
||||
result += "." + node.classes[y]
|
||||
}
|
||||
}
|
||||
if(node.value) {
|
||||
result += " " + node.value
|
||||
}
|
||||
result += ">"
|
||||
if(node.children)
|
||||
result += serializeTree(node.children)
|
||||
result += "</" + node.name + ">"
|
||||
} else if(node.type == "timestamp") {
|
||||
result += "<" + serializeTimestamp(node.value) + ">"
|
||||
} else {
|
||||
result += "<" + node.value + ">"
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
function serializeCue(cue) {
|
||||
return (cue.id !== undefined ? cue.id + "\n" : "")
|
||||
+ serializeTimestamp(cue.startTime)
|
||||
+ " --> "
|
||||
+ serializeTimestamp(cue.endTime)
|
||||
+ serializeCueSettings(cue)
|
||||
+ "\n" + serializeTree(cue.tree.children) + "\n\n"
|
||||
}
|
||||
function serializeStyle(style) {
|
||||
return "STYLE\n" + style + "\n\n"
|
||||
}
|
||||
this.serialize = function(cues, styles) {
|
||||
var result = "WEBVTT\n\n"
|
||||
if (styles) {
|
||||
for(var i=0;i<styles.length;i++) {
|
||||
result += serializeStyle(styles[i])
|
||||
}
|
||||
}
|
||||
for(var i=0;i<cues.length;i++) {
|
||||
result += serializeCue(cues[i])
|
||||
}
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
function exportify(object) {
|
||||
object.WebVTTParser = WebVTTParser
|
||||
object.WebVTTCueTimingsAndSettingsParser = WebVTTCueTimingsAndSettingsParser
|
||||
object.WebVTTCueTextParser = WebVTTCueTextParser
|
||||
object.WebVTTSerializer = WebVTTSerializer
|
||||
}
|
||||
if (typeof window !== 'undefined') exportify(window);
|
||||
if (typeof exports !== 'undefined') exportify(exports);
|
||||
})()
|
||||
Vendored
+15
@@ -0,0 +1,15 @@
|
||||
import type Artplayer from 'artplayer';
|
||||
|
||||
export = artplayerPluginMultipleSubtitles;
|
||||
export as namespace artplayerPluginMultipleSubtitles;
|
||||
|
||||
declare const artplayerPluginMultipleSubtitles: (option: {
|
||||
subtitles: {
|
||||
url?: string;
|
||||
name?: string;
|
||||
type?: 'vtt' | 'srt' | 'ass';
|
||||
encoding?: string;
|
||||
}[];
|
||||
}) => (art: Artplayer) => {
|
||||
name: 'artplayerPluginMultipleSubtitles';
|
||||
};
|
||||
Reference in new issue
Block a user